Browse Source

Merge git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6

* git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (137 commits)
  [SCSI] iscsi: bidi support for iscsi_tcp
  [SCSI] iscsi: bidi support at the generic libiscsi level
  [SCSI] iscsi: extended cdb support
  [SCSI] zfcp: Fix error handling for blocked unit for send FCP command
  [SCSI] zfcp: Remove zfcp_erp_wait from slave destory handler to fix deadlock
  [SCSI] zfcp: fix 31 bit compile warnings
  [SCSI] bsg: no need to set BSG_F_BLOCK bit in bsg_complete_all_commands
  [SCSI] bsg: remove minor in struct bsg_device
  [SCSI] bsg: use better helper list functions
  [SCSI] bsg: replace kobject_get with blk_get_queue
  [SCSI] bsg: takes a ref to struct device in fops->open
  [SCSI] qla1280: remove version check
  [SCSI] libsas: fix endianness bug in sas_ata
  [SCSI] zfcp: fix compiler warning caused by poking inside new semaphore (linux-next)
  [SCSI] aacraid: Do not describe check_reset parameter with its value
  [SCSI] aacraid: Fix down_interruptible() to check the return value
  [SCSI] sun3_scsi_vme: add MODULE_LICENSE
  [SCSI] st: rename flush_write_buffer()
  [SCSI] tgt: use KMEM_CACHE macro
  [SCSI] initio: fix big endian problems for auto request sense
  ...
Linus Torvalds 17 năm trước cách đây
mục cha
commit
2cca775bae
100 tập tin đã thay đổi với 3402 bổ sung3360 xóa
  1. 11 1
      Documentation/scsi/st.txt
  2. 4 19
      arch/ia64/hp/sim/simscsi.c
  3. 29 23
      block/bsg.c
  4. 1 5
      drivers/ata/libata-scsi.c
  5. 2 1
      drivers/base/transport_class.c
  6. 18 11
      drivers/message/fusion/mptbase.c
  7. 3 2
      drivers/message/fusion/mptbase.h
  8. 17 5
      drivers/message/fusion/mptsas.c
  9. 4 4
      drivers/message/fusion/mptscsih.c
  10. 17 16
      drivers/s390/scsi/zfcp_aux.c
  11. 11 13
      drivers/s390/scsi/zfcp_ccw.c
  12. 801 480
      drivers/s390/scsi/zfcp_dbf.c
  13. 228 0
      drivers/s390/scsi/zfcp_dbf.h
  14. 4 165
      drivers/s390/scsi/zfcp_def.h
  15. 222 466
      drivers/s390/scsi/zfcp_erp.c
  16. 36 23
      drivers/s390/scsi/zfcp_ext.h
  17. 90 307
      drivers/s390/scsi/zfcp_fsf.c
  18. 3 4
      drivers/s390/scsi/zfcp_qdio.c
  19. 22 47
      drivers/s390/scsi/zfcp_scsi.c
  20. 6 5
      drivers/s390/scsi/zfcp_sysfs_adapter.c
  21. 5 4
      drivers/s390/scsi/zfcp_sysfs_port.c
  22. 3 2
      drivers/s390/scsi/zfcp_sysfs_unit.c
  23. 9 14
      drivers/scsi/3w-9xxx.c
  24. 2 12
      drivers/scsi/3w-xxxx.c
  25. 4 1
      drivers/scsi/BusLogic.c
  26. 2 19
      drivers/scsi/BusLogic.h
  27. 3 3
      drivers/scsi/FlashPoint.c
  28. 8 6
      drivers/scsi/Kconfig
  29. 3 0
      drivers/scsi/a2091.c
  30. 3 0
      drivers/scsi/a3000.c
  31. 27 42
      drivers/scsi/aacraid/aachba.c
  32. 6 4
      drivers/scsi/aacraid/commsup.c
  33. 5 2
      drivers/scsi/aic7xxx/aic79xx_osm.c
  34. 7 3
      drivers/scsi/aic7xxx/aic7xxx_osm.c
  35. 1 1
      drivers/scsi/aic7xxx/aicasm/aicasm_gram.y
  36. 0 16
      drivers/scsi/aic94xx/aic94xx.h
  37. 4 4
      drivers/scsi/aic94xx/aic94xx_dev.c
  38. 9 1
      drivers/scsi/aic94xx/aic94xx_dump.c
  39. 0 9
      drivers/scsi/aic94xx/aic94xx_dump.h
  40. 21 23
      drivers/scsi/aic94xx/aic94xx_hwi.c
  41. 0 2
      drivers/scsi/aic94xx/aic94xx_hwi.h
  42. 4 6
      drivers/scsi/aic94xx/aic94xx_init.c
  43. 26 27
      drivers/scsi/aic94xx/aic94xx_reg.c
  44. 18 15
      drivers/scsi/aic94xx/aic94xx_scb.c
  45. 2 2
      drivers/scsi/aic94xx/aic94xx_sds.c
  46. 5 26
      drivers/scsi/aic94xx/aic94xx_seq.c
  47. 0 4
      drivers/scsi/aic94xx/aic94xx_seq.h
  48. 6 6
      drivers/scsi/aic94xx/aic94xx_task.c
  49. 1 1
      drivers/scsi/aic94xx/aic94xx_tmf.c
  50. 0 1
      drivers/scsi/arm/acornscsi.c
  51. 0 1
      drivers/scsi/arm/cumana_1.c
  52. 17 16
      drivers/scsi/ch.c
  53. 0 1
      drivers/scsi/dc395x.c
  54. 0 2
      drivers/scsi/eata_pio.c
  55. 132 188
      drivers/scsi/gdth.c
  56. 0 2
      drivers/scsi/gdth.h
  57. 3 0
      drivers/scsi/gvp11.c
  58. 0 1
      drivers/scsi/hosts.c
  59. 4 3
      drivers/scsi/hptiop.c
  60. 5 4
      drivers/scsi/initio.c
  61. 26 63
      drivers/scsi/ips.c
  62. 17 14
      drivers/scsi/iscsi_tcp.c
  63. 120 20
      drivers/scsi/libiscsi.c
  64. 1 1
      drivers/scsi/libsas/sas_ata.c
  65. 41 0
      drivers/scsi/libsas/sas_scsi_host.c
  66. 1 4
      drivers/scsi/lpfc/lpfc.h
  67. 8 2
      drivers/scsi/lpfc/lpfc_attr.c
  68. 16 32
      drivers/scsi/lpfc/lpfc_ct.c
  69. 2 0
      drivers/scsi/lpfc/lpfc_debugfs.c
  70. 54 67
      drivers/scsi/lpfc/lpfc_els.c
  71. 21 52
      drivers/scsi/lpfc/lpfc_hbadisc.c
  72. 43 55
      drivers/scsi/lpfc/lpfc_init.c
  73. 23 17
      drivers/scsi/lpfc/lpfc_nportdisc.c
  74. 21 13
      drivers/scsi/lpfc/lpfc_scsi.c
  75. 68 44
      drivers/scsi/lpfc/lpfc_sli.c
  76. 1 1
      drivers/scsi/lpfc/lpfc_version.h
  77. 2 1
      drivers/scsi/lpfc/lpfc_vport.c
  78. 0 1
      drivers/scsi/mac_scsi.c
  79. 31 18
      drivers/scsi/megaraid/megaraid_sas.c
  80. 5 0
      drivers/scsi/megaraid/megaraid_sas.h
  81. 3 0
      drivers/scsi/mvme147.c
  82. 12 89
      drivers/scsi/ps3rom.c
  83. 0 5
      drivers/scsi/qla1280.c
  84. 2 1
      drivers/scsi/qla2xxx/Kconfig
  85. 27 9
      drivers/scsi/qla2xxx/qla_attr.c
  86. 1 123
      drivers/scsi/qla2xxx/qla_dbg.c
  87. 9 14
      drivers/scsi/qla2xxx/qla_dbg.h
  88. 68 10
      drivers/scsi/qla2xxx/qla_def.h
  89. 1 1
      drivers/scsi/qla2xxx/qla_dfs.c
  90. 170 3
      drivers/scsi/qla2xxx/qla_fw.h
  91. 24 9
      drivers/scsi/qla2xxx/qla_gbl.h
  92. 6 10
      drivers/scsi/qla2xxx/qla_gs.c
  93. 132 60
      drivers/scsi/qla2xxx/qla_init.c
  94. 1 86
      drivers/scsi/qla2xxx/qla_inline.h
  95. 1 4
      drivers/scsi/qla2xxx/qla_iocb.c
  96. 102 121
      drivers/scsi/qla2xxx/qla_isr.c
  97. 238 80
      drivers/scsi/qla2xxx/qla_mbx.c
  98. 12 18
      drivers/scsi/qla2xxx/qla_mid.c
  99. 217 226
      drivers/scsi/qla2xxx/qla_os.c
  100. 1 15
      drivers/scsi/qla2xxx/qla_settings.h

+ 11 - 1
Documentation/scsi/st.txt

@@ -2,7 +2,7 @@ This file contains brief information about the SCSI tape driver.
 The driver is currently maintained by Kai Mäkisara (email
 The driver is currently maintained by Kai Mäkisara (email
 Kai.Makisara@kolumbus.fi)
 Kai.Makisara@kolumbus.fi)
 
 
-Last modified: Mon Mar  7 21:14:44 2005 by kai.makisara
+Last modified: Sun Feb 24 21:59:07 2008 by kai.makisara
 
 
 
 
 BASICS
 BASICS
@@ -133,6 +133,11 @@ the defaults set by the user. The value -1 means the default is not set. The
 file 'dev' contains the device numbers corresponding to this device. The links
 file 'dev' contains the device numbers corresponding to this device. The links
 'device' and 'driver' point to the SCSI device and driver entries.
 'device' and 'driver' point to the SCSI device and driver entries.
 
 
+Each directory also contains the entry 'options' which shows the currently
+enabled driver and mode options. The value in the file is a bit mask where the
+bit definitions are the same as those used with MTSETDRVBUFFER in setting the
+options.
+
 A link named 'tape' is made from the SCSI device directory to the class
 A link named 'tape' is made from the SCSI device directory to the class
 directory corresponding to the mode 0 auto-rewind device (e.g., st0). 
 directory corresponding to the mode 0 auto-rewind device (e.g., st0). 
 
 
@@ -372,6 +377,11 @@ MTSETDRVBUFFER
 	     MT_ST_SYSV sets the SYSV semantics (mode)
 	     MT_ST_SYSV sets the SYSV semantics (mode)
 	     MT_ST_NOWAIT enables immediate mode (i.e., don't wait for
 	     MT_ST_NOWAIT enables immediate mode (i.e., don't wait for
 	        the command to finish) for some commands (e.g., rewind)
 	        the command to finish) for some commands (e.g., rewind)
+	     MT_ST_SILI enables setting the SILI bit in SCSI commands when
+		reading in variable block mode to enhance performance when
+		reading blocks shorter than the byte count; set this only
+		if you are sure that the drive supports SILI and the HBA
+		correctly returns transfer residuals
 	     MT_ST_DEBUGGING debugging (global; debugging must be
 	     MT_ST_DEBUGGING debugging (global; debugging must be
 		compiled into the driver)
 		compiled into the driver)
 	MT_ST_SETBOOLEANS
 	MT_ST_SETBOOLEANS

+ 4 - 19
arch/ia64/hp/sim/simscsi.c

@@ -201,22 +201,6 @@ simscsi_readwrite10 (struct scsi_cmnd *sc, int mode)
 	simscsi_sg_readwrite(sc, mode, offset);
 	simscsi_sg_readwrite(sc, mode, offset);
 }
 }
 
 
-static void simscsi_fillresult(struct scsi_cmnd *sc, char *buf, unsigned len)
-{
-
-	int i;
-	unsigned thislen;
-	struct scatterlist *slp;
-
-	scsi_for_each_sg(sc, slp, scsi_sg_count(sc), i) {
-		if (!len)
-			break;
-		thislen = min(len, slp->length);
-		memcpy(sg_virt(slp), buf, thislen);
-		len -= thislen;
-	}
-}
-
 static int
 static int
 simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 {
 {
@@ -258,7 +242,7 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 			buf[6] = 0;	/* reserved */
 			buf[6] = 0;	/* reserved */
 			buf[7] = 0;	/* various flags */
 			buf[7] = 0;	/* various flags */
 			memcpy(buf + 8, "HP      SIMULATED DISK  0.00",  28);
 			memcpy(buf + 8, "HP      SIMULATED DISK  0.00",  28);
-			simscsi_fillresult(sc, buf, 36);
+			scsi_sg_copy_from_buffer(sc, buf, 36);
 			sc->result = GOOD;
 			sc->result = GOOD;
 			break;
 			break;
 
 
@@ -306,14 +290,15 @@ simscsi_queuecommand (struct scsi_cmnd *sc, void (*done)(struct scsi_cmnd *))
 			buf[5] = 0;
 			buf[5] = 0;
 			buf[6] = 2;
 			buf[6] = 2;
 			buf[7] = 0;
 			buf[7] = 0;
-			simscsi_fillresult(sc, buf, 8);
+			scsi_sg_copy_from_buffer(sc, buf, 8);
 			sc->result = GOOD;
 			sc->result = GOOD;
 			break;
 			break;
 
 
 		      case MODE_SENSE:
 		      case MODE_SENSE:
 		      case MODE_SENSE_10:
 		      case MODE_SENSE_10:
 			/* sd.c uses this to determine whether disk does write-caching. */
 			/* sd.c uses this to determine whether disk does write-caching. */
-			simscsi_fillresult(sc, (char *)empty_zero_page, scsi_bufflen(sc));
+			scsi_sg_copy_from_buffer(sc, (char *)empty_zero_page,
+						 PAGE_SIZE);
 			sc->result = GOOD;
 			sc->result = GOOD;
 			break;
 			break;
 
 

+ 29 - 23
block/bsg.c

@@ -37,7 +37,6 @@ struct bsg_device {
 	struct list_head done_list;
 	struct list_head done_list;
 	struct hlist_node dev_list;
 	struct hlist_node dev_list;
 	atomic_t ref_count;
 	atomic_t ref_count;
-	int minor;
 	int queued_cmds;
 	int queued_cmds;
 	int done_cmds;
 	int done_cmds;
 	wait_queue_head_t wq_done;
 	wait_queue_head_t wq_done;
@@ -368,7 +367,7 @@ static struct bsg_command *bsg_next_done_cmd(struct bsg_device *bd)
 
 
 	spin_lock_irq(&bd->lock);
 	spin_lock_irq(&bd->lock);
 	if (bd->done_cmds) {
 	if (bd->done_cmds) {
-		bc = list_entry(bd->done_list.next, struct bsg_command, list);
+		bc = list_first_entry(&bd->done_list, struct bsg_command, list);
 		list_del(&bc->list);
 		list_del(&bc->list);
 		bd->done_cmds--;
 		bd->done_cmds--;
 	}
 	}
@@ -468,8 +467,6 @@ static int bsg_complete_all_commands(struct bsg_device *bd)
 
 
 	dprintk("%s: entered\n", bd->name);
 	dprintk("%s: entered\n", bd->name);
 
 
-	set_bit(BSG_F_BLOCK, &bd->flags);
-
 	/*
 	/*
 	 * wait for all commands to complete
 	 * wait for all commands to complete
 	 */
 	 */
@@ -705,6 +702,7 @@ static struct bsg_device *bsg_alloc_device(void)
 static int bsg_put_device(struct bsg_device *bd)
 static int bsg_put_device(struct bsg_device *bd)
 {
 {
 	int ret = 0;
 	int ret = 0;
+	struct device *dev = bd->queue->bsg_dev.dev;
 
 
 	mutex_lock(&bsg_mutex);
 	mutex_lock(&bsg_mutex);
 
 
@@ -730,6 +728,7 @@ static int bsg_put_device(struct bsg_device *bd)
 	kfree(bd);
 	kfree(bd);
 out:
 out:
 	mutex_unlock(&bsg_mutex);
 	mutex_unlock(&bsg_mutex);
+	put_device(dev);
 	return ret;
 	return ret;
 }
 }
 
 
@@ -738,22 +737,26 @@ static struct bsg_device *bsg_add_device(struct inode *inode,
 					 struct file *file)
 					 struct file *file)
 {
 {
 	struct bsg_device *bd;
 	struct bsg_device *bd;
+	int ret;
 #ifdef BSG_DEBUG
 #ifdef BSG_DEBUG
 	unsigned char buf[32];
 	unsigned char buf[32];
 #endif
 #endif
+	ret = blk_get_queue(rq);
+	if (ret)
+		return ERR_PTR(-ENXIO);
 
 
 	bd = bsg_alloc_device();
 	bd = bsg_alloc_device();
-	if (!bd)
+	if (!bd) {
+		blk_put_queue(rq);
 		return ERR_PTR(-ENOMEM);
 		return ERR_PTR(-ENOMEM);
+	}
 
 
 	bd->queue = rq;
 	bd->queue = rq;
-	kobject_get(&rq->kobj);
 	bsg_set_block(bd, file);
 	bsg_set_block(bd, file);
 
 
 	atomic_set(&bd->ref_count, 1);
 	atomic_set(&bd->ref_count, 1);
-	bd->minor = iminor(inode);
 	mutex_lock(&bsg_mutex);
 	mutex_lock(&bsg_mutex);
-	hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(bd->minor));
+	hlist_add_head(&bd->dev_list, bsg_dev_idx_hash(iminor(inode)));
 
 
 	strncpy(bd->name, rq->bsg_dev.class_dev->class_id, sizeof(bd->name) - 1);
 	strncpy(bd->name, rq->bsg_dev.class_dev->class_id, sizeof(bd->name) - 1);
 	dprintk("bound to <%s>, max queue %d\n",
 	dprintk("bound to <%s>, max queue %d\n",
@@ -763,23 +766,21 @@ static struct bsg_device *bsg_add_device(struct inode *inode,
 	return bd;
 	return bd;
 }
 }
 
 
-static struct bsg_device *__bsg_get_device(int minor)
+static struct bsg_device *__bsg_get_device(int minor, struct request_queue *q)
 {
 {
-	struct bsg_device *bd = NULL;
+	struct bsg_device *bd;
 	struct hlist_node *entry;
 	struct hlist_node *entry;
 
 
 	mutex_lock(&bsg_mutex);
 	mutex_lock(&bsg_mutex);
 
 
-	hlist_for_each(entry, bsg_dev_idx_hash(minor)) {
-		bd = hlist_entry(entry, struct bsg_device, dev_list);
-		if (bd->minor == minor) {
+	hlist_for_each_entry(bd, entry, bsg_dev_idx_hash(minor), dev_list) {
+		if (bd->queue == q) {
 			atomic_inc(&bd->ref_count);
 			atomic_inc(&bd->ref_count);
-			break;
+			goto found;
 		}
 		}
-
-		bd = NULL;
 	}
 	}
-
+	bd = NULL;
+found:
 	mutex_unlock(&bsg_mutex);
 	mutex_unlock(&bsg_mutex);
 	return bd;
 	return bd;
 }
 }
@@ -789,21 +790,27 @@ static struct bsg_device *bsg_get_device(struct inode *inode, struct file *file)
 	struct bsg_device *bd;
 	struct bsg_device *bd;
 	struct bsg_class_device *bcd;
 	struct bsg_class_device *bcd;
 
 
-	bd = __bsg_get_device(iminor(inode));
-	if (bd)
-		return bd;
-
 	/*
 	/*
 	 * find the class device
 	 * find the class device
 	 */
 	 */
 	mutex_lock(&bsg_mutex);
 	mutex_lock(&bsg_mutex);
 	bcd = idr_find(&bsg_minor_idr, iminor(inode));
 	bcd = idr_find(&bsg_minor_idr, iminor(inode));
+	if (bcd)
+		get_device(bcd->dev);
 	mutex_unlock(&bsg_mutex);
 	mutex_unlock(&bsg_mutex);
 
 
 	if (!bcd)
 	if (!bcd)
 		return ERR_PTR(-ENODEV);
 		return ERR_PTR(-ENODEV);
 
 
-	return bsg_add_device(inode, bcd->queue, file);
+	bd = __bsg_get_device(iminor(inode), bcd->queue);
+	if (bd)
+		return bd;
+
+	bd = bsg_add_device(inode, bcd->queue, file);
+	if (IS_ERR(bd))
+		put_device(bcd->dev);
+
+	return bd;
 }
 }
 
 
 static int bsg_open(struct inode *inode, struct file *file)
 static int bsg_open(struct inode *inode, struct file *file)
@@ -942,7 +949,6 @@ void bsg_unregister_queue(struct request_queue *q)
 	class_device_unregister(bcd->class_dev);
 	class_device_unregister(bcd->class_dev);
 	put_device(bcd->dev);
 	put_device(bcd->dev);
 	bcd->class_dev = NULL;
 	bcd->class_dev = NULL;
-	bcd->dev = NULL;
 	mutex_unlock(&bsg_mutex);
 	mutex_unlock(&bsg_mutex);
 }
 }
 EXPORT_SYMBOL_GPL(bsg_unregister_queue);
 EXPORT_SYMBOL_GPL(bsg_unregister_queue);

+ 1 - 5
drivers/ata/libata-scsi.c

@@ -2332,11 +2332,7 @@ void ata_scsi_set_sense(struct scsi_cmnd *cmd, u8 sk, u8 asc, u8 ascq)
 {
 {
 	cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
 	cmd->result = (DRIVER_SENSE << 24) | SAM_STAT_CHECK_CONDITION;
 
 
-	cmd->sense_buffer[0] = 0x70;	/* fixed format, current */
-	cmd->sense_buffer[2] = sk;
-	cmd->sense_buffer[7] = 18 - 8;	/* additional sense length */
-	cmd->sense_buffer[12] = asc;
-	cmd->sense_buffer[13] = ascq;
+	scsi_build_sense_buffer(0, cmd->sense_buffer, sk, asc, ascq);
 }
 }
 
 
 /**
 /**

+ 2 - 1
drivers/base/transport_class.c

@@ -108,7 +108,8 @@ EXPORT_SYMBOL_GPL(anon_transport_class_register);
  */
  */
 void anon_transport_class_unregister(struct anon_transport_class *atc)
 void anon_transport_class_unregister(struct anon_transport_class *atc)
 {
 {
-	attribute_container_unregister(&atc->container);
+	if (unlikely(attribute_container_unregister(&atc->container)))
+		BUG();
 }
 }
 EXPORT_SYMBOL_GPL(anon_transport_class_unregister);
 EXPORT_SYMBOL_GPL(anon_transport_class_unregister);
 
 

+ 18 - 11
drivers/message/fusion/mptbase.c

@@ -79,7 +79,7 @@ MODULE_VERSION(my_VERSION);
 /*
 /*
  *  cmd line parameters
  *  cmd line parameters
  */
  */
-static int mpt_msi_enable;
+static int mpt_msi_enable = -1;
 module_param(mpt_msi_enable, int, 0);
 module_param(mpt_msi_enable, int, 0);
 MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
 MODULE_PARM_DESC(mpt_msi_enable, " MSI Support Enable (default=0)");
 
 
@@ -1686,6 +1686,11 @@ mpt_attach(struct pci_dev *pdev, const struct pci_device_id *id)
 		ioc->bus_type = SAS;
 		ioc->bus_type = SAS;
 	}
 	}
 
 
+	if (ioc->bus_type == SAS && mpt_msi_enable == -1)
+		ioc->msi_enable = 1;
+	else
+		ioc->msi_enable = mpt_msi_enable;
+
 	if (ioc->errata_flag_1064)
 	if (ioc->errata_flag_1064)
 		pci_disable_io_access(pdev);
 		pci_disable_io_access(pdev);
 
 
@@ -1831,7 +1836,7 @@ mpt_suspend(struct pci_dev *pdev, pm_message_t state)
 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
 	CHIPREG_WRITE32(&ioc->chip->IntStatus, 0);
 
 
 	free_irq(ioc->pci_irq, ioc);
 	free_irq(ioc->pci_irq, ioc);
-	if (mpt_msi_enable)
+	if (ioc->msi_enable)
 		pci_disable_msi(ioc->pcidev);
 		pci_disable_msi(ioc->pcidev);
 	ioc->pci_irq = -1;
 	ioc->pci_irq = -1;
 	pci_save_state(pdev);
 	pci_save_state(pdev);
@@ -2057,15 +2062,17 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
 	if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
 	if ((ret == 0) && (reason == MPT_HOSTEVENT_IOC_BRINGUP)) {
 		ioc->pci_irq = -1;
 		ioc->pci_irq = -1;
 		if (ioc->pcidev->irq) {
 		if (ioc->pcidev->irq) {
-			if (mpt_msi_enable && !pci_enable_msi(ioc->pcidev))
+			if (ioc->msi_enable && !pci_enable_msi(ioc->pcidev))
 				printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
 				printk(MYIOC_s_INFO_FMT "PCI-MSI enabled\n",
 				    ioc->name);
 				    ioc->name);
+			else
+				ioc->msi_enable = 0;
 			rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
 			rc = request_irq(ioc->pcidev->irq, mpt_interrupt,
 			    IRQF_SHARED, ioc->name, ioc);
 			    IRQF_SHARED, ioc->name, ioc);
 			if (rc < 0) {
 			if (rc < 0) {
 				printk(MYIOC_s_ERR_FMT "Unable to allocate "
 				printk(MYIOC_s_ERR_FMT "Unable to allocate "
 				    "interrupt %d!\n", ioc->name, ioc->pcidev->irq);
 				    "interrupt %d!\n", ioc->name, ioc->pcidev->irq);
-				if (mpt_msi_enable)
+				if (ioc->msi_enable)
 					pci_disable_msi(ioc->pcidev);
 					pci_disable_msi(ioc->pcidev);
 				return -EBUSY;
 				return -EBUSY;
 			}
 			}
@@ -2173,7 +2180,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
 		/*
 		/*
 		 * Initalize link list for inactive raid volumes.
 		 * Initalize link list for inactive raid volumes.
 		 */
 		 */
-		init_MUTEX(&ioc->raid_data.inactive_list_mutex);
+		mutex_init(&ioc->raid_data.inactive_list_mutex);
 		INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
 		INIT_LIST_HEAD(&ioc->raid_data.inactive_list);
 
 
 		if (ioc->bus_type == SAS) {
 		if (ioc->bus_type == SAS) {
@@ -2261,7 +2268,7 @@ mpt_do_ioc_recovery(MPT_ADAPTER *ioc, u32 reason, int sleepFlag)
  out:
  out:
 	if ((ret != 0) && irq_allocated) {
 	if ((ret != 0) && irq_allocated) {
 		free_irq(ioc->pci_irq, ioc);
 		free_irq(ioc->pci_irq, ioc);
-		if (mpt_msi_enable)
+		if (ioc->msi_enable)
 			pci_disable_msi(ioc->pcidev);
 			pci_disable_msi(ioc->pcidev);
 	}
 	}
 	return ret;
 	return ret;
@@ -2443,7 +2450,7 @@ mpt_adapter_dispose(MPT_ADAPTER *ioc)
 
 
 	if (ioc->pci_irq != -1) {
 	if (ioc->pci_irq != -1) {
 		free_irq(ioc->pci_irq, ioc);
 		free_irq(ioc->pci_irq, ioc);
-		if (mpt_msi_enable)
+		if (ioc->msi_enable)
 			pci_disable_msi(ioc->pcidev);
 			pci_disable_msi(ioc->pcidev);
 		ioc->pci_irq = -1;
 		ioc->pci_irq = -1;
 	}
 	}
@@ -5159,13 +5166,13 @@ mpt_inactive_raid_list_free(MPT_ADAPTER *ioc)
 	if (list_empty(&ioc->raid_data.inactive_list))
 	if (list_empty(&ioc->raid_data.inactive_list))
 		return;
 		return;
 
 
-	down(&ioc->raid_data.inactive_list_mutex);
+	mutex_lock(&ioc->raid_data.inactive_list_mutex);
 	list_for_each_entry_safe(component_info, pNext,
 	list_for_each_entry_safe(component_info, pNext,
 	    &ioc->raid_data.inactive_list, list) {
 	    &ioc->raid_data.inactive_list, list) {
 		list_del(&component_info->list);
 		list_del(&component_info->list);
 		kfree(component_info);
 		kfree(component_info);
 	}
 	}
-	up(&ioc->raid_data.inactive_list_mutex);
+	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
 }
 }
 
 
 /**
 /**
@@ -5224,7 +5231,7 @@ mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
 	if (!handle_inactive_volumes)
 	if (!handle_inactive_volumes)
 		goto out;
 		goto out;
 
 
-	down(&ioc->raid_data.inactive_list_mutex);
+	mutex_lock(&ioc->raid_data.inactive_list_mutex);
 	for (i = 0; i < buffer->NumPhysDisks; i++) {
 	for (i = 0; i < buffer->NumPhysDisks; i++) {
 		if(mpt_raid_phys_disk_pg0(ioc,
 		if(mpt_raid_phys_disk_pg0(ioc,
 		    buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
 		    buffer->PhysDisk[i].PhysDiskNum, &phys_disk) != 0)
@@ -5244,7 +5251,7 @@ mpt_inactive_raid_volumes(MPT_ADAPTER *ioc, u8 channel, u8 id)
 		list_add_tail(&component_info->list,
 		list_add_tail(&component_info->list,
 		    &ioc->raid_data.inactive_list);
 		    &ioc->raid_data.inactive_list);
 	}
 	}
-	up(&ioc->raid_data.inactive_list_mutex);
+	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
 
 
  out:
  out:
 	if (buffer)
 	if (buffer)

+ 3 - 2
drivers/message/fusion/mptbase.h

@@ -51,6 +51,7 @@
 
 
 #include <linux/kernel.h>
 #include <linux/kernel.h>
 #include <linux/pci.h>
 #include <linux/pci.h>
+#include <linux/mutex.h>
 
 
 #include "lsi/mpi_type.h"
 #include "lsi/mpi_type.h"
 #include "lsi/mpi.h"		/* Fusion MPI(nterface) basic defs */
 #include "lsi/mpi.h"		/* Fusion MPI(nterface) basic defs */
@@ -531,7 +532,7 @@ struct inactive_raid_component_info {
 typedef	struct _RaidCfgData {
 typedef	struct _RaidCfgData {
 	IOCPage2_t	*pIocPg2;		/* table of Raid Volumes */
 	IOCPage2_t	*pIocPg2;		/* table of Raid Volumes */
 	IOCPage3_t	*pIocPg3;		/* table of physical disks */
 	IOCPage3_t	*pIocPg3;		/* table of physical disks */
-	struct semaphore	inactive_list_mutex;
+	struct mutex	inactive_list_mutex;
 	struct list_head	inactive_list; /* link list for physical
 	struct list_head	inactive_list; /* link list for physical
 						disk that belong in
 						disk that belong in
 						inactive volumes */
 						inactive volumes */
@@ -630,6 +631,7 @@ typedef struct _MPT_ADAPTER
 	int			 mtrr_reg;
 	int			 mtrr_reg;
 	struct pci_dev		*pcidev;	/* struct pci_dev pointer */
 	struct pci_dev		*pcidev;	/* struct pci_dev pointer */
 	int			bars;		/* bitmask of BAR's that must be configured */
 	int			bars;		/* bitmask of BAR's that must be configured */
+	int			msi_enable;
 	u8			__iomem *memmap;	/* mmap address */
 	u8			__iomem *memmap;	/* mmap address */
 	struct Scsi_Host	*sh;		/* Scsi Host pointer */
 	struct Scsi_Host	*sh;		/* Scsi Host pointer */
 	SpiCfgData		spi_data;	/* Scsi config. data */
 	SpiCfgData		spi_data;	/* Scsi config. data */
@@ -693,7 +695,6 @@ typedef struct _MPT_ADAPTER
 	struct mutex		 sas_discovery_mutex;
 	struct mutex		 sas_discovery_mutex;
 	u8			 sas_discovery_runtime;
 	u8			 sas_discovery_runtime;
 	u8			 sas_discovery_ignore_events;
 	u8			 sas_discovery_ignore_events;
-	u16			 handle;
 	int			 sas_index; /* index refrencing */
 	int			 sas_index; /* index refrencing */
 	MPT_SAS_MGMT		 sas_mgmt;
 	MPT_SAS_MGMT		 sas_mgmt;
 	struct work_struct	 sas_persist_task;
 	struct work_struct	 sas_persist_task;

+ 17 - 5
drivers/message/fusion/mptsas.c

@@ -230,6 +230,20 @@ static inline MPT_ADAPTER *rphy_to_ioc(struct sas_rphy *rphy)
 	return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
 	return ((MPT_SCSI_HOST *)shost->hostdata)->ioc;
 }
 }
 
 
+static struct mptsas_portinfo *
+mptsas_get_hba_portinfo(MPT_ADAPTER *ioc)
+{
+	struct list_head	*head = &ioc->sas_topology;
+	struct mptsas_portinfo	*pi = NULL;
+
+	/* always the first entry on sas_topology list */
+
+	if (!list_empty(head))
+		pi = list_entry(head->next, struct mptsas_portinfo, list);
+
+	return pi;
+}
+
 /*
 /*
  * mptsas_find_portinfo_by_handle
  * mptsas_find_portinfo_by_handle
  *
  *
@@ -1290,7 +1304,7 @@ static int mptsas_smp_handler(struct Scsi_Host *shost, struct sas_rphy *rphy,
 		struct mptsas_portinfo *port_info;
 		struct mptsas_portinfo *port_info;
 
 
 		mutex_lock(&ioc->sas_topology_mutex);
 		mutex_lock(&ioc->sas_topology_mutex);
-		port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
+		port_info = mptsas_get_hba_portinfo(ioc);
 		if (port_info && port_info->phy_info)
 		if (port_info && port_info->phy_info)
 			sas_address =
 			sas_address =
 				port_info->phy_info[0].phy->identify.sas_address;
 				port_info->phy_info[0].phy->identify.sas_address;
@@ -2028,8 +2042,7 @@ static int mptsas_probe_one_phy(struct device *dev,
 			int i;
 			int i;
 
 
 			mutex_lock(&ioc->sas_topology_mutex);
 			mutex_lock(&ioc->sas_topology_mutex);
-			port_info = mptsas_find_portinfo_by_handle(ioc,
-								   ioc->handle);
+			port_info = mptsas_get_hba_portinfo(ioc);
 			mutex_unlock(&ioc->sas_topology_mutex);
 			mutex_unlock(&ioc->sas_topology_mutex);
 
 
 			for (i = 0; i < port_info->num_phys; i++)
 			for (i = 0; i < port_info->num_phys; i++)
@@ -2099,8 +2112,7 @@ mptsas_probe_hba_phys(MPT_ADAPTER *ioc)
 
 
 	mptsas_sas_io_unit_pg1(ioc);
 	mptsas_sas_io_unit_pg1(ioc);
 	mutex_lock(&ioc->sas_topology_mutex);
 	mutex_lock(&ioc->sas_topology_mutex);
-	ioc->handle = hba->phy_info[0].handle;
-	port_info = mptsas_find_portinfo_by_handle(ioc, ioc->handle);
+	port_info = mptsas_get_hba_portinfo(ioc);
 	if (!port_info) {
 	if (!port_info) {
 		port_info = hba;
 		port_info = hba;
 		list_add_tail(&port_info->list, &ioc->sas_topology);
 		list_add_tail(&port_info->list, &ioc->sas_topology);

+ 4 - 4
drivers/message/fusion/mptscsih.c

@@ -2304,14 +2304,14 @@ mptscsih_is_phys_disk(MPT_ADAPTER *ioc, u8 channel, u8 id)
 	if (list_empty(&ioc->raid_data.inactive_list))
 	if (list_empty(&ioc->raid_data.inactive_list))
 		goto out;
 		goto out;
 
 
-	down(&ioc->raid_data.inactive_list_mutex);
+	mutex_lock(&ioc->raid_data.inactive_list_mutex);
 	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
 	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
 	    list) {
 	    list) {
 		if ((component_info->d.PhysDiskID == id) &&
 		if ((component_info->d.PhysDiskID == id) &&
 		    (component_info->d.PhysDiskBus == channel))
 		    (component_info->d.PhysDiskBus == channel))
 			rc = 1;
 			rc = 1;
 	}
 	}
-	up(&ioc->raid_data.inactive_list_mutex);
+	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
 
 
  out:
  out:
 	return rc;
 	return rc;
@@ -2341,14 +2341,14 @@ mptscsih_raid_id_to_num(MPT_ADAPTER *ioc, u8 channel, u8 id)
 	if (list_empty(&ioc->raid_data.inactive_list))
 	if (list_empty(&ioc->raid_data.inactive_list))
 		goto out;
 		goto out;
 
 
-	down(&ioc->raid_data.inactive_list_mutex);
+	mutex_lock(&ioc->raid_data.inactive_list_mutex);
 	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
 	list_for_each_entry(component_info, &ioc->raid_data.inactive_list,
 	    list) {
 	    list) {
 		if ((component_info->d.PhysDiskID == id) &&
 		if ((component_info->d.PhysDiskID == id) &&
 		    (component_info->d.PhysDiskBus == channel))
 		    (component_info->d.PhysDiskBus == channel))
 			rc = component_info->d.PhysDiskNum;
 			rc = component_info->d.PhysDiskNum;
 	}
 	}
-	up(&ioc->raid_data.inactive_list_mutex);
+	mutex_unlock(&ioc->raid_data.inactive_list_mutex);
 
 
  out:
  out:
 	return rc;
 	return rc;

+ 17 - 16
drivers/s390/scsi/zfcp_aux.c

@@ -1030,10 +1030,10 @@ zfcp_adapter_enqueue(struct ccw_device *ccw_device)
 
 
 	/* initialize debug locks */
 	/* initialize debug locks */
 
 
-	spin_lock_init(&adapter->erp_dbf_lock);
 	spin_lock_init(&adapter->hba_dbf_lock);
 	spin_lock_init(&adapter->hba_dbf_lock);
 	spin_lock_init(&adapter->san_dbf_lock);
 	spin_lock_init(&adapter->san_dbf_lock);
 	spin_lock_init(&adapter->scsi_dbf_lock);
 	spin_lock_init(&adapter->scsi_dbf_lock);
+	spin_lock_init(&adapter->rec_dbf_lock);
 
 
 	retval = zfcp_adapter_debug_register(adapter);
 	retval = zfcp_adapter_debug_register(adapter);
 	if (retval)
 	if (retval)
@@ -1325,10 +1325,10 @@ zfcp_nameserver_enqueue(struct zfcp_adapter *adapter)
 
 
 #define ZFCP_LOG_AREA                   ZFCP_LOG_AREA_FC
 #define ZFCP_LOG_AREA                   ZFCP_LOG_AREA_FC
 
 
-static void
-zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter,
-			   struct fsf_status_read_buffer *status_buffer)
+static void zfcp_fsf_incoming_els_rscn(struct zfcp_fsf_req *fsf_req)
 {
 {
+	struct fsf_status_read_buffer *status_buffer = (void*)fsf_req->data;
+	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct fcp_rscn_head *fcp_rscn_head;
 	struct fcp_rscn_head *fcp_rscn_head;
 	struct fcp_rscn_element *fcp_rscn_element;
 	struct fcp_rscn_element *fcp_rscn_element;
 	struct zfcp_port *port;
 	struct zfcp_port *port;
@@ -1375,7 +1375,8 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter,
 				ZFCP_LOG_INFO("incoming RSCN, trying to open "
 				ZFCP_LOG_INFO("incoming RSCN, trying to open "
 					      "port 0x%016Lx\n", port->wwpn);
 					      "port 0x%016Lx\n", port->wwpn);
 				zfcp_erp_port_reopen(port,
 				zfcp_erp_port_reopen(port,
-						     ZFCP_STATUS_COMMON_ERP_FAILED);
+						     ZFCP_STATUS_COMMON_ERP_FAILED,
+						     82, fsf_req);
 				continue;
 				continue;
 			}
 			}
 
 
@@ -1406,10 +1407,10 @@ zfcp_fsf_incoming_els_rscn(struct zfcp_adapter *adapter,
 	}
 	}
 }
 }
 
 
-static void
-zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter,
-			    struct fsf_status_read_buffer *status_buffer)
+static void zfcp_fsf_incoming_els_plogi(struct zfcp_fsf_req *fsf_req)
 {
 {
+	struct fsf_status_read_buffer *status_buffer = (void*)fsf_req->data;
+	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct fsf_plogi *els_plogi;
 	struct fsf_plogi *els_plogi;
 	struct zfcp_port *port;
 	struct zfcp_port *port;
 	unsigned long flags;
 	unsigned long flags;
@@ -1428,14 +1429,14 @@ zfcp_fsf_incoming_els_plogi(struct zfcp_adapter *adapter,
 			       status_buffer->d_id,
 			       status_buffer->d_id,
 			       zfcp_get_busid_by_adapter(adapter));
 			       zfcp_get_busid_by_adapter(adapter));
 	} else {
 	} else {
-		zfcp_erp_port_forced_reopen(port, 0);
+		zfcp_erp_port_forced_reopen(port, 0, 83, fsf_req);
 	}
 	}
 }
 }
 
 
-static void
-zfcp_fsf_incoming_els_logo(struct zfcp_adapter *adapter,
-			   struct fsf_status_read_buffer *status_buffer)
+static void zfcp_fsf_incoming_els_logo(struct zfcp_fsf_req *fsf_req)
 {
 {
+	struct fsf_status_read_buffer *status_buffer = (void*)fsf_req->data;
+	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct fcp_logo *els_logo = (struct fcp_logo *) status_buffer->payload;
 	struct fcp_logo *els_logo = (struct fcp_logo *) status_buffer->payload;
 	struct zfcp_port *port;
 	struct zfcp_port *port;
 	unsigned long flags;
 	unsigned long flags;
@@ -1453,7 +1454,7 @@ zfcp_fsf_incoming_els_logo(struct zfcp_adapter *adapter,
 			       status_buffer->d_id,
 			       status_buffer->d_id,
 			       zfcp_get_busid_by_adapter(adapter));
 			       zfcp_get_busid_by_adapter(adapter));
 	} else {
 	} else {
-		zfcp_erp_port_forced_reopen(port, 0);
+		zfcp_erp_port_forced_reopen(port, 0, 84, fsf_req);
 	}
 	}
 }
 }
 
 
@@ -1480,12 +1481,12 @@ zfcp_fsf_incoming_els(struct zfcp_fsf_req *fsf_req)
 
 
 	zfcp_san_dbf_event_incoming_els(fsf_req);
 	zfcp_san_dbf_event_incoming_els(fsf_req);
 	if (els_type == LS_PLOGI)
 	if (els_type == LS_PLOGI)
-		zfcp_fsf_incoming_els_plogi(adapter, status_buffer);
+		zfcp_fsf_incoming_els_plogi(fsf_req);
 	else if (els_type == LS_LOGO)
 	else if (els_type == LS_LOGO)
-		zfcp_fsf_incoming_els_logo(adapter, status_buffer);
+		zfcp_fsf_incoming_els_logo(fsf_req);
 	else if ((els_type & 0xffff0000) == LS_RSCN)
 	else if ((els_type & 0xffff0000) == LS_RSCN)
 		/* we are only concerned with the command, not the length */
 		/* we are only concerned with the command, not the length */
-		zfcp_fsf_incoming_els_rscn(adapter, status_buffer);
+		zfcp_fsf_incoming_els_rscn(fsf_req);
 	else
 	else
 		zfcp_fsf_incoming_els_unknown(adapter, status_buffer);
 		zfcp_fsf_incoming_els_unknown(adapter, status_buffer);
 }
 }

+ 11 - 13
drivers/s390/scsi/zfcp_ccw.c

@@ -170,9 +170,10 @@ zfcp_ccw_set_online(struct ccw_device *ccw_device)
 	BUG_ON(!zfcp_reqlist_isempty(adapter));
 	BUG_ON(!zfcp_reqlist_isempty(adapter));
 	adapter->req_no = 0;
 	adapter->req_no = 0;
 
 
-	zfcp_erp_modify_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING,
-				       ZFCP_SET);
-	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED);
+	zfcp_erp_modify_adapter_status(adapter, 10, NULL,
+				       ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
+	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 85,
+				NULL);
 	zfcp_erp_wait(adapter);
 	zfcp_erp_wait(adapter);
 	goto out;
 	goto out;
 
 
@@ -197,7 +198,7 @@ zfcp_ccw_set_offline(struct ccw_device *ccw_device)
 
 
 	down(&zfcp_data.config_sema);
 	down(&zfcp_data.config_sema);
 	adapter = dev_get_drvdata(&ccw_device->dev);
 	adapter = dev_get_drvdata(&ccw_device->dev);
-	zfcp_erp_adapter_shutdown(adapter, 0);
+	zfcp_erp_adapter_shutdown(adapter, 0, 86, NULL);
 	zfcp_erp_wait(adapter);
 	zfcp_erp_wait(adapter);
 	zfcp_erp_thread_kill(adapter);
 	zfcp_erp_thread_kill(adapter);
 	up(&zfcp_data.config_sema);
 	up(&zfcp_data.config_sema);
@@ -223,24 +224,21 @@ zfcp_ccw_notify(struct ccw_device *ccw_device, int event)
 	case CIO_GONE:
 	case CIO_GONE:
 		ZFCP_LOG_NORMAL("adapter %s: device gone\n",
 		ZFCP_LOG_NORMAL("adapter %s: device gone\n",
 				zfcp_get_busid_by_adapter(adapter));
 				zfcp_get_busid_by_adapter(adapter));
-		debug_text_event(adapter->erp_dbf,1,"dev_gone");
-		zfcp_erp_adapter_shutdown(adapter, 0);
+		zfcp_erp_adapter_shutdown(adapter, 0, 87, NULL);
 		break;
 		break;
 	case CIO_NO_PATH:
 	case CIO_NO_PATH:
 		ZFCP_LOG_NORMAL("adapter %s: no path\n",
 		ZFCP_LOG_NORMAL("adapter %s: no path\n",
 				zfcp_get_busid_by_adapter(adapter));
 				zfcp_get_busid_by_adapter(adapter));
-		debug_text_event(adapter->erp_dbf,1,"no_path");
-		zfcp_erp_adapter_shutdown(adapter, 0);
+		zfcp_erp_adapter_shutdown(adapter, 0, 88, NULL);
 		break;
 		break;
 	case CIO_OPER:
 	case CIO_OPER:
 		ZFCP_LOG_NORMAL("adapter %s: operational again\n",
 		ZFCP_LOG_NORMAL("adapter %s: operational again\n",
 				zfcp_get_busid_by_adapter(adapter));
 				zfcp_get_busid_by_adapter(adapter));
-		debug_text_event(adapter->erp_dbf,1,"dev_oper");
-		zfcp_erp_modify_adapter_status(adapter,
+		zfcp_erp_modify_adapter_status(adapter, 11, NULL,
 					       ZFCP_STATUS_COMMON_RUNNING,
 					       ZFCP_STATUS_COMMON_RUNNING,
 					       ZFCP_SET);
 					       ZFCP_SET);
-		zfcp_erp_adapter_reopen(adapter,
-					ZFCP_STATUS_COMMON_ERP_FAILED);
+		zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED,
+					89, NULL);
 		break;
 		break;
 	}
 	}
 	zfcp_erp_wait(adapter);
 	zfcp_erp_wait(adapter);
@@ -272,7 +270,7 @@ zfcp_ccw_shutdown(struct ccw_device *cdev)
 
 
 	down(&zfcp_data.config_sema);
 	down(&zfcp_data.config_sema);
 	adapter = dev_get_drvdata(&cdev->dev);
 	adapter = dev_get_drvdata(&cdev->dev);
-	zfcp_erp_adapter_shutdown(adapter, 0);
+	zfcp_erp_adapter_shutdown(adapter, 0, 90, NULL);
 	zfcp_erp_wait(adapter);
 	zfcp_erp_wait(adapter);
 	up(&zfcp_data.config_sema);
 	up(&zfcp_data.config_sema);
 }
 }

+ 801 - 480
drivers/s390/scsi/zfcp_dbf.c

@@ -31,123 +31,128 @@ MODULE_PARM_DESC(dbfsize,
 
 
 #define ZFCP_LOG_AREA			ZFCP_LOG_AREA_OTHER
 #define ZFCP_LOG_AREA			ZFCP_LOG_AREA_OTHER
 
 
-static int
-zfcp_dbf_stck(char *out_buf, const char *label, unsigned long long stck)
+static void zfcp_dbf_hexdump(debug_info_t *dbf, void *to, int to_len,
+			     int level, char *from, int from_len)
+{
+	int offset;
+	struct zfcp_dbf_dump *dump = to;
+	int room = to_len - sizeof(*dump);
+
+	for (offset = 0; offset < from_len; offset += dump->size) {
+		memset(to, 0, to_len);
+		strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
+		dump->total_size = from_len;
+		dump->offset = offset;
+		dump->size = min(from_len - offset, room);
+		memcpy(dump->data, from + offset, dump->size);
+		debug_event(dbf, level, dump, dump->size);
+	}
+}
+
+/* FIXME: this duplicate this code in s390 debug feature */
+static void zfcp_dbf_timestamp(unsigned long long stck, struct timespec *time)
 {
 {
 	unsigned long long sec;
 	unsigned long long sec;
-	struct timespec dbftime;
-	int len = 0;
 
 
 	stck -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096);
 	stck -= 0x8126d60e46000000LL - (0x3c26700LL * 1000000 * 4096);
 	sec = stck >> 12;
 	sec = stck >> 12;
 	do_div(sec, 1000000);
 	do_div(sec, 1000000);
-	dbftime.tv_sec = sec;
+	time->tv_sec = sec;
 	stck -= (sec * 1000000) << 12;
 	stck -= (sec * 1000000) << 12;
-	dbftime.tv_nsec = ((stck * 1000) >> 12);
-	len += sprintf(out_buf + len, "%-24s%011lu:%06lu\n",
-		       label, dbftime.tv_sec, dbftime.tv_nsec);
-
-	return len;
+	time->tv_nsec = ((stck * 1000) >> 12);
 }
 }
 
 
-static int zfcp_dbf_tag(char *out_buf, const char *label, const char *tag)
+static void zfcp_dbf_tag(char **p, const char *label, const char *tag)
 {
 {
-	int len = 0, i;
+	int i;
 
 
-	len += sprintf(out_buf + len, "%-24s", label);
+	*p += sprintf(*p, "%-24s", label);
 	for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++)
 	for (i = 0; i < ZFCP_DBF_TAG_SIZE; i++)
-		len += sprintf(out_buf + len, "%c", tag[i]);
-	len += sprintf(out_buf + len, "\n");
+		*p += sprintf(*p, "%c", tag[i]);
+	*p += sprintf(*p, "\n");
+}
 
 
-	return len;
+static void zfcp_dbf_outs(char **buf, const char *s1, const char *s2)
+{
+	*buf += sprintf(*buf, "%-24s%s\n", s1, s2);
 }
 }
 
 
-static int
-zfcp_dbf_view(char *out_buf, const char *label, const char *format, ...)
+static void zfcp_dbf_out(char **buf, const char *s, const char *format, ...)
 {
 {
 	va_list arg;
 	va_list arg;
-	int len = 0;
 
 
-	len += sprintf(out_buf + len, "%-24s", label);
+	*buf += sprintf(*buf, "%-24s", s);
 	va_start(arg, format);
 	va_start(arg, format);
-	len += vsprintf(out_buf + len, format, arg);
+	*buf += vsprintf(*buf, format, arg);
 	va_end(arg);
 	va_end(arg);
-	len += sprintf(out_buf + len, "\n");
-
-	return len;
+	*buf += sprintf(*buf, "\n");
 }
 }
 
 
-static int
-zfcp_dbf_view_dump(char *out_buf, const char *label,
-		   char *buffer, int buflen, int offset, int total_size)
+static void zfcp_dbf_outd(char **p, const char *label, char *buffer,
+			  int buflen, int offset, int total_size)
 {
 {
-	int len = 0;
-
-	if (offset == 0)
-		len += sprintf(out_buf + len, "%-24s  ", label);
-
+	if (!offset)
+		*p += sprintf(*p, "%-24s  ", label);
 	while (buflen--) {
 	while (buflen--) {
 		if (offset > 0) {
 		if (offset > 0) {
 			if ((offset % 32) == 0)
 			if ((offset % 32) == 0)
-				len += sprintf(out_buf + len, "\n%-24c  ", ' ');
+				*p += sprintf(*p, "\n%-24c  ", ' ');
 			else if ((offset % 4) == 0)
 			else if ((offset % 4) == 0)
-				len += sprintf(out_buf + len, " ");
+				*p += sprintf(*p, " ");
 		}
 		}
-		len += sprintf(out_buf + len, "%02x", *buffer++);
+		*p += sprintf(*p, "%02x", *buffer++);
 		if (++offset == total_size) {
 		if (++offset == total_size) {
-			len += sprintf(out_buf + len, "\n");
+			*p += sprintf(*p, "\n");
 			break;
 			break;
 		}
 		}
 	}
 	}
-
-	if (total_size == 0)
-		len += sprintf(out_buf + len, "\n");
-
-	return len;
+	if (!total_size)
+		*p += sprintf(*p, "\n");
 }
 }
 
 
-static int
-zfcp_dbf_view_header(debug_info_t * id, struct debug_view *view, int area,
-		     debug_entry_t * entry, char *out_buf)
+static int zfcp_dbf_view_header(debug_info_t *id, struct debug_view *view,
+				int area, debug_entry_t *entry, char *out_buf)
 {
 {
 	struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)DEBUG_DATA(entry);
 	struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)DEBUG_DATA(entry);
-	int len = 0;
+	struct timespec t;
+	char *p = out_buf;
 
 
 	if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) {
 	if (strncmp(dump->tag, "dump", ZFCP_DBF_TAG_SIZE) != 0) {
-		len += zfcp_dbf_stck(out_buf + len, "timestamp",
-				     entry->id.stck);
-		len += zfcp_dbf_view(out_buf + len, "cpu", "%02i",
-				     entry->id.fields.cpuid);
-	} else {
-		len += zfcp_dbf_view_dump(out_buf + len, NULL,
-					  dump->data,
-					  dump->size,
-					  dump->offset, dump->total_size);
+		zfcp_dbf_timestamp(entry->id.stck, &t);
+		zfcp_dbf_out(&p, "timestamp", "%011lu:%06lu",
+			     t.tv_sec, t.tv_nsec);
+		zfcp_dbf_out(&p, "cpu", "%02i", entry->id.fields.cpuid);
+	} else	{
+		zfcp_dbf_outd(&p, NULL, dump->data, dump->size, dump->offset,
+			      dump->total_size);
 		if ((dump->offset + dump->size) == dump->total_size)
 		if ((dump->offset + dump->size) == dump->total_size)
-			len += sprintf(out_buf + len, "\n");
+			p += sprintf(p, "\n");
 	}
 	}
-
-	return len;
+	return p - out_buf;
 }
 }
 
 
+/**
+ * zfcp_hba_dbf_event_fsf_response - trace event for request completion
+ * @fsf_req: request that has been completed
+ */
 void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
 void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
 {
 {
 	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct fsf_qtcb *qtcb = fsf_req->qtcb;
 	struct fsf_qtcb *qtcb = fsf_req->qtcb;
 	union fsf_prot_status_qual *prot_status_qual =
 	union fsf_prot_status_qual *prot_status_qual =
-	    &qtcb->prefix.prot_status_qual;
+					&qtcb->prefix.prot_status_qual;
 	union fsf_status_qual *fsf_status_qual = &qtcb->header.fsf_status_qual;
 	union fsf_status_qual *fsf_status_qual = &qtcb->header.fsf_status_qual;
 	struct scsi_cmnd *scsi_cmnd;
 	struct scsi_cmnd *scsi_cmnd;
 	struct zfcp_port *port;
 	struct zfcp_port *port;
 	struct zfcp_unit *unit;
 	struct zfcp_unit *unit;
 	struct zfcp_send_els *send_els;
 	struct zfcp_send_els *send_els;
 	struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
 	struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
-	struct zfcp_hba_dbf_record_response *response = &rec->type.response;
+	struct zfcp_hba_dbf_record_response *response = &rec->u.response;
 	int level;
 	int level;
 	unsigned long flags;
 	unsigned long flags;
 
 
 	spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
 	spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
-	memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));
+	memset(rec, 0, sizeof(*rec));
 	strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE);
 	strncpy(rec->tag, "resp", ZFCP_DBF_TAG_SIZE);
 
 
 	if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
 	if ((qtcb->prefix.prot_status != FSF_PROT_GOOD) &&
@@ -161,6 +166,9 @@ void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
 		   (fsf_req->fsf_command == FSF_QTCB_OPEN_LUN)) {
 		   (fsf_req->fsf_command == FSF_QTCB_OPEN_LUN)) {
 		strncpy(rec->tag2, "open", ZFCP_DBF_TAG_SIZE);
 		strncpy(rec->tag2, "open", ZFCP_DBF_TAG_SIZE);
 		level = 4;
 		level = 4;
+	} else if (qtcb->header.log_length) {
+		strncpy(rec->tag2, "qtcb", ZFCP_DBF_TAG_SIZE);
+		level = 5;
 	} else {
 	} else {
 		strncpy(rec->tag2, "norm", ZFCP_DBF_TAG_SIZE);
 		strncpy(rec->tag2, "norm", ZFCP_DBF_TAG_SIZE);
 		level = 6;
 		level = 6;
@@ -188,11 +196,9 @@ void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
 		if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
 		if (fsf_req->status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
 			break;
 			break;
 		scsi_cmnd = (struct scsi_cmnd *)fsf_req->data;
 		scsi_cmnd = (struct scsi_cmnd *)fsf_req->data;
-		if (scsi_cmnd != NULL) {
-			response->data.send_fcp.scsi_cmnd
-			    = (unsigned long)scsi_cmnd;
-			response->data.send_fcp.scsi_serial
-			    = scsi_cmnd->serial_number;
+		if (scsi_cmnd) {
+			response->u.fcp.cmnd = (unsigned long)scsi_cmnd;
+			response->u.fcp.serial = scsi_cmnd->serial_number;
 		}
 		}
 		break;
 		break;
 
 
@@ -200,25 +206,25 @@ void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
 	case FSF_QTCB_CLOSE_PORT:
 	case FSF_QTCB_CLOSE_PORT:
 	case FSF_QTCB_CLOSE_PHYSICAL_PORT:
 	case FSF_QTCB_CLOSE_PHYSICAL_PORT:
 		port = (struct zfcp_port *)fsf_req->data;
 		port = (struct zfcp_port *)fsf_req->data;
-		response->data.port.wwpn = port->wwpn;
-		response->data.port.d_id = port->d_id;
-		response->data.port.port_handle = qtcb->header.port_handle;
+		response->u.port.wwpn = port->wwpn;
+		response->u.port.d_id = port->d_id;
+		response->u.port.port_handle = qtcb->header.port_handle;
 		break;
 		break;
 
 
 	case FSF_QTCB_OPEN_LUN:
 	case FSF_QTCB_OPEN_LUN:
 	case FSF_QTCB_CLOSE_LUN:
 	case FSF_QTCB_CLOSE_LUN:
 		unit = (struct zfcp_unit *)fsf_req->data;
 		unit = (struct zfcp_unit *)fsf_req->data;
 		port = unit->port;
 		port = unit->port;
-		response->data.unit.wwpn = port->wwpn;
-		response->data.unit.fcp_lun = unit->fcp_lun;
-		response->data.unit.port_handle = qtcb->header.port_handle;
-		response->data.unit.lun_handle = qtcb->header.lun_handle;
+		response->u.unit.wwpn = port->wwpn;
+		response->u.unit.fcp_lun = unit->fcp_lun;
+		response->u.unit.port_handle = qtcb->header.port_handle;
+		response->u.unit.lun_handle = qtcb->header.lun_handle;
 		break;
 		break;
 
 
 	case FSF_QTCB_SEND_ELS:
 	case FSF_QTCB_SEND_ELS:
 		send_els = (struct zfcp_send_els *)fsf_req->data;
 		send_els = (struct zfcp_send_els *)fsf_req->data;
-		response->data.send_els.d_id = qtcb->bottom.support.d_id;
-		response->data.send_els.ls_code = send_els->ls_code >> 24;
+		response->u.els.d_id = qtcb->bottom.support.d_id;
+		response->u.els.ls_code = send_els->ls_code >> 24;
 		break;
 		break;
 
 
 	case FSF_QTCB_ABORT_FCP_CMND:
 	case FSF_QTCB_ABORT_FCP_CMND:
@@ -230,39 +236,54 @@ void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *fsf_req)
 		break;
 		break;
 	}
 	}
 
 
-	debug_event(adapter->hba_dbf, level,
-		    rec, sizeof(struct zfcp_hba_dbf_record));
+	debug_event(adapter->hba_dbf, level, rec, sizeof(*rec));
+
+	/* have fcp channel microcode fixed to use as little as possible */
+	if (fsf_req->fsf_command != FSF_QTCB_FCP_CMND) {
+		/* adjust length skipping trailing zeros */
+		char *buf = (char *)qtcb + qtcb->header.log_start;
+		int len = qtcb->header.log_length;
+		for (; len && !buf[len - 1]; len--);
+		zfcp_dbf_hexdump(adapter->hba_dbf, rec, sizeof(*rec), level,
+				 buf, len);
+	}
+
 	spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
 	spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
 }
 }
 
 
-void
-zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter,
-			     struct fsf_status_read_buffer *status_buffer)
+/**
+ * zfcp_hba_dbf_event_fsf_unsol - trace event for an unsolicited status buffer
+ * @tag: tag indicating which kind of unsolicited status has been received
+ * @adapter: adapter that has issued the unsolicited status buffer
+ * @status_buffer: buffer containing payload of unsolicited status
+ */
+void zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter,
+				  struct fsf_status_read_buffer *status_buffer)
 {
 {
 	struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
 	struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
 	unsigned long flags;
 	unsigned long flags;
 
 
 	spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
 	spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
-	memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));
+	memset(rec, 0, sizeof(*rec));
 	strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE);
 	strncpy(rec->tag, "stat", ZFCP_DBF_TAG_SIZE);
 	strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE);
 	strncpy(rec->tag2, tag, ZFCP_DBF_TAG_SIZE);
 
 
-	rec->type.status.failed = adapter->status_read_failed;
+	rec->u.status.failed = adapter->status_read_failed;
 	if (status_buffer != NULL) {
 	if (status_buffer != NULL) {
-		rec->type.status.status_type = status_buffer->status_type;
-		rec->type.status.status_subtype = status_buffer->status_subtype;
-		memcpy(&rec->type.status.queue_designator,
+		rec->u.status.status_type = status_buffer->status_type;
+		rec->u.status.status_subtype = status_buffer->status_subtype;
+		memcpy(&rec->u.status.queue_designator,
 		       &status_buffer->queue_designator,
 		       &status_buffer->queue_designator,
 		       sizeof(struct fsf_queue_designator));
 		       sizeof(struct fsf_queue_designator));
 
 
 		switch (status_buffer->status_type) {
 		switch (status_buffer->status_type) {
 		case FSF_STATUS_READ_SENSE_DATA_AVAIL:
 		case FSF_STATUS_READ_SENSE_DATA_AVAIL:
-			rec->type.status.payload_size =
+			rec->u.status.payload_size =
 			    ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL;
 			    ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL;
 			break;
 			break;
 
 
 		case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:
 		case FSF_STATUS_READ_BIT_ERROR_THRESHOLD:
-			rec->type.status.payload_size =
+			rec->u.status.payload_size =
 			    ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD;
 			    ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD;
 			break;
 			break;
 
 
@@ -270,119 +291,101 @@ zfcp_hba_dbf_event_fsf_unsol(const char *tag, struct zfcp_adapter *adapter,
 			switch (status_buffer->status_subtype) {
 			switch (status_buffer->status_subtype) {
 			case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
 			case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
 			case FSF_STATUS_READ_SUB_FDISC_FAILED:
 			case FSF_STATUS_READ_SUB_FDISC_FAILED:
-				rec->type.status.payload_size =
+				rec->u.status.payload_size =
 					sizeof(struct fsf_link_down_info);
 					sizeof(struct fsf_link_down_info);
 			}
 			}
 			break;
 			break;
 
 
 		case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:
 		case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:
-			rec->type.status.payload_size =
+			rec->u.status.payload_size =
 			    ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT;
 			    ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT;
 			break;
 			break;
 		}
 		}
-		memcpy(&rec->type.status.payload,
-		       &status_buffer->payload, rec->type.status.payload_size);
+		memcpy(&rec->u.status.payload,
+		       &status_buffer->payload, rec->u.status.payload_size);
 	}
 	}
 
 
-	debug_event(adapter->hba_dbf, 2,
-		    rec, sizeof(struct zfcp_hba_dbf_record));
+	debug_event(adapter->hba_dbf, 2, rec, sizeof(*rec));
 	spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
 	spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
 }
 }
 
 
-void
-zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status,
-			unsigned int qdio_error, unsigned int siga_error,
-			int sbal_index, int sbal_count)
+/**
+ * zfcp_hba_dbf_event_qdio - trace event for QDIO related failure
+ * @adapter: adapter affected by this QDIO related event
+ * @status: as passed by qdio module
+ * @qdio_error: as passed by qdio module
+ * @siga_error: as passed by qdio module
+ * @sbal_index: first buffer with error condition, as passed by qdio module
+ * @sbal_count: number of buffers affected, as passed by qdio module
+ */
+void zfcp_hba_dbf_event_qdio(struct zfcp_adapter *adapter, unsigned int status,
+			     unsigned int qdio_error, unsigned int siga_error,
+			     int sbal_index, int sbal_count)
 {
 {
-	struct zfcp_hba_dbf_record *rec = &adapter->hba_dbf_buf;
+	struct zfcp_hba_dbf_record *r = &adapter->hba_dbf_buf;
 	unsigned long flags;
 	unsigned long flags;
 
 
 	spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
 	spin_lock_irqsave(&adapter->hba_dbf_lock, flags);
-	memset(rec, 0, sizeof(struct zfcp_hba_dbf_record));
-	strncpy(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE);
-	rec->type.qdio.status = status;
-	rec->type.qdio.qdio_error = qdio_error;
-	rec->type.qdio.siga_error = siga_error;
-	rec->type.qdio.sbal_index = sbal_index;
-	rec->type.qdio.sbal_count = sbal_count;
-	debug_event(adapter->hba_dbf, 0,
-		    rec, sizeof(struct zfcp_hba_dbf_record));
+	memset(r, 0, sizeof(*r));
+	strncpy(r->tag, "qdio", ZFCP_DBF_TAG_SIZE);
+	r->u.qdio.status = status;
+	r->u.qdio.qdio_error = qdio_error;
+	r->u.qdio.siga_error = siga_error;
+	r->u.qdio.sbal_index = sbal_index;
+	r->u.qdio.sbal_count = sbal_count;
+	debug_event(adapter->hba_dbf, 0, r, sizeof(*r));
 	spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
 	spin_unlock_irqrestore(&adapter->hba_dbf_lock, flags);
 }
 }
 
 
-static int
-zfcp_hba_dbf_view_response(char *out_buf,
-			   struct zfcp_hba_dbf_record_response *rec)
-{
-	int len = 0;
-
-	len += zfcp_dbf_view(out_buf + len, "fsf_command", "0x%08x",
-			     rec->fsf_command);
-	len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx",
-			     rec->fsf_reqid);
-	len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x",
-			     rec->fsf_seqno);
-	len += zfcp_dbf_stck(out_buf + len, "fsf_issued", rec->fsf_issued);
-	len += zfcp_dbf_view(out_buf + len, "fsf_prot_status", "0x%08x",
-			     rec->fsf_prot_status);
-	len += zfcp_dbf_view(out_buf + len, "fsf_status", "0x%08x",
-			     rec->fsf_status);
-	len += zfcp_dbf_view_dump(out_buf + len, "fsf_prot_status_qual",
-				  rec->fsf_prot_status_qual,
-				  FSF_PROT_STATUS_QUAL_SIZE,
-				  0, FSF_PROT_STATUS_QUAL_SIZE);
-	len += zfcp_dbf_view_dump(out_buf + len, "fsf_status_qual",
-				  rec->fsf_status_qual,
-				  FSF_STATUS_QUALIFIER_SIZE,
-				  0, FSF_STATUS_QUALIFIER_SIZE);
-	len += zfcp_dbf_view(out_buf + len, "fsf_req_status", "0x%08x",
-			     rec->fsf_req_status);
-	len += zfcp_dbf_view(out_buf + len, "sbal_first", "0x%02x",
-			     rec->sbal_first);
-	len += zfcp_dbf_view(out_buf + len, "sbal_curr", "0x%02x",
-			     rec->sbal_curr);
-	len += zfcp_dbf_view(out_buf + len, "sbal_last", "0x%02x",
-			     rec->sbal_last);
-	len += zfcp_dbf_view(out_buf + len, "pool", "0x%02x", rec->pool);
-
-	switch (rec->fsf_command) {
+static void zfcp_hba_dbf_view_response(char **p,
+				       struct zfcp_hba_dbf_record_response *r)
+{
+	struct timespec t;
+
+	zfcp_dbf_out(p, "fsf_command", "0x%08x", r->fsf_command);
+	zfcp_dbf_out(p, "fsf_reqid", "0x%0Lx", r->fsf_reqid);
+	zfcp_dbf_out(p, "fsf_seqno", "0x%08x", r->fsf_seqno);
+	zfcp_dbf_timestamp(r->fsf_issued, &t);
+	zfcp_dbf_out(p, "fsf_issued", "%011lu:%06lu", t.tv_sec, t.tv_nsec);
+	zfcp_dbf_out(p, "fsf_prot_status", "0x%08x", r->fsf_prot_status);
+	zfcp_dbf_out(p, "fsf_status", "0x%08x", r->fsf_status);
+	zfcp_dbf_outd(p, "fsf_prot_status_qual", r->fsf_prot_status_qual,
+		      FSF_PROT_STATUS_QUAL_SIZE, 0, FSF_PROT_STATUS_QUAL_SIZE);
+	zfcp_dbf_outd(p, "fsf_status_qual", r->fsf_status_qual,
+		      FSF_STATUS_QUALIFIER_SIZE, 0, FSF_STATUS_QUALIFIER_SIZE);
+	zfcp_dbf_out(p, "fsf_req_status", "0x%08x", r->fsf_req_status);
+	zfcp_dbf_out(p, "sbal_first", "0x%02x", r->sbal_first);
+	zfcp_dbf_out(p, "sbal_curr", "0x%02x", r->sbal_curr);
+	zfcp_dbf_out(p, "sbal_last", "0x%02x", r->sbal_last);
+	zfcp_dbf_out(p, "pool", "0x%02x", r->pool);
+
+	switch (r->fsf_command) {
 	case FSF_QTCB_FCP_CMND:
 	case FSF_QTCB_FCP_CMND:
-		if (rec->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
+		if (r->fsf_req_status & ZFCP_STATUS_FSFREQ_TASK_MANAGEMENT)
 			break;
 			break;
-		len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx",
-				     rec->data.send_fcp.scsi_cmnd);
-		len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx",
-				     rec->data.send_fcp.scsi_serial);
+		zfcp_dbf_out(p, "scsi_cmnd", "0x%0Lx", r->u.fcp.cmnd);
+		zfcp_dbf_out(p, "scsi_serial", "0x%016Lx", r->u.fcp.serial);
 		break;
 		break;
 
 
 	case FSF_QTCB_OPEN_PORT_WITH_DID:
 	case FSF_QTCB_OPEN_PORT_WITH_DID:
 	case FSF_QTCB_CLOSE_PORT:
 	case FSF_QTCB_CLOSE_PORT:
 	case FSF_QTCB_CLOSE_PHYSICAL_PORT:
 	case FSF_QTCB_CLOSE_PHYSICAL_PORT:
-		len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx",
-				     rec->data.port.wwpn);
-		len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x",
-				     rec->data.port.d_id);
-		len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x",
-				     rec->data.port.port_handle);
+		zfcp_dbf_out(p, "wwpn", "0x%016Lx", r->u.port.wwpn);
+		zfcp_dbf_out(p, "d_id", "0x%06x", r->u.port.d_id);
+		zfcp_dbf_out(p, "port_handle", "0x%08x", r->u.port.port_handle);
 		break;
 		break;
 
 
 	case FSF_QTCB_OPEN_LUN:
 	case FSF_QTCB_OPEN_LUN:
 	case FSF_QTCB_CLOSE_LUN:
 	case FSF_QTCB_CLOSE_LUN:
-		len += zfcp_dbf_view(out_buf + len, "wwpn", "0x%016Lx",
-				     rec->data.unit.wwpn);
-		len += zfcp_dbf_view(out_buf + len, "fcp_lun", "0x%016Lx",
-				     rec->data.unit.fcp_lun);
-		len += zfcp_dbf_view(out_buf + len, "port_handle", "0x%08x",
-				     rec->data.unit.port_handle);
-		len += zfcp_dbf_view(out_buf + len, "lun_handle", "0x%08x",
-				     rec->data.unit.lun_handle);
+		zfcp_dbf_out(p, "wwpn", "0x%016Lx", r->u.unit.wwpn);
+		zfcp_dbf_out(p, "fcp_lun", "0x%016Lx", r->u.unit.fcp_lun);
+		zfcp_dbf_out(p, "port_handle", "0x%08x", r->u.unit.port_handle);
+		zfcp_dbf_out(p, "lun_handle", "0x%08x", r->u.unit.lun_handle);
 		break;
 		break;
 
 
 	case FSF_QTCB_SEND_ELS:
 	case FSF_QTCB_SEND_ELS:
-		len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x",
-				     rec->data.send_els.d_id);
-		len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x",
-				     rec->data.send_els.ls_code);
+		zfcp_dbf_out(p, "d_id", "0x%06x", r->u.els.d_id);
+		zfcp_dbf_out(p, "ls_code", "0x%02x", r->u.els.ls_code);
 		break;
 		break;
 
 
 	case FSF_QTCB_ABORT_FCP_CMND:
 	case FSF_QTCB_ABORT_FCP_CMND:
@@ -393,74 +396,52 @@ zfcp_hba_dbf_view_response(char *out_buf,
 	case FSF_QTCB_UPLOAD_CONTROL_FILE:
 	case FSF_QTCB_UPLOAD_CONTROL_FILE:
 		break;
 		break;
 	}
 	}
-
-	return len;
 }
 }
 
 
-static int
-zfcp_hba_dbf_view_status(char *out_buf, struct zfcp_hba_dbf_record_status *rec)
+static void zfcp_hba_dbf_view_status(char **p,
+				     struct zfcp_hba_dbf_record_status *r)
 {
 {
-	int len = 0;
-
-	len += zfcp_dbf_view(out_buf + len, "failed", "0x%02x", rec->failed);
-	len += zfcp_dbf_view(out_buf + len, "status_type", "0x%08x",
-			     rec->status_type);
-	len += zfcp_dbf_view(out_buf + len, "status_subtype", "0x%08x",
-			     rec->status_subtype);
-	len += zfcp_dbf_view_dump(out_buf + len, "queue_designator",
-				  (char *)&rec->queue_designator,
-				  sizeof(struct fsf_queue_designator),
-				  0, sizeof(struct fsf_queue_designator));
-	len += zfcp_dbf_view_dump(out_buf + len, "payload",
-				  (char *)&rec->payload,
-				  rec->payload_size, 0, rec->payload_size);
-
-	return len;
+	zfcp_dbf_out(p, "failed", "0x%02x", r->failed);
+	zfcp_dbf_out(p, "status_type", "0x%08x", r->status_type);
+	zfcp_dbf_out(p, "status_subtype", "0x%08x", r->status_subtype);
+	zfcp_dbf_outd(p, "queue_designator", (char *)&r->queue_designator,
+		      sizeof(struct fsf_queue_designator), 0,
+		      sizeof(struct fsf_queue_designator));
+	zfcp_dbf_outd(p, "payload", (char *)&r->payload, r->payload_size, 0,
+		      r->payload_size);
 }
 }
 
 
-static int
-zfcp_hba_dbf_view_qdio(char *out_buf, struct zfcp_hba_dbf_record_qdio *rec)
+static void zfcp_hba_dbf_view_qdio(char **p, struct zfcp_hba_dbf_record_qdio *r)
 {
 {
-	int len = 0;
-
-	len += zfcp_dbf_view(out_buf + len, "status", "0x%08x", rec->status);
-	len += zfcp_dbf_view(out_buf + len, "qdio_error", "0x%08x",
-			     rec->qdio_error);
-	len += zfcp_dbf_view(out_buf + len, "siga_error", "0x%08x",
-			     rec->siga_error);
-	len += zfcp_dbf_view(out_buf + len, "sbal_index", "0x%02x",
-			     rec->sbal_index);
-	len += zfcp_dbf_view(out_buf + len, "sbal_count", "0x%02x",
-			     rec->sbal_count);
-
-	return len;
+	zfcp_dbf_out(p, "status", "0x%08x", r->status);
+	zfcp_dbf_out(p, "qdio_error", "0x%08x", r->qdio_error);
+	zfcp_dbf_out(p, "siga_error", "0x%08x", r->siga_error);
+	zfcp_dbf_out(p, "sbal_index", "0x%02x", r->sbal_index);
+	zfcp_dbf_out(p, "sbal_count", "0x%02x", r->sbal_count);
 }
 }
 
 
-static int
-zfcp_hba_dbf_view_format(debug_info_t * id, struct debug_view *view,
-			 char *out_buf, const char *in_buf)
+static int zfcp_hba_dbf_view_format(debug_info_t *id, struct debug_view *view,
+				    char *out_buf, const char *in_buf)
 {
 {
-	struct zfcp_hba_dbf_record *rec = (struct zfcp_hba_dbf_record *)in_buf;
-	int len = 0;
+	struct zfcp_hba_dbf_record *r = (struct zfcp_hba_dbf_record *)in_buf;
+	char *p = out_buf;
 
 
-	if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
+	if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
 		return 0;
 		return 0;
 
 
-	len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag);
-	if (isalpha(rec->tag2[0]))
-		len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2);
-	if (strncmp(rec->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0)
-		len += zfcp_hba_dbf_view_response(out_buf + len,
-						  &rec->type.response);
-	else if (strncmp(rec->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0)
-		len += zfcp_hba_dbf_view_status(out_buf + len,
-						&rec->type.status);
-	else if (strncmp(rec->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0)
-		len += zfcp_hba_dbf_view_qdio(out_buf + len, &rec->type.qdio);
+	zfcp_dbf_tag(&p, "tag", r->tag);
+	if (isalpha(r->tag2[0]))
+		zfcp_dbf_tag(&p, "tag2", r->tag2);
 
 
-	len += sprintf(out_buf + len, "\n");
+	if (strncmp(r->tag, "resp", ZFCP_DBF_TAG_SIZE) == 0)
+		zfcp_hba_dbf_view_response(&p, &r->u.response);
+	else if (strncmp(r->tag, "stat", ZFCP_DBF_TAG_SIZE) == 0)
+		zfcp_hba_dbf_view_status(&p, &r->u.status);
+	else if (strncmp(r->tag, "qdio", ZFCP_DBF_TAG_SIZE) == 0)
+		zfcp_hba_dbf_view_qdio(&p, &r->u.qdio);
 
 
-	return len;
+	p += sprintf(p, "\n");
+	return p - out_buf;
 }
 }
 
 
 static struct debug_view zfcp_hba_dbf_view = {
 static struct debug_view zfcp_hba_dbf_view = {
@@ -472,219 +453,570 @@ static struct debug_view zfcp_hba_dbf_view = {
 	NULL
 	NULL
 };
 };
 
 
-static void
-_zfcp_san_dbf_event_common_ct(const char *tag, struct zfcp_fsf_req *fsf_req,
-			      u32 s_id, u32 d_id, void *buffer, int buflen)
+static const char *zfcp_rec_dbf_tags[] = {
+	[ZFCP_REC_DBF_ID_THREAD] = "thread",
+	[ZFCP_REC_DBF_ID_TARGET] = "target",
+	[ZFCP_REC_DBF_ID_TRIGGER] = "trigger",
+	[ZFCP_REC_DBF_ID_ACTION] = "action",
+};
+
+static const char *zfcp_rec_dbf_ids[] = {
+	[1]	= "new",
+	[2]	= "ready",
+	[3]	= "kill",
+	[4]	= "down sleep",
+	[5]	= "down wakeup",
+	[6]	= "down sleep ecd",
+	[7]	= "down wakeup ecd",
+	[8]	= "down sleep epd",
+	[9]	= "down wakeup epd",
+	[10]	= "online",
+	[11]	= "operational",
+	[12]	= "scsi slave destroy",
+	[13]	= "propagate failed adapter",
+	[14]	= "propagate failed port",
+	[15]	= "block adapter",
+	[16]	= "unblock adapter",
+	[17]	= "block port",
+	[18]	= "unblock port",
+	[19]	= "block unit",
+	[20]	= "unblock unit",
+	[21]	= "unit recovery failed",
+	[22]	= "port recovery failed",
+	[23]	= "adapter recovery failed",
+	[24]	= "qdio queues down",
+	[25]	= "p2p failed",
+	[26]	= "nameserver lookup failed",
+	[27]	= "nameserver port failed",
+	[28]	= "link up",
+	[29]	= "link down",
+	[30]	= "link up status read",
+	[31]	= "open port failed",
+	[32]	= "open port failed",
+	[33]	= "close port",
+	[34]	= "open unit failed",
+	[35]	= "exclusive open unit failed",
+	[36]	= "shared open unit failed",
+	[37]	= "link down",
+	[38]	= "link down status read no link",
+	[39]	= "link down status read fdisc login",
+	[40]	= "link down status read firmware update",
+	[41]	= "link down status read unknown reason",
+	[42]	= "link down ecd incomplete",
+	[43]	= "link down epd incomplete",
+	[44]	= "sysfs adapter recovery",
+	[45]	= "sysfs port recovery",
+	[46]	= "sysfs unit recovery",
+	[47]	= "port boxed abort",
+	[48]	= "unit boxed abort",
+	[49]	= "port boxed ct",
+	[50]	= "port boxed close physical",
+	[51]	= "port boxed open unit",
+	[52]	= "port boxed close unit",
+	[53]	= "port boxed fcp",
+	[54]	= "unit boxed fcp",
+	[55]	= "port access denied ct",
+	[56]	= "port access denied els",
+	[57]	= "port access denied open port",
+	[58]	= "port access denied close physical",
+	[59]	= "unit access denied open unit",
+	[60]	= "shared unit access denied open unit",
+	[61]	= "unit access denied fcp",
+	[62]	= "request timeout",
+	[63]	= "adisc link test reject or timeout",
+	[64]	= "adisc link test d_id changed",
+	[65]	= "adisc link test failed",
+	[66]	= "recovery out of memory",
+	[67]	= "adapter recovery repeated after state change",
+	[68]	= "port recovery repeated after state change",
+	[69]	= "unit recovery repeated after state change",
+	[70]	= "port recovery follow-up after successful adapter recovery",
+	[71]	= "adapter recovery escalation after failed adapter recovery",
+	[72]	= "port recovery follow-up after successful physical port "
+		  "recovery",
+	[73]	= "adapter recovery escalation after failed physical port "
+		  "recovery",
+	[74]	= "unit recovery follow-up after successful port recovery",
+	[75]	= "physical port recovery escalation after failed port "
+		  "recovery",
+	[76]	= "port recovery escalation after failed unit recovery",
+	[77]	= "recovery opening nameserver port",
+	[78]	= "duplicate request id",
+	[79]	= "link down",
+	[80]	= "exclusive read-only unit access unsupported",
+	[81]	= "shared read-write unit access unsupported",
+	[82]	= "incoming rscn",
+	[83]	= "incoming plogi",
+	[84]	= "incoming logo",
+	[85]	= "online",
+	[86]	= "offline",
+	[87]	= "ccw device gone",
+	[88]	= "ccw device no path",
+	[89]	= "ccw device operational",
+	[90]	= "ccw device shutdown",
+	[91]	= "sysfs port addition",
+	[92]	= "sysfs port removal",
+	[93]	= "sysfs adapter recovery",
+	[94]	= "sysfs unit addition",
+	[95]	= "sysfs unit removal",
+	[96]	= "sysfs port recovery",
+	[97]	= "sysfs unit recovery",
+	[98]	= "sequence number mismatch",
+	[99]	= "link up",
+	[100]	= "error state",
+	[101]	= "status read physical port closed",
+	[102]	= "link up status read",
+	[103]	= "too many failed status read buffers",
+	[104]	= "port handle not valid abort",
+	[105]	= "lun handle not valid abort",
+	[106]	= "port handle not valid ct",
+	[107]	= "port handle not valid close port",
+	[108]	= "port handle not valid close physical port",
+	[109]	= "port handle not valid open unit",
+	[110]	= "port handle not valid close unit",
+	[111]	= "lun handle not valid close unit",
+	[112]	= "port handle not valid fcp",
+	[113]	= "lun handle not valid fcp",
+	[114]	= "handle mismatch fcp",
+	[115]	= "lun not valid fcp",
+	[116]	= "qdio send failed",
+	[117]	= "version mismatch",
+	[118]	= "incompatible qtcb type",
+	[119]	= "unknown protocol status",
+	[120]	= "unknown fsf command",
+	[121]	= "no recommendation for status qualifier",
+	[122]	= "status read physical port closed in error",
+	[123]	= "fc service class not supported ct",
+	[124]	= "fc service class not supported els",
+	[125]	= "need newer zfcp",
+	[126]	= "need newer microcode",
+	[127]	= "arbitrated loop not supported",
+	[128]	= "unknown topology",
+	[129]	= "qtcb size mismatch",
+	[130]	= "unknown fsf status ecd",
+	[131]	= "fcp request too big",
+	[132]	= "fc service class not supported fcp",
+	[133]	= "data direction not valid fcp",
+	[134]	= "command length not valid fcp",
+	[135]	= "status read act update",
+	[136]	= "status read cfdc update",
+	[137]	= "hbaapi port open",
+	[138]	= "hbaapi unit open",
+	[139]	= "hbaapi unit shutdown",
+	[140]	= "qdio error",
+	[141]	= "scsi host reset",
+	[142]	= "dismissing fsf request for recovery action",
+	[143]	= "recovery action timed out",
+	[144]	= "recovery action gone",
+	[145]	= "recovery action being processed",
+	[146]	= "recovery action ready for next step",
+};
+
+static int zfcp_rec_dbf_view_format(debug_info_t *id, struct debug_view *view,
+				    char *buf, const char *_rec)
+{
+	struct zfcp_rec_dbf_record *r = (struct zfcp_rec_dbf_record *)_rec;
+	char *p = buf;
+
+	zfcp_dbf_outs(&p, "tag", zfcp_rec_dbf_tags[r->id]);
+	zfcp_dbf_outs(&p, "hint", zfcp_rec_dbf_ids[r->id2]);
+	zfcp_dbf_out(&p, "id", "%d", r->id2);
+	switch (r->id) {
+	case ZFCP_REC_DBF_ID_THREAD:
+		zfcp_dbf_out(&p, "total", "%d", r->u.thread.total);
+		zfcp_dbf_out(&p, "ready", "%d", r->u.thread.ready);
+		zfcp_dbf_out(&p, "running", "%d", r->u.thread.running);
+		break;
+	case ZFCP_REC_DBF_ID_TARGET:
+		zfcp_dbf_out(&p, "reference", "0x%016Lx", r->u.target.ref);
+		zfcp_dbf_out(&p, "status", "0x%08x", r->u.target.status);
+		zfcp_dbf_out(&p, "erp_count", "%d", r->u.target.erp_count);
+		zfcp_dbf_out(&p, "d_id", "0x%06x", r->u.target.d_id);
+		zfcp_dbf_out(&p, "wwpn", "0x%016Lx", r->u.target.wwpn);
+		zfcp_dbf_out(&p, "fcp_lun", "0x%016Lx", r->u.target.fcp_lun);
+		break;
+	case ZFCP_REC_DBF_ID_TRIGGER:
+		zfcp_dbf_out(&p, "reference", "0x%016Lx", r->u.trigger.ref);
+		zfcp_dbf_out(&p, "erp_action", "0x%016Lx", r->u.trigger.action);
+		zfcp_dbf_out(&p, "requested", "%d", r->u.trigger.want);
+		zfcp_dbf_out(&p, "executed", "%d", r->u.trigger.need);
+		zfcp_dbf_out(&p, "wwpn", "0x%016Lx", r->u.trigger.wwpn);
+		zfcp_dbf_out(&p, "fcp_lun", "0x%016Lx", r->u.trigger.fcp_lun);
+		zfcp_dbf_out(&p, "adapter_status", "0x%08x", r->u.trigger.as);
+		zfcp_dbf_out(&p, "port_status", "0x%08x", r->u.trigger.ps);
+		zfcp_dbf_out(&p, "unit_status", "0x%08x", r->u.trigger.us);
+		break;
+	case ZFCP_REC_DBF_ID_ACTION:
+		zfcp_dbf_out(&p, "erp_action", "0x%016Lx", r->u.action.action);
+		zfcp_dbf_out(&p, "fsf_req", "0x%016Lx", r->u.action.fsf_req);
+		zfcp_dbf_out(&p, "status", "0x%08Lx", r->u.action.status);
+		zfcp_dbf_out(&p, "step", "0x%08Lx", r->u.action.step);
+		break;
+	}
+	p += sprintf(p, "\n");
+	return p - buf;
+}
+
+static struct debug_view zfcp_rec_dbf_view = {
+	"structured",
+	NULL,
+	&zfcp_dbf_view_header,
+	&zfcp_rec_dbf_view_format,
+	NULL,
+	NULL
+};
+
+/**
+ * zfcp_rec_dbf_event_thread - trace event related to recovery thread operation
+ * @id2: identifier for event
+ * @adapter: adapter
+ * @lock: non-zero value indicates that erp_lock has not yet been acquired
+ */
+void zfcp_rec_dbf_event_thread(u8 id2, struct zfcp_adapter *adapter, int lock)
+{
+	struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
+	unsigned long flags = 0;
+	struct list_head *entry;
+	unsigned ready = 0, running = 0, total;
+
+	if (lock)
+		read_lock_irqsave(&adapter->erp_lock, flags);
+	list_for_each(entry, &adapter->erp_ready_head)
+		ready++;
+	list_for_each(entry, &adapter->erp_running_head)
+		running++;
+	total = adapter->erp_total_count;
+	if (lock)
+		read_unlock_irqrestore(&adapter->erp_lock, flags);
+
+	spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
+	memset(r, 0, sizeof(*r));
+	r->id = ZFCP_REC_DBF_ID_THREAD;
+	r->id2 = id2;
+	r->u.thread.total = total;
+	r->u.thread.ready = ready;
+	r->u.thread.running = running;
+	debug_event(adapter->rec_dbf, 5, r, sizeof(*r));
+	spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags);
+}
+
+static void zfcp_rec_dbf_event_target(u8 id2, void *ref,
+				      struct zfcp_adapter *adapter,
+				      atomic_t *status, atomic_t *erp_count,
+				      u64 wwpn, u32 d_id, u64 fcp_lun)
+{
+	struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
+	unsigned long flags;
+
+	spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
+	memset(r, 0, sizeof(*r));
+	r->id = ZFCP_REC_DBF_ID_TARGET;
+	r->id2 = id2;
+	r->u.target.ref = (unsigned long)ref;
+	r->u.target.status = atomic_read(status);
+	r->u.target.wwpn = wwpn;
+	r->u.target.d_id = d_id;
+	r->u.target.fcp_lun = fcp_lun;
+	r->u.target.erp_count = atomic_read(erp_count);
+	debug_event(adapter->rec_dbf, 3, r, sizeof(*r));
+	spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags);
+}
+
+/**
+ * zfcp_rec_dbf_event_adapter - trace event for adapter state change
+ * @id: identifier for trigger of state change
+ * @ref: additional reference (e.g. request)
+ * @adapter: adapter
+ */
+void zfcp_rec_dbf_event_adapter(u8 id, void *ref, struct zfcp_adapter *adapter)
+{
+	zfcp_rec_dbf_event_target(id, ref, adapter, &adapter->status,
+				  &adapter->erp_counter, 0, 0, 0);
+}
+
+/**
+ * zfcp_rec_dbf_event_port - trace event for port state change
+ * @id: identifier for trigger of state change
+ * @ref: additional reference (e.g. request)
+ * @port: port
+ */
+void zfcp_rec_dbf_event_port(u8 id, void *ref, struct zfcp_port *port)
 {
 {
-	struct zfcp_send_ct *send_ct = (struct zfcp_send_ct *)fsf_req->data;
-	struct zfcp_port *port = send_ct->port;
 	struct zfcp_adapter *adapter = port->adapter;
 	struct zfcp_adapter *adapter = port->adapter;
-	struct ct_hdr *header = (struct ct_hdr *)buffer;
-	struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf;
-	struct zfcp_san_dbf_record_ct *ct = &rec->type.ct;
+
+	zfcp_rec_dbf_event_target(id, ref, adapter, &port->status,
+				  &port->erp_counter, port->wwpn, port->d_id,
+				  0);
+}
+
+/**
+ * zfcp_rec_dbf_event_unit - trace event for unit state change
+ * @id: identifier for trigger of state change
+ * @ref: additional reference (e.g. request)
+ * @unit: unit
+ */
+void zfcp_rec_dbf_event_unit(u8 id, void *ref, struct zfcp_unit *unit)
+{
+	struct zfcp_port *port = unit->port;
+	struct zfcp_adapter *adapter = port->adapter;
+
+	zfcp_rec_dbf_event_target(id, ref, adapter, &unit->status,
+				  &unit->erp_counter, port->wwpn, port->d_id,
+				  unit->fcp_lun);
+}
+
+/**
+ * zfcp_rec_dbf_event_trigger - trace event for triggered error recovery
+ * @id2: identifier for error recovery trigger
+ * @ref: additional reference (e.g. request)
+ * @want: originally requested error recovery action
+ * @need: error recovery action actually initiated
+ * @action: address of error recovery action struct
+ * @adapter: adapter
+ * @port: port
+ * @unit: unit
+ */
+void zfcp_rec_dbf_event_trigger(u8 id2, void *ref, u8 want, u8 need,
+				void *action, struct zfcp_adapter *adapter,
+				struct zfcp_port *port, struct zfcp_unit *unit)
+{
+	struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
 	unsigned long flags;
 	unsigned long flags;
 
 
-	spin_lock_irqsave(&adapter->san_dbf_lock, flags);
-	memset(rec, 0, sizeof(struct zfcp_san_dbf_record));
-	strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
-	rec->fsf_reqid = (unsigned long)fsf_req;
-	rec->fsf_seqno = fsf_req->seq_no;
-	rec->s_id = s_id;
-	rec->d_id = d_id;
-	if (strncmp(tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {
-		ct->type.request.cmd_req_code = header->cmd_rsp_code;
-		ct->type.request.revision = header->revision;
-		ct->type.request.gs_type = header->gs_type;
-		ct->type.request.gs_subtype = header->gs_subtype;
-		ct->type.request.options = header->options;
-		ct->type.request.max_res_size = header->max_res_size;
-	} else if (strncmp(tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) {
-		ct->type.response.cmd_rsp_code = header->cmd_rsp_code;
-		ct->type.response.revision = header->revision;
-		ct->type.response.reason_code = header->reason_code;
-		ct->type.response.reason_code_expl = header->reason_code_expl;
-		ct->type.response.vendor_unique = header->vendor_unique;
+	spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
+	memset(r, 0, sizeof(*r));
+	r->id = ZFCP_REC_DBF_ID_TRIGGER;
+	r->id2 = id2;
+	r->u.trigger.ref = (unsigned long)ref;
+	r->u.trigger.want = want;
+	r->u.trigger.need = need;
+	r->u.trigger.action = (unsigned long)action;
+	r->u.trigger.as = atomic_read(&adapter->status);
+	if (port) {
+		r->u.trigger.ps = atomic_read(&port->status);
+		r->u.trigger.wwpn = port->wwpn;
 	}
 	}
-	ct->payload_size =
-	    min(buflen - (int)sizeof(struct ct_hdr), ZFCP_DBF_CT_PAYLOAD);
-	memcpy(ct->payload, buffer + sizeof(struct ct_hdr), ct->payload_size);
-	debug_event(adapter->san_dbf, 3,
-		    rec, sizeof(struct zfcp_san_dbf_record));
-	spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
+	if (unit) {
+		r->u.trigger.us = atomic_read(&unit->status);
+		r->u.trigger.fcp_lun = unit->fcp_lun;
+	}
+	debug_event(adapter->rec_dbf, action ? 1 : 4, r, sizeof(*r));
+	spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags);
 }
 }
 
 
+/**
+ * zfcp_rec_dbf_event_action - trace event showing progress of recovery action
+ * @id2: identifier
+ * @erp_action: error recovery action struct pointer
+ */
+void zfcp_rec_dbf_event_action(u8 id2, struct zfcp_erp_action *erp_action)
+{
+	struct zfcp_adapter *adapter = erp_action->adapter;
+	struct zfcp_rec_dbf_record *r = &adapter->rec_dbf_buf;
+	unsigned long flags;
+
+	spin_lock_irqsave(&adapter->rec_dbf_lock, flags);
+	memset(r, 0, sizeof(*r));
+	r->id = ZFCP_REC_DBF_ID_ACTION;
+	r->id2 = id2;
+	r->u.action.action = (unsigned long)erp_action;
+	r->u.action.status = erp_action->status;
+	r->u.action.step = erp_action->step;
+	r->u.action.fsf_req = (unsigned long)erp_action->fsf_req;
+	debug_event(adapter->rec_dbf, 4, r, sizeof(*r));
+	spin_unlock_irqrestore(&adapter->rec_dbf_lock, flags);
+}
+
+/**
+ * zfcp_san_dbf_event_ct_request - trace event for issued CT request
+ * @fsf_req: request containing issued CT data
+ */
 void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
 void zfcp_san_dbf_event_ct_request(struct zfcp_fsf_req *fsf_req)
 {
 {
 	struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
 	struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
 	struct zfcp_port *port = ct->port;
 	struct zfcp_port *port = ct->port;
 	struct zfcp_adapter *adapter = port->adapter;
 	struct zfcp_adapter *adapter = port->adapter;
+	struct ct_hdr *hdr = zfcp_sg_to_address(ct->req);
+	struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
+	struct zfcp_san_dbf_record_ct_request *oct = &r->u.ct_req;
+	unsigned long flags;
 
 
-	_zfcp_san_dbf_event_common_ct("octc", fsf_req,
-				      fc_host_port_id(adapter->scsi_host),
-				      port->d_id, zfcp_sg_to_address(ct->req),
-				      ct->req->length);
+	spin_lock_irqsave(&adapter->san_dbf_lock, flags);
+	memset(r, 0, sizeof(*r));
+	strncpy(r->tag, "octc", ZFCP_DBF_TAG_SIZE);
+	r->fsf_reqid = (unsigned long)fsf_req;
+	r->fsf_seqno = fsf_req->seq_no;
+	r->s_id = fc_host_port_id(adapter->scsi_host);
+	r->d_id = port->d_id;
+	oct->cmd_req_code = hdr->cmd_rsp_code;
+	oct->revision = hdr->revision;
+	oct->gs_type = hdr->gs_type;
+	oct->gs_subtype = hdr->gs_subtype;
+	oct->options = hdr->options;
+	oct->max_res_size = hdr->max_res_size;
+	oct->len = min((int)ct->req->length - (int)sizeof(struct ct_hdr),
+		       ZFCP_DBF_CT_PAYLOAD);
+	memcpy(oct->payload, (void *)hdr + sizeof(struct ct_hdr), oct->len);
+	debug_event(adapter->san_dbf, 3, r, sizeof(*r));
+	spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
 }
 }
 
 
+/**
+ * zfcp_san_dbf_event_ct_response - trace event for completion of CT request
+ * @fsf_req: request containing CT response
+ */
 void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
 void zfcp_san_dbf_event_ct_response(struct zfcp_fsf_req *fsf_req)
 {
 {
 	struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
 	struct zfcp_send_ct *ct = (struct zfcp_send_ct *)fsf_req->data;
 	struct zfcp_port *port = ct->port;
 	struct zfcp_port *port = ct->port;
 	struct zfcp_adapter *adapter = port->adapter;
 	struct zfcp_adapter *adapter = port->adapter;
+	struct ct_hdr *hdr = zfcp_sg_to_address(ct->resp);
+	struct zfcp_san_dbf_record *r = &adapter->san_dbf_buf;
+	struct zfcp_san_dbf_record_ct_response *rct = &r->u.ct_resp;
+	unsigned long flags;
 
 
-	_zfcp_san_dbf_event_common_ct("rctc", fsf_req, port->d_id,
-				      fc_host_port_id(adapter->scsi_host),
-				      zfcp_sg_to_address(ct->resp),
-				      ct->resp->length);
+	spin_lock_irqsave(&adapter->san_dbf_lock, flags);
+	memset(r, 0, sizeof(*r));
+	strncpy(r->tag, "rctc", ZFCP_DBF_TAG_SIZE);
+	r->fsf_reqid = (unsigned long)fsf_req;
+	r->fsf_seqno = fsf_req->seq_no;
+	r->s_id = port->d_id;
+	r->d_id = fc_host_port_id(adapter->scsi_host);
+	rct->cmd_rsp_code = hdr->cmd_rsp_code;
+	rct->revision = hdr->revision;
+	rct->reason_code = hdr->reason_code;
+	rct->expl = hdr->reason_code_expl;
+	rct->vendor_unique = hdr->vendor_unique;
+	rct->len = min((int)ct->resp->length - (int)sizeof(struct ct_hdr),
+		       ZFCP_DBF_CT_PAYLOAD);
+	memcpy(rct->payload, (void *)hdr + sizeof(struct ct_hdr), rct->len);
+	debug_event(adapter->san_dbf, 3, r, sizeof(*r));
+	spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
 }
 }
 
 
-static void
-_zfcp_san_dbf_event_common_els(const char *tag, int level,
-			       struct zfcp_fsf_req *fsf_req, u32 s_id,
-			       u32 d_id, u8 ls_code, void *buffer, int buflen)
+static void zfcp_san_dbf_event_els(const char *tag, int level,
+				   struct zfcp_fsf_req *fsf_req, u32 s_id,
+				   u32 d_id, u8 ls_code, void *buffer,
+				   int buflen)
 {
 {
 	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf;
 	struct zfcp_san_dbf_record *rec = &adapter->san_dbf_buf;
-	struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
 	unsigned long flags;
 	unsigned long flags;
-	int offset = 0;
 
 
 	spin_lock_irqsave(&adapter->san_dbf_lock, flags);
 	spin_lock_irqsave(&adapter->san_dbf_lock, flags);
-	do {
-		memset(rec, 0, sizeof(struct zfcp_san_dbf_record));
-		if (offset == 0) {
-			strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
-			rec->fsf_reqid = (unsigned long)fsf_req;
-			rec->fsf_seqno = fsf_req->seq_no;
-			rec->s_id = s_id;
-			rec->d_id = d_id;
-			rec->type.els.ls_code = ls_code;
-			buflen = min(buflen, ZFCP_DBF_ELS_MAX_PAYLOAD);
-			rec->type.els.payload_size = buflen;
-			memcpy(rec->type.els.payload,
-			       buffer, min(buflen, ZFCP_DBF_ELS_PAYLOAD));
-			offset += min(buflen, ZFCP_DBF_ELS_PAYLOAD);
-		} else {
-			strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
-			dump->total_size = buflen;
-			dump->offset = offset;
-			dump->size = min(buflen - offset,
-					 (int)sizeof(struct zfcp_san_dbf_record)
-					 - (int)sizeof(struct zfcp_dbf_dump));
-			memcpy(dump->data, buffer + offset, dump->size);
-			offset += dump->size;
-		}
-		debug_event(adapter->san_dbf, level,
-			    rec, sizeof(struct zfcp_san_dbf_record));
-	} while (offset < buflen);
+	memset(rec, 0, sizeof(*rec));
+	strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
+	rec->fsf_reqid = (unsigned long)fsf_req;
+	rec->fsf_seqno = fsf_req->seq_no;
+	rec->s_id = s_id;
+	rec->d_id = d_id;
+	rec->u.els.ls_code = ls_code;
+	debug_event(adapter->san_dbf, level, rec, sizeof(*rec));
+	zfcp_dbf_hexdump(adapter->san_dbf, rec, sizeof(*rec), level,
+			 buffer, min(buflen, ZFCP_DBF_ELS_MAX_PAYLOAD));
 	spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
 	spin_unlock_irqrestore(&adapter->san_dbf_lock, flags);
 }
 }
 
 
+/**
+ * zfcp_san_dbf_event_els_request - trace event for issued ELS
+ * @fsf_req: request containing issued ELS
+ */
 void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req)
 void zfcp_san_dbf_event_els_request(struct zfcp_fsf_req *fsf_req)
 {
 {
 	struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
 	struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
 
 
-	_zfcp_san_dbf_event_common_els("oels", 2, fsf_req,
-				       fc_host_port_id(els->adapter->scsi_host),
-				       els->d_id,
-				       *(u8 *) zfcp_sg_to_address(els->req),
-				       zfcp_sg_to_address(els->req),
-				       els->req->length);
+	zfcp_san_dbf_event_els("oels", 2, fsf_req,
+			       fc_host_port_id(els->adapter->scsi_host),
+			       els->d_id, *(u8 *) zfcp_sg_to_address(els->req),
+			       zfcp_sg_to_address(els->req), els->req->length);
 }
 }
 
 
+/**
+ * zfcp_san_dbf_event_els_response - trace event for completed ELS
+ * @fsf_req: request containing ELS response
+ */
 void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req)
 void zfcp_san_dbf_event_els_response(struct zfcp_fsf_req *fsf_req)
 {
 {
 	struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
 	struct zfcp_send_els *els = (struct zfcp_send_els *)fsf_req->data;
 
 
-	_zfcp_san_dbf_event_common_els("rels", 2, fsf_req, els->d_id,
-				       fc_host_port_id(els->adapter->scsi_host),
-				       *(u8 *) zfcp_sg_to_address(els->req),
-				       zfcp_sg_to_address(els->resp),
-				       els->resp->length);
+	zfcp_san_dbf_event_els("rels", 2, fsf_req, els->d_id,
+			       fc_host_port_id(els->adapter->scsi_host),
+			       *(u8 *)zfcp_sg_to_address(els->req),
+			       zfcp_sg_to_address(els->resp),
+			       els->resp->length);
 }
 }
 
 
+/**
+ * zfcp_san_dbf_event_incoming_els - trace event for incomig ELS
+ * @fsf_req: request containing unsolicited status buffer with incoming ELS
+ */
 void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req)
 void zfcp_san_dbf_event_incoming_els(struct zfcp_fsf_req *fsf_req)
 {
 {
 	struct zfcp_adapter *adapter = fsf_req->adapter;
 	struct zfcp_adapter *adapter = fsf_req->adapter;
-	struct fsf_status_read_buffer *status_buffer =
-	    (struct fsf_status_read_buffer *)fsf_req->data;
-	int length = (int)status_buffer->length -
-	    (int)((void *)&status_buffer->payload - (void *)status_buffer);
-
-	_zfcp_san_dbf_event_common_els("iels", 1, fsf_req, status_buffer->d_id,
-				       fc_host_port_id(adapter->scsi_host),
-				       *(u8 *) status_buffer->payload,
-				       (void *)status_buffer->payload, length);
+	struct fsf_status_read_buffer *buf =
+			(struct fsf_status_read_buffer *)fsf_req->data;
+	int length = (int)buf->length -
+		     (int)((void *)&buf->payload - (void *)buf);
+
+	zfcp_san_dbf_event_els("iels", 1, fsf_req, buf->d_id,
+			       fc_host_port_id(adapter->scsi_host),
+			       *(u8 *)buf->payload, (void *)buf->payload,
+			       length);
 }
 }
 
 
-static int
-zfcp_san_dbf_view_format(debug_info_t * id, struct debug_view *view,
-			 char *out_buf, const char *in_buf)
+static int zfcp_san_dbf_view_format(debug_info_t *id, struct debug_view *view,
+				    char *out_buf, const char *in_buf)
 {
 {
-	struct zfcp_san_dbf_record *rec = (struct zfcp_san_dbf_record *)in_buf;
+	struct zfcp_san_dbf_record *r = (struct zfcp_san_dbf_record *)in_buf;
 	char *buffer = NULL;
 	char *buffer = NULL;
 	int buflen = 0, total = 0;
 	int buflen = 0, total = 0;
-	int len = 0;
+	char *p = out_buf;
 
 
-	if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
+	if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
 		return 0;
 		return 0;
 
 
-	len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag);
-	len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx",
-			     rec->fsf_reqid);
-	len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x",
-			     rec->fsf_seqno);
-	len += zfcp_dbf_view(out_buf + len, "s_id", "0x%06x", rec->s_id);
-	len += zfcp_dbf_view(out_buf + len, "d_id", "0x%06x", rec->d_id);
-
-	if (strncmp(rec->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {
-		len += zfcp_dbf_view(out_buf + len, "cmd_req_code", "0x%04x",
-				     rec->type.ct.type.request.cmd_req_code);
-		len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x",
-				     rec->type.ct.type.request.revision);
-		len += zfcp_dbf_view(out_buf + len, "gs_type", "0x%02x",
-				     rec->type.ct.type.request.gs_type);
-		len += zfcp_dbf_view(out_buf + len, "gs_subtype", "0x%02x",
-				     rec->type.ct.type.request.gs_subtype);
-		len += zfcp_dbf_view(out_buf + len, "options", "0x%02x",
-				     rec->type.ct.type.request.options);
-		len += zfcp_dbf_view(out_buf + len, "max_res_size", "0x%04x",
-				     rec->type.ct.type.request.max_res_size);
-		total = rec->type.ct.payload_size;
-		buffer = rec->type.ct.payload;
+	zfcp_dbf_tag(&p, "tag", r->tag);
+	zfcp_dbf_out(&p, "fsf_reqid", "0x%0Lx", r->fsf_reqid);
+	zfcp_dbf_out(&p, "fsf_seqno", "0x%08x", r->fsf_seqno);
+	zfcp_dbf_out(&p, "s_id", "0x%06x", r->s_id);
+	zfcp_dbf_out(&p, "d_id", "0x%06x", r->d_id);
+
+	if (strncmp(r->tag, "octc", ZFCP_DBF_TAG_SIZE) == 0) {
+		struct zfcp_san_dbf_record_ct_request *ct = &r->u.ct_req;
+		zfcp_dbf_out(&p, "cmd_req_code", "0x%04x", ct->cmd_req_code);
+		zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision);
+		zfcp_dbf_out(&p, "gs_type", "0x%02x", ct->gs_type);
+		zfcp_dbf_out(&p, "gs_subtype", "0x%02x", ct->gs_subtype);
+		zfcp_dbf_out(&p, "options", "0x%02x", ct->options);
+		zfcp_dbf_out(&p, "max_res_size", "0x%04x", ct->max_res_size);
+		total = ct->len;
+		buffer = ct->payload;
 		buflen = min(total, ZFCP_DBF_CT_PAYLOAD);
 		buflen = min(total, ZFCP_DBF_CT_PAYLOAD);
-	} else if (strncmp(rec->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) {
-		len += zfcp_dbf_view(out_buf + len, "cmd_rsp_code", "0x%04x",
-				     rec->type.ct.type.response.cmd_rsp_code);
-		len += zfcp_dbf_view(out_buf + len, "revision", "0x%02x",
-				     rec->type.ct.type.response.revision);
-		len += zfcp_dbf_view(out_buf + len, "reason_code", "0x%02x",
-				     rec->type.ct.type.response.reason_code);
-		len +=
-		    zfcp_dbf_view(out_buf + len, "reason_code_expl", "0x%02x",
-				  rec->type.ct.type.response.reason_code_expl);
-		len +=
-		    zfcp_dbf_view(out_buf + len, "vendor_unique", "0x%02x",
-				  rec->type.ct.type.response.vendor_unique);
-		total = rec->type.ct.payload_size;
-		buffer = rec->type.ct.payload;
+	} else if (strncmp(r->tag, "rctc", ZFCP_DBF_TAG_SIZE) == 0) {
+		struct zfcp_san_dbf_record_ct_response *ct = &r->u.ct_resp;
+		zfcp_dbf_out(&p, "cmd_rsp_code", "0x%04x", ct->cmd_rsp_code);
+		zfcp_dbf_out(&p, "revision", "0x%02x", ct->revision);
+		zfcp_dbf_out(&p, "reason_code", "0x%02x", ct->reason_code);
+		zfcp_dbf_out(&p, "reason_code_expl", "0x%02x", ct->expl);
+		zfcp_dbf_out(&p, "vendor_unique", "0x%02x", ct->vendor_unique);
+		total = ct->len;
+		buffer = ct->payload;
 		buflen = min(total, ZFCP_DBF_CT_PAYLOAD);
 		buflen = min(total, ZFCP_DBF_CT_PAYLOAD);
-	} else if (strncmp(rec->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 ||
-		   strncmp(rec->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 ||
-		   strncmp(rec->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {
-		len += zfcp_dbf_view(out_buf + len, "ls_code", "0x%02x",
-				     rec->type.els.ls_code);
-		total = rec->type.els.payload_size;
-		buffer = rec->type.els.payload;
+	} else if (strncmp(r->tag, "oels", ZFCP_DBF_TAG_SIZE) == 0 ||
+		   strncmp(r->tag, "rels", ZFCP_DBF_TAG_SIZE) == 0 ||
+		   strncmp(r->tag, "iels", ZFCP_DBF_TAG_SIZE) == 0) {
+		struct zfcp_san_dbf_record_els *els = &r->u.els;
+		zfcp_dbf_out(&p, "ls_code", "0x%02x", els->ls_code);
+		total = els->len;
+		buffer = els->payload;
 		buflen = min(total, ZFCP_DBF_ELS_PAYLOAD);
 		buflen = min(total, ZFCP_DBF_ELS_PAYLOAD);
 	}
 	}
 
 
-	len += zfcp_dbf_view_dump(out_buf + len, "payload",
-				  buffer, buflen, 0, total);
-
+	zfcp_dbf_outd(&p, "payload", buffer, buflen, 0, total);
 	if (buflen == total)
 	if (buflen == total)
-		len += sprintf(out_buf + len, "\n");
+		p += sprintf(p, "\n");
 
 
-	return len;
+	return p - out_buf;
 }
 }
 
 
 static struct debug_view zfcp_san_dbf_view = {
 static struct debug_view zfcp_san_dbf_view = {
@@ -696,12 +1028,11 @@ static struct debug_view zfcp_san_dbf_view = {
 	NULL
 	NULL
 };
 };
 
 
-static void
-_zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
-			    struct zfcp_adapter *adapter,
-			    struct scsi_cmnd *scsi_cmnd,
-			    struct zfcp_fsf_req *fsf_req,
-			    unsigned long old_req_id)
+static void zfcp_scsi_dbf_event(const char *tag, const char *tag2, int level,
+				struct zfcp_adapter *adapter,
+				struct scsi_cmnd *scsi_cmnd,
+				struct zfcp_fsf_req *fsf_req,
+				unsigned long old_req_id)
 {
 {
 	struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf;
 	struct zfcp_scsi_dbf_record *rec = &adapter->scsi_dbf_buf;
 	struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
 	struct zfcp_dbf_dump *dump = (struct zfcp_dbf_dump *)rec;
@@ -712,7 +1043,7 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
 
 
 	spin_lock_irqsave(&adapter->scsi_dbf_lock, flags);
 	spin_lock_irqsave(&adapter->scsi_dbf_lock, flags);
 	do {
 	do {
-		memset(rec, 0, sizeof(struct zfcp_scsi_dbf_record));
+		memset(rec, 0, sizeof(*rec));
 		if (offset == 0) {
 		if (offset == 0) {
 			strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
 			strncpy(rec->tag, tag, ZFCP_DBF_TAG_SIZE);
 			strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE);
 			strncpy(rec->tag2, tag2, ZFCP_DBF_TAG_SIZE);
@@ -738,20 +1069,16 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
 				fcp_sns_info =
 				fcp_sns_info =
 				    zfcp_get_fcp_sns_info_ptr(fcp_rsp);
 				    zfcp_get_fcp_sns_info_ptr(fcp_rsp);
 
 
-				rec->type.fcp.rsp_validity =
-				    fcp_rsp->validity.value;
-				rec->type.fcp.rsp_scsi_status =
-				    fcp_rsp->scsi_status;
-				rec->type.fcp.rsp_resid = fcp_rsp->fcp_resid;
+				rec->rsp_validity = fcp_rsp->validity.value;
+				rec->rsp_scsi_status = fcp_rsp->scsi_status;
+				rec->rsp_resid = fcp_rsp->fcp_resid;
 				if (fcp_rsp->validity.bits.fcp_rsp_len_valid)
 				if (fcp_rsp->validity.bits.fcp_rsp_len_valid)
-					rec->type.fcp.rsp_code =
-					    *(fcp_rsp_info + 3);
+					rec->rsp_code = *(fcp_rsp_info + 3);
 				if (fcp_rsp->validity.bits.fcp_sns_len_valid) {
 				if (fcp_rsp->validity.bits.fcp_sns_len_valid) {
 					buflen = min((int)fcp_rsp->fcp_sns_len,
 					buflen = min((int)fcp_rsp->fcp_sns_len,
 						     ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO);
 						     ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO);
-					rec->type.fcp.sns_info_len = buflen;
-					memcpy(rec->type.fcp.sns_info,
-					       fcp_sns_info,
+					rec->sns_info_len = buflen;
+					memcpy(rec->sns_info, fcp_sns_info,
 					       min(buflen,
 					       min(buflen,
 						   ZFCP_DBF_SCSI_FCP_SNS_INFO));
 						   ZFCP_DBF_SCSI_FCP_SNS_INFO));
 					offset += min(buflen,
 					offset += min(buflen,
@@ -762,7 +1089,7 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
 				rec->fsf_seqno = fsf_req->seq_no;
 				rec->fsf_seqno = fsf_req->seq_no;
 				rec->fsf_issued = fsf_req->issued;
 				rec->fsf_issued = fsf_req->issued;
 			}
 			}
-			rec->type.old_fsf_reqid = old_req_id;
+			rec->old_fsf_reqid = old_req_id;
 		} else {
 		} else {
 			strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
 			strncpy(dump->tag, "dump", ZFCP_DBF_TAG_SIZE);
 			dump->total_size = buflen;
 			dump->total_size = buflen;
@@ -774,108 +1101,101 @@ _zfcp_scsi_dbf_event_common(const char *tag, const char *tag2, int level,
 			memcpy(dump->data, fcp_sns_info + offset, dump->size);
 			memcpy(dump->data, fcp_sns_info + offset, dump->size);
 			offset += dump->size;
 			offset += dump->size;
 		}
 		}
-		debug_event(adapter->scsi_dbf, level,
-			    rec, sizeof(struct zfcp_scsi_dbf_record));
+		debug_event(adapter->scsi_dbf, level, rec, sizeof(*rec));
 	} while (offset < buflen);
 	} while (offset < buflen);
 	spin_unlock_irqrestore(&adapter->scsi_dbf_lock, flags);
 	spin_unlock_irqrestore(&adapter->scsi_dbf_lock, flags);
 }
 }
 
 
-void
-zfcp_scsi_dbf_event_result(const char *tag, int level,
-			   struct zfcp_adapter *adapter,
-			   struct scsi_cmnd *scsi_cmnd,
-			   struct zfcp_fsf_req *fsf_req)
+/**
+ * zfcp_scsi_dbf_event_result - trace event for SCSI command completion
+ * @tag: tag indicating success or failure of SCSI command
+ * @level: trace level applicable for this event
+ * @adapter: adapter that has been used to issue the SCSI command
+ * @scsi_cmnd: SCSI command pointer
+ * @fsf_req: request used to issue SCSI command (might be NULL)
+ */
+void zfcp_scsi_dbf_event_result(const char *tag, int level,
+				struct zfcp_adapter *adapter,
+				struct scsi_cmnd *scsi_cmnd,
+				struct zfcp_fsf_req *fsf_req)
 {
 {
-	_zfcp_scsi_dbf_event_common("rslt", tag, level,
-			adapter, scsi_cmnd, fsf_req, 0);
+	zfcp_scsi_dbf_event("rslt", tag, level, adapter, scsi_cmnd, fsf_req, 0);
 }
 }
 
 
-void
-zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter,
-			  struct scsi_cmnd *scsi_cmnd,
-			  struct zfcp_fsf_req *new_fsf_req,
-			  unsigned long old_req_id)
+/**
+ * zfcp_scsi_dbf_event_abort - trace event for SCSI command abort
+ * @tag: tag indicating success or failure of abort operation
+ * @adapter: adapter thas has been used to issue SCSI command to be aborted
+ * @scsi_cmnd: SCSI command to be aborted
+ * @new_fsf_req: request containing abort (might be NULL)
+ * @old_req_id: identifier of request containg SCSI command to be aborted
+ */
+void zfcp_scsi_dbf_event_abort(const char *tag, struct zfcp_adapter *adapter,
+			       struct scsi_cmnd *scsi_cmnd,
+			       struct zfcp_fsf_req *new_fsf_req,
+			       unsigned long old_req_id)
 {
 {
-	_zfcp_scsi_dbf_event_common("abrt", tag, 1,
-			adapter, scsi_cmnd, new_fsf_req, old_req_id);
+	zfcp_scsi_dbf_event("abrt", tag, 1, adapter, scsi_cmnd, new_fsf_req,
+			    old_req_id);
 }
 }
 
 
-void
-zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag, struct zfcp_unit *unit,
-			     struct scsi_cmnd *scsi_cmnd)
+/**
+ * zfcp_scsi_dbf_event_devreset - trace event for Logical Unit or Target Reset
+ * @tag: tag indicating success or failure of reset operation
+ * @flag: indicates type of reset (Target Reset, Logical Unit Reset)
+ * @unit: unit that needs reset
+ * @scsi_cmnd: SCSI command which caused this error recovery
+ */
+void zfcp_scsi_dbf_event_devreset(const char *tag, u8 flag,
+				  struct zfcp_unit *unit,
+				  struct scsi_cmnd *scsi_cmnd)
 {
 {
-	struct zfcp_adapter *adapter = unit->port->adapter;
-
-	_zfcp_scsi_dbf_event_common(flag == FCP_TARGET_RESET ? "trst" : "lrst",
-			tag, 1, adapter, scsi_cmnd, NULL, 0);
+	zfcp_scsi_dbf_event(flag == FCP_TARGET_RESET ? "trst" : "lrst", tag, 1,
+			    unit->port->adapter, scsi_cmnd, NULL, 0);
 }
 }
 
 
-static int
-zfcp_scsi_dbf_view_format(debug_info_t * id, struct debug_view *view,
-			  char *out_buf, const char *in_buf)
+static int zfcp_scsi_dbf_view_format(debug_info_t *id, struct debug_view *view,
+				     char *out_buf, const char *in_buf)
 {
 {
-	struct zfcp_scsi_dbf_record *rec =
-	    (struct zfcp_scsi_dbf_record *)in_buf;
-	int len = 0;
+	struct zfcp_scsi_dbf_record *r = (struct zfcp_scsi_dbf_record *)in_buf;
+	struct timespec t;
+	char *p = out_buf;
 
 
-	if (strncmp(rec->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
+	if (strncmp(r->tag, "dump", ZFCP_DBF_TAG_SIZE) == 0)
 		return 0;
 		return 0;
 
 
-	len += zfcp_dbf_tag(out_buf + len, "tag", rec->tag);
-	len += zfcp_dbf_tag(out_buf + len, "tag2", rec->tag2);
-	len += zfcp_dbf_view(out_buf + len, "scsi_id", "0x%08x", rec->scsi_id);
-	len += zfcp_dbf_view(out_buf + len, "scsi_lun", "0x%08x",
-			     rec->scsi_lun);
-	len += zfcp_dbf_view(out_buf + len, "scsi_result", "0x%08x",
-			     rec->scsi_result);
-	len += zfcp_dbf_view(out_buf + len, "scsi_cmnd", "0x%0Lx",
-			     rec->scsi_cmnd);
-	len += zfcp_dbf_view(out_buf + len, "scsi_serial", "0x%016Lx",
-			     rec->scsi_serial);
-	len += zfcp_dbf_view_dump(out_buf + len, "scsi_opcode",
-				  rec->scsi_opcode,
-				  ZFCP_DBF_SCSI_OPCODE,
-				  0, ZFCP_DBF_SCSI_OPCODE);
-	len += zfcp_dbf_view(out_buf + len, "scsi_retries", "0x%02x",
-			     rec->scsi_retries);
-	len += zfcp_dbf_view(out_buf + len, "scsi_allowed", "0x%02x",
-			     rec->scsi_allowed);
-	if (strncmp(rec->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0) {
-		len += zfcp_dbf_view(out_buf + len, "old_fsf_reqid", "0x%0Lx",
-				     rec->type.old_fsf_reqid);
-	}
-	len += zfcp_dbf_view(out_buf + len, "fsf_reqid", "0x%0Lx",
-			     rec->fsf_reqid);
-	len += zfcp_dbf_view(out_buf + len, "fsf_seqno", "0x%08x",
-			     rec->fsf_seqno);
-	len += zfcp_dbf_stck(out_buf + len, "fsf_issued", rec->fsf_issued);
-	if (strncmp(rec->tag, "rslt", ZFCP_DBF_TAG_SIZE) == 0) {
-		len +=
-		    zfcp_dbf_view(out_buf + len, "fcp_rsp_validity", "0x%02x",
-				  rec->type.fcp.rsp_validity);
-		len +=
-		    zfcp_dbf_view(out_buf + len, "fcp_rsp_scsi_status",
-				  "0x%02x", rec->type.fcp.rsp_scsi_status);
-		len +=
-		    zfcp_dbf_view(out_buf + len, "fcp_rsp_resid", "0x%08x",
-				  rec->type.fcp.rsp_resid);
-		len +=
-		    zfcp_dbf_view(out_buf + len, "fcp_rsp_code", "0x%08x",
-				  rec->type.fcp.rsp_code);
-		len +=
-		    zfcp_dbf_view(out_buf + len, "fcp_sns_info_len", "0x%08x",
-				  rec->type.fcp.sns_info_len);
-		len +=
-		    zfcp_dbf_view_dump(out_buf + len, "fcp_sns_info",
-				       rec->type.fcp.sns_info,
-				       min((int)rec->type.fcp.sns_info_len,
-					   ZFCP_DBF_SCSI_FCP_SNS_INFO), 0,
-				       rec->type.fcp.sns_info_len);
+	zfcp_dbf_tag(&p, "tag", r->tag);
+	zfcp_dbf_tag(&p, "tag2", r->tag2);
+	zfcp_dbf_out(&p, "scsi_id", "0x%08x", r->scsi_id);
+	zfcp_dbf_out(&p, "scsi_lun", "0x%08x", r->scsi_lun);
+	zfcp_dbf_out(&p, "scsi_result", "0x%08x", r->scsi_result);
+	zfcp_dbf_out(&p, "scsi_cmnd", "0x%0Lx", r->scsi_cmnd);
+	zfcp_dbf_out(&p, "scsi_serial", "0x%016Lx", r->scsi_serial);
+	zfcp_dbf_outd(&p, "scsi_opcode", r->scsi_opcode, ZFCP_DBF_SCSI_OPCODE,
+		      0, ZFCP_DBF_SCSI_OPCODE);
+	zfcp_dbf_out(&p, "scsi_retries", "0x%02x", r->scsi_retries);
+	zfcp_dbf_out(&p, "scsi_allowed", "0x%02x", r->scsi_allowed);
+	if (strncmp(r->tag, "abrt", ZFCP_DBF_TAG_SIZE) == 0)
+		zfcp_dbf_out(&p, "old_fsf_reqid", "0x%0Lx", r->old_fsf_reqid);
+	zfcp_dbf_out(&p, "fsf_reqid", "0x%0Lx", r->fsf_reqid);
+	zfcp_dbf_out(&p, "fsf_seqno", "0x%08x", r->fsf_seqno);
+	zfcp_dbf_timestamp(r->fsf_issued, &t);
+	zfcp_dbf_out(&p, "fsf_issued", "%011lu:%06lu", t.tv_sec, t.tv_nsec);
+
+	if (strncmp(r->tag, "rslt", ZFCP_DBF_TAG_SIZE) == 0) {
+		zfcp_dbf_out(&p, "fcp_rsp_validity", "0x%02x", r->rsp_validity);
+		zfcp_dbf_out(&p, "fcp_rsp_scsi_status", "0x%02x",
+			     r->rsp_scsi_status);
+		zfcp_dbf_out(&p, "fcp_rsp_resid", "0x%08x", r->rsp_resid);
+		zfcp_dbf_out(&p, "fcp_rsp_code", "0x%08x", r->rsp_code);
+		zfcp_dbf_out(&p, "fcp_sns_info_len", "0x%08x", r->sns_info_len);
+		zfcp_dbf_outd(&p, "fcp_sns_info", r->sns_info,
+			      min((int)r->sns_info_len,
+			      ZFCP_DBF_SCSI_FCP_SNS_INFO), 0,
+			      r->sns_info_len);
 	}
 	}
-
-	len += sprintf(out_buf + len, "\n");
-
-	return len;
+	p += sprintf(p, "\n");
+	return p - out_buf;
 }
 }
 
 
 static struct debug_view zfcp_scsi_dbf_view = {
 static struct debug_view zfcp_scsi_dbf_view = {
@@ -897,13 +1217,14 @@ int zfcp_adapter_debug_register(struct zfcp_adapter *adapter)
 	char dbf_name[DEBUG_MAX_NAME_LEN];
 	char dbf_name[DEBUG_MAX_NAME_LEN];
 
 
 	/* debug feature area which records recovery activity */
 	/* debug feature area which records recovery activity */
-	sprintf(dbf_name, "zfcp_%s_erp", zfcp_get_busid_by_adapter(adapter));
-	adapter->erp_dbf = debug_register(dbf_name, dbfsize, 2,
-					  sizeof(struct zfcp_erp_dbf_record));
-	if (!adapter->erp_dbf)
+	sprintf(dbf_name, "zfcp_%s_rec", zfcp_get_busid_by_adapter(adapter));
+	adapter->rec_dbf = debug_register(dbf_name, dbfsize, 1,
+					  sizeof(struct zfcp_rec_dbf_record));
+	if (!adapter->rec_dbf)
 		goto failed;
 		goto failed;
-	debug_register_view(adapter->erp_dbf, &debug_hex_ascii_view);
-	debug_set_level(adapter->erp_dbf, 3);
+	debug_register_view(adapter->rec_dbf, &debug_hex_ascii_view);
+	debug_register_view(adapter->rec_dbf, &zfcp_rec_dbf_view);
+	debug_set_level(adapter->rec_dbf, 3);
 
 
 	/* debug feature area which records HBA (FSF and QDIO) conditions */
 	/* debug feature area which records HBA (FSF and QDIO) conditions */
 	sprintf(dbf_name, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter));
 	sprintf(dbf_name, "zfcp_%s_hba", zfcp_get_busid_by_adapter(adapter));
@@ -952,11 +1273,11 @@ void zfcp_adapter_debug_unregister(struct zfcp_adapter *adapter)
 	debug_unregister(adapter->scsi_dbf);
 	debug_unregister(adapter->scsi_dbf);
 	debug_unregister(adapter->san_dbf);
 	debug_unregister(adapter->san_dbf);
 	debug_unregister(adapter->hba_dbf);
 	debug_unregister(adapter->hba_dbf);
-	debug_unregister(adapter->erp_dbf);
+	debug_unregister(adapter->rec_dbf);
 	adapter->scsi_dbf = NULL;
 	adapter->scsi_dbf = NULL;
 	adapter->san_dbf = NULL;
 	adapter->san_dbf = NULL;
 	adapter->hba_dbf = NULL;
 	adapter->hba_dbf = NULL;
-	adapter->erp_dbf = NULL;
+	adapter->rec_dbf = NULL;
 }
 }
 
 
 #undef ZFCP_LOG_AREA
 #undef ZFCP_LOG_AREA

+ 228 - 0
drivers/s390/scsi/zfcp_dbf.h

@@ -0,0 +1,228 @@
+/*
+ * This file is part of the zfcp device driver for
+ * FCP adapters for IBM System z9 and zSeries.
+ *
+ * Copyright IBM Corp. 2008, 2008
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#ifndef ZFCP_DBF_H
+#define ZFCP_DBF_H
+
+#include "zfcp_fsf.h"
+
+#define ZFCP_DBF_TAG_SIZE      4
+
+struct zfcp_dbf_dump {
+	u8 tag[ZFCP_DBF_TAG_SIZE];
+	u32 total_size;		/* size of total dump data */
+	u32 offset;		/* how much data has being already dumped */
+	u32 size;		/* how much data comes with this record */
+	u8 data[];		/* dump data */
+} __attribute__ ((packed));
+
+struct zfcp_rec_dbf_record_thread {
+	u32 total;
+	u32 ready;
+	u32 running;
+} __attribute__ ((packed));
+
+struct zfcp_rec_dbf_record_target {
+	u64 ref;
+	u32 status;
+	u32 d_id;
+	u64 wwpn;
+	u64 fcp_lun;
+	u32 erp_count;
+} __attribute__ ((packed));
+
+struct zfcp_rec_dbf_record_trigger {
+	u8 want;
+	u8 need;
+	u32 as;
+	u32 ps;
+	u32 us;
+	u64 ref;
+	u64 action;
+	u64 wwpn;
+	u64 fcp_lun;
+} __attribute__ ((packed));
+
+struct zfcp_rec_dbf_record_action {
+	u32 status;
+	u32 step;
+	u64 action;
+	u64 fsf_req;
+} __attribute__ ((packed));
+
+struct zfcp_rec_dbf_record {
+	u8 id;
+	u8 id2;
+	union {
+		struct zfcp_rec_dbf_record_action action;
+		struct zfcp_rec_dbf_record_thread thread;
+		struct zfcp_rec_dbf_record_target target;
+		struct zfcp_rec_dbf_record_trigger trigger;
+	} u;
+} __attribute__ ((packed));
+
+enum {
+	ZFCP_REC_DBF_ID_ACTION,
+	ZFCP_REC_DBF_ID_THREAD,
+	ZFCP_REC_DBF_ID_TARGET,
+	ZFCP_REC_DBF_ID_TRIGGER,
+};
+
+struct zfcp_hba_dbf_record_response {
+	u32 fsf_command;
+	u64 fsf_reqid;
+	u32 fsf_seqno;
+	u64 fsf_issued;
+	u32 fsf_prot_status;
+	u32 fsf_status;
+	u8 fsf_prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];
+	u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
+	u32 fsf_req_status;
+	u8 sbal_first;
+	u8 sbal_curr;
+	u8 sbal_last;
+	u8 pool;
+	u64 erp_action;
+	union {
+		struct {
+			u64 cmnd;
+			u64 serial;
+		} fcp;
+		struct {
+			u64 wwpn;
+			u32 d_id;
+			u32 port_handle;
+		} port;
+		struct {
+			u64 wwpn;
+			u64 fcp_lun;
+			u32 port_handle;
+			u32 lun_handle;
+		} unit;
+		struct {
+			u32 d_id;
+			u8 ls_code;
+		} els;
+	} u;
+} __attribute__ ((packed));
+
+struct zfcp_hba_dbf_record_status {
+	u8 failed;
+	u32 status_type;
+	u32 status_subtype;
+	struct fsf_queue_designator
+	 queue_designator;
+	u32 payload_size;
+#define ZFCP_DBF_UNSOL_PAYLOAD				80
+#define ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL		32
+#define ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD	56
+#define ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT	2 * sizeof(u32)
+	u8 payload[ZFCP_DBF_UNSOL_PAYLOAD];
+} __attribute__ ((packed));
+
+struct zfcp_hba_dbf_record_qdio {
+	u32 status;
+	u32 qdio_error;
+	u32 siga_error;
+	u8 sbal_index;
+	u8 sbal_count;
+} __attribute__ ((packed));
+
+struct zfcp_hba_dbf_record {
+	u8 tag[ZFCP_DBF_TAG_SIZE];
+	u8 tag2[ZFCP_DBF_TAG_SIZE];
+	union {
+		struct zfcp_hba_dbf_record_response response;
+		struct zfcp_hba_dbf_record_status status;
+		struct zfcp_hba_dbf_record_qdio qdio;
+	} u;
+} __attribute__ ((packed));
+
+struct zfcp_san_dbf_record_ct_request {
+	u16 cmd_req_code;
+	u8 revision;
+	u8 gs_type;
+	u8 gs_subtype;
+	u8 options;
+	u16 max_res_size;
+	u32 len;
+#define ZFCP_DBF_CT_PAYLOAD	24
+	u8 payload[ZFCP_DBF_CT_PAYLOAD];
+} __attribute__ ((packed));
+
+struct zfcp_san_dbf_record_ct_response {
+	u16 cmd_rsp_code;
+	u8 revision;
+	u8 reason_code;
+	u8 expl;
+	u8 vendor_unique;
+	u32 len;
+	u8 payload[ZFCP_DBF_CT_PAYLOAD];
+} __attribute__ ((packed));
+
+struct zfcp_san_dbf_record_els {
+	u8 ls_code;
+	u32 len;
+#define ZFCP_DBF_ELS_PAYLOAD	32
+#define ZFCP_DBF_ELS_MAX_PAYLOAD 1024
+	u8 payload[ZFCP_DBF_ELS_PAYLOAD];
+} __attribute__ ((packed));
+
+struct zfcp_san_dbf_record {
+	u8 tag[ZFCP_DBF_TAG_SIZE];
+	u64 fsf_reqid;
+	u32 fsf_seqno;
+	u32 s_id;
+	u32 d_id;
+	union {
+		struct zfcp_san_dbf_record_ct_request ct_req;
+		struct zfcp_san_dbf_record_ct_response ct_resp;
+		struct zfcp_san_dbf_record_els els;
+	} u;
+} __attribute__ ((packed));
+
+struct zfcp_scsi_dbf_record {
+	u8 tag[ZFCP_DBF_TAG_SIZE];
+	u8 tag2[ZFCP_DBF_TAG_SIZE];
+	u32 scsi_id;
+	u32 scsi_lun;
+	u32 scsi_result;
+	u64 scsi_cmnd;
+	u64 scsi_serial;
+#define ZFCP_DBF_SCSI_OPCODE	16
+	u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE];
+	u8 scsi_retries;
+	u8 scsi_allowed;
+	u64 fsf_reqid;
+	u32 fsf_seqno;
+	u64 fsf_issued;
+	u64 old_fsf_reqid;
+	u8 rsp_validity;
+	u8 rsp_scsi_status;
+	u32 rsp_resid;
+	u8 rsp_code;
+#define ZFCP_DBF_SCSI_FCP_SNS_INFO	16
+#define ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO	256
+	u32 sns_info_len;
+	u8 sns_info[ZFCP_DBF_SCSI_FCP_SNS_INFO];
+} __attribute__ ((packed));
+
+#endif /* ZFCP_DBF_H */

+ 4 - 165
drivers/s390/scsi/zfcp_def.h

@@ -47,6 +47,7 @@
 #include <asm/qdio.h>
 #include <asm/qdio.h>
 #include <asm/debug.h>
 #include <asm/debug.h>
 #include <asm/ebcdic.h>
 #include <asm/ebcdic.h>
+#include "zfcp_dbf.h"
 #include "zfcp_fsf.h"
 #include "zfcp_fsf.h"
 
 
 
 
@@ -261,167 +262,6 @@ struct fcp_logo {
         wwn_t nport_wwpn;
         wwn_t nport_wwpn;
 } __attribute__((packed));
 } __attribute__((packed));
 
 
-/*
- * DBF stuff
- */
-#define ZFCP_DBF_TAG_SIZE      4
-
-struct zfcp_dbf_dump {
-	u8 tag[ZFCP_DBF_TAG_SIZE];
-	u32 total_size;		/* size of total dump data */
-	u32 offset;		/* how much data has being already dumped */
-	u32 size;		/* how much data comes with this record */
-	u8 data[];		/* dump data */
-} __attribute__ ((packed));
-
-/* FIXME: to be inflated when reworking the erp dbf */
-struct zfcp_erp_dbf_record {
-	u8 dummy[16];
-} __attribute__ ((packed));
-
-struct zfcp_hba_dbf_record_response {
-	u32 fsf_command;
-	u64 fsf_reqid;
-	u32 fsf_seqno;
-	u64 fsf_issued;
-	u32 fsf_prot_status;
-	u32 fsf_status;
-	u8 fsf_prot_status_qual[FSF_PROT_STATUS_QUAL_SIZE];
-	u8 fsf_status_qual[FSF_STATUS_QUALIFIER_SIZE];
-	u32 fsf_req_status;
-	u8 sbal_first;
-	u8 sbal_curr;
-	u8 sbal_last;
-	u8 pool;
-	u64 erp_action;
-	union {
-		struct {
-			u64 scsi_cmnd;
-			u64 scsi_serial;
-		} send_fcp;
-		struct {
-			u64 wwpn;
-			u32 d_id;
-			u32 port_handle;
-		} port;
-		struct {
-			u64 wwpn;
-			u64 fcp_lun;
-			u32 port_handle;
-			u32 lun_handle;
-		} unit;
-		struct {
-			u32 d_id;
-			u8 ls_code;
-		} send_els;
-	} data;
-} __attribute__ ((packed));
-
-struct zfcp_hba_dbf_record_status {
-	u8 failed;
-	u32 status_type;
-	u32 status_subtype;
-	struct fsf_queue_designator
-	 queue_designator;
-	u32 payload_size;
-#define ZFCP_DBF_UNSOL_PAYLOAD				80
-#define ZFCP_DBF_UNSOL_PAYLOAD_SENSE_DATA_AVAIL		32
-#define ZFCP_DBF_UNSOL_PAYLOAD_BIT_ERROR_THRESHOLD	56
-#define ZFCP_DBF_UNSOL_PAYLOAD_FEATURE_UPDATE_ALERT	2 * sizeof(u32)
-	u8 payload[ZFCP_DBF_UNSOL_PAYLOAD];
-} __attribute__ ((packed));
-
-struct zfcp_hba_dbf_record_qdio {
-	u32 status;
-	u32 qdio_error;
-	u32 siga_error;
-	u8 sbal_index;
-	u8 sbal_count;
-} __attribute__ ((packed));
-
-struct zfcp_hba_dbf_record {
-	u8 tag[ZFCP_DBF_TAG_SIZE];
-	u8 tag2[ZFCP_DBF_TAG_SIZE];
-	union {
-		struct zfcp_hba_dbf_record_response response;
-		struct zfcp_hba_dbf_record_status status;
-		struct zfcp_hba_dbf_record_qdio qdio;
-	} type;
-} __attribute__ ((packed));
-
-struct zfcp_san_dbf_record_ct {
-	union {
-		struct {
-			u16 cmd_req_code;
-			u8 revision;
-			u8 gs_type;
-			u8 gs_subtype;
-			u8 options;
-			u16 max_res_size;
-		} request;
-		struct {
-			u16 cmd_rsp_code;
-			u8 revision;
-			u8 reason_code;
-			u8 reason_code_expl;
-			u8 vendor_unique;
-		} response;
-	} type;
-	u32 payload_size;
-#define ZFCP_DBF_CT_PAYLOAD	24
-	u8 payload[ZFCP_DBF_CT_PAYLOAD];
-} __attribute__ ((packed));
-
-struct zfcp_san_dbf_record_els {
-	u8 ls_code;
-	u32 payload_size;
-#define ZFCP_DBF_ELS_PAYLOAD	32
-#define ZFCP_DBF_ELS_MAX_PAYLOAD 1024
-	u8 payload[ZFCP_DBF_ELS_PAYLOAD];
-} __attribute__ ((packed));
-
-struct zfcp_san_dbf_record {
-	u8 tag[ZFCP_DBF_TAG_SIZE];
-	u64 fsf_reqid;
-	u32 fsf_seqno;
-	u32 s_id;
-	u32 d_id;
-	union {
-		struct zfcp_san_dbf_record_ct ct;
-		struct zfcp_san_dbf_record_els els;
-	} type;
-} __attribute__ ((packed));
-
-struct zfcp_scsi_dbf_record {
-	u8 tag[ZFCP_DBF_TAG_SIZE];
-	u8 tag2[ZFCP_DBF_TAG_SIZE];
-	u32 scsi_id;
-	u32 scsi_lun;
-	u32 scsi_result;
-	u64 scsi_cmnd;
-	u64 scsi_serial;
-#define ZFCP_DBF_SCSI_OPCODE	16
-	u8 scsi_opcode[ZFCP_DBF_SCSI_OPCODE];
-	u8 scsi_retries;
-	u8 scsi_allowed;
-	u64 fsf_reqid;
-	u32 fsf_seqno;
-	u64 fsf_issued;
-	union {
-		u64 old_fsf_reqid;
-		struct {
-			u8 rsp_validity;
-			u8 rsp_scsi_status;
-			u32 rsp_resid;
-			u8 rsp_code;
-#define ZFCP_DBF_SCSI_FCP_SNS_INFO	16
-#define ZFCP_DBF_SCSI_MAX_FCP_SNS_INFO	256
-			u32 sns_info_len;
-			u8 sns_info[ZFCP_DBF_SCSI_FCP_SNS_INFO];
-		} fcp;
-	} type;
-} __attribute__ ((packed));
-
 /*
 /*
  * FC-FS stuff
  * FC-FS stuff
  */
  */
@@ -634,7 +474,6 @@ do { \
 		 ZFCP_STATUS_PORT_NO_SCSI_ID)
 		 ZFCP_STATUS_PORT_NO_SCSI_ID)
 
 
 /* logical unit status */
 /* logical unit status */
-#define ZFCP_STATUS_UNIT_NOTSUPPUNITRESET	0x00000001
 #define ZFCP_STATUS_UNIT_TEMPORARY		0x00000002
 #define ZFCP_STATUS_UNIT_TEMPORARY		0x00000002
 #define ZFCP_STATUS_UNIT_SHARED			0x00000004
 #define ZFCP_STATUS_UNIT_SHARED			0x00000004
 #define ZFCP_STATUS_UNIT_READONLY		0x00000008
 #define ZFCP_STATUS_UNIT_READONLY		0x00000008
@@ -917,15 +756,15 @@ struct zfcp_adapter {
 	u32			erp_low_mem_count; /* nr of erp actions waiting
 	u32			erp_low_mem_count; /* nr of erp actions waiting
 						      for memory */
 						      for memory */
 	struct zfcp_port	*nameserver_port;  /* adapter's nameserver */
 	struct zfcp_port	*nameserver_port;  /* adapter's nameserver */
-	debug_info_t		*erp_dbf;
+	debug_info_t		*rec_dbf;
 	debug_info_t		*hba_dbf;
 	debug_info_t		*hba_dbf;
 	debug_info_t		*san_dbf;          /* debug feature areas */
 	debug_info_t		*san_dbf;          /* debug feature areas */
 	debug_info_t		*scsi_dbf;
 	debug_info_t		*scsi_dbf;
-	spinlock_t		erp_dbf_lock;
+	spinlock_t		rec_dbf_lock;
 	spinlock_t		hba_dbf_lock;
 	spinlock_t		hba_dbf_lock;
 	spinlock_t		san_dbf_lock;
 	spinlock_t		san_dbf_lock;
 	spinlock_t		scsi_dbf_lock;
 	spinlock_t		scsi_dbf_lock;
-	struct zfcp_erp_dbf_record	erp_dbf_buf;
+	struct zfcp_rec_dbf_record	rec_dbf_buf;
 	struct zfcp_hba_dbf_record	hba_dbf_buf;
 	struct zfcp_hba_dbf_record	hba_dbf_buf;
 	struct zfcp_san_dbf_record	san_dbf_buf;
 	struct zfcp_san_dbf_record	san_dbf_buf;
 	struct zfcp_scsi_dbf_record	scsi_dbf_buf;
 	struct zfcp_scsi_dbf_record	scsi_dbf_buf;

+ 222 - 466
drivers/s390/scsi/zfcp_erp.c

@@ -26,13 +26,17 @@
 static int zfcp_erp_adisc(struct zfcp_port *);
 static int zfcp_erp_adisc(struct zfcp_port *);
 static void zfcp_erp_adisc_handler(unsigned long);
 static void zfcp_erp_adisc_handler(unsigned long);
 
 
-static int zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *, int);
-static int zfcp_erp_port_forced_reopen_internal(struct zfcp_port *, int);
-static int zfcp_erp_port_reopen_internal(struct zfcp_port *, int);
-static int zfcp_erp_unit_reopen_internal(struct zfcp_unit *, int);
-
-static int zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *, int);
-static int zfcp_erp_unit_reopen_all_internal(struct zfcp_port *, int);
+static int zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *, int, u8,
+					    void *);
+static int zfcp_erp_port_forced_reopen_internal(struct zfcp_port *, int, u8,
+						void *);
+static int zfcp_erp_port_reopen_internal(struct zfcp_port *, int, u8, void *);
+static int zfcp_erp_unit_reopen_internal(struct zfcp_unit *, int, u8, void *);
+
+static int zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *, int, u8,
+					     void *);
+static int zfcp_erp_unit_reopen_all_internal(struct zfcp_port *, int, u8,
+					     void *);
 
 
 static void zfcp_erp_adapter_block(struct zfcp_adapter *, int);
 static void zfcp_erp_adapter_block(struct zfcp_adapter *, int);
 static void zfcp_erp_adapter_unblock(struct zfcp_adapter *);
 static void zfcp_erp_adapter_unblock(struct zfcp_adapter *);
@@ -97,7 +101,8 @@ static void zfcp_erp_action_dismiss_unit(struct zfcp_unit *);
 static void zfcp_erp_action_dismiss(struct zfcp_erp_action *);
 static void zfcp_erp_action_dismiss(struct zfcp_erp_action *);
 
 
 static int zfcp_erp_action_enqueue(int, struct zfcp_adapter *,
 static int zfcp_erp_action_enqueue(int, struct zfcp_adapter *,
-				   struct zfcp_port *, struct zfcp_unit *);
+				   struct zfcp_port *, struct zfcp_unit *,
+				   u8 id, void *ref);
 static int zfcp_erp_action_dequeue(struct zfcp_erp_action *);
 static int zfcp_erp_action_dequeue(struct zfcp_erp_action *);
 static void zfcp_erp_action_cleanup(int, struct zfcp_adapter *,
 static void zfcp_erp_action_cleanup(int, struct zfcp_adapter *,
 				    struct zfcp_port *, struct zfcp_unit *,
 				    struct zfcp_port *, struct zfcp_unit *,
@@ -128,11 +133,9 @@ static void zfcp_close_qdio(struct zfcp_adapter *adapter)
 	atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
 	atomic_clear_mask(ZFCP_STATUS_ADAPTER_QDIOUP, &adapter->status);
 	write_unlock_irq(&req_queue->queue_lock);
 	write_unlock_irq(&req_queue->queue_lock);
 
 
-	debug_text_event(adapter->erp_dbf, 3, "qdio_down2a");
 	while (qdio_shutdown(adapter->ccw_device,
 	while (qdio_shutdown(adapter->ccw_device,
 			     QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS)
 			     QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS)
 		ssleep(1);
 		ssleep(1);
-	debug_text_event(adapter->erp_dbf, 3, "qdio_down2b");
 
 
 	/* cleanup used outbound sbals */
 	/* cleanup used outbound sbals */
 	count = atomic_read(&req_queue->free_count);
 	count = atomic_read(&req_queue->free_count);
@@ -163,7 +166,7 @@ static void zfcp_close_fsf(struct zfcp_adapter *adapter)
 	/* reset FSF request sequence number */
 	/* reset FSF request sequence number */
 	adapter->fsf_req_seq_no = 0;
 	adapter->fsf_req_seq_no = 0;
 	/* all ports and units are closed */
 	/* all ports and units are closed */
-	zfcp_erp_modify_adapter_status(adapter,
+	zfcp_erp_modify_adapter_status(adapter, 24, NULL,
 				       ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR);
 				       ZFCP_STATUS_COMMON_OPEN, ZFCP_CLEAR);
 }
 }
 
 
@@ -179,7 +182,8 @@ static void zfcp_close_fsf(struct zfcp_adapter *adapter)
 static void zfcp_fsf_request_timeout_handler(unsigned long data)
 static void zfcp_fsf_request_timeout_handler(unsigned long data)
 {
 {
 	struct zfcp_adapter *adapter = (struct zfcp_adapter *) data;
 	struct zfcp_adapter *adapter = (struct zfcp_adapter *) data;
-	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED);
+	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 62,
+				NULL);
 }
 }
 
 
 void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, unsigned long timeout)
 void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, unsigned long timeout)
@@ -200,12 +204,11 @@ void zfcp_fsf_start_timer(struct zfcp_fsf_req *fsf_req, unsigned long timeout)
  * returns:	0	- initiated action successfully
  * returns:	0	- initiated action successfully
  *		<0	- failed to initiate action
  *		<0	- failed to initiate action
  */
  */
-static int
-zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, int clear_mask)
+static int zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter,
+					    int clear_mask, u8 id, void *ref)
 {
 {
 	int retval;
 	int retval;
 
 
-	debug_text_event(adapter->erp_dbf, 5, "a_ro");
 	ZFCP_LOG_DEBUG("reopen adapter %s\n",
 	ZFCP_LOG_DEBUG("reopen adapter %s\n",
 		       zfcp_get_busid_by_adapter(adapter));
 		       zfcp_get_busid_by_adapter(adapter));
 
 
@@ -214,14 +217,13 @@ zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, int clear_mask)
 	if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &adapter->status)) {
 	if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_FAILED, &adapter->status)) {
 		ZFCP_LOG_DEBUG("skipped reopen of failed adapter %s\n",
 		ZFCP_LOG_DEBUG("skipped reopen of failed adapter %s\n",
 			       zfcp_get_busid_by_adapter(adapter));
 			       zfcp_get_busid_by_adapter(adapter));
-		debug_text_event(adapter->erp_dbf, 5, "a_ro_f");
 		/* ensure propagation of failed status to new devices */
 		/* ensure propagation of failed status to new devices */
-		zfcp_erp_adapter_failed(adapter);
+		zfcp_erp_adapter_failed(adapter, 13, NULL);
 		retval = -EIO;
 		retval = -EIO;
 		goto out;
 		goto out;
 	}
 	}
 	retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER,
 	retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_ADAPTER,
-					 adapter, NULL, NULL);
+					 adapter, NULL, NULL, id, ref);
 
 
  out:
  out:
 	return retval;
 	return retval;
@@ -236,56 +238,56 @@ zfcp_erp_adapter_reopen_internal(struct zfcp_adapter *adapter, int clear_mask)
  * returns:	0	- initiated action successfully
  * returns:	0	- initiated action successfully
  *		<0	- failed to initiate action
  *		<0	- failed to initiate action
  */
  */
-int
-zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear_mask)
+int zfcp_erp_adapter_reopen(struct zfcp_adapter *adapter, int clear_mask,
+			    u8 id, void *ref)
 {
 {
 	int retval;
 	int retval;
 	unsigned long flags;
 	unsigned long flags;
 
 
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	write_lock(&adapter->erp_lock);
 	write_lock(&adapter->erp_lock);
-	retval = zfcp_erp_adapter_reopen_internal(adapter, clear_mask);
+	retval = zfcp_erp_adapter_reopen_internal(adapter, clear_mask, id, ref);
 	write_unlock(&adapter->erp_lock);
 	write_unlock(&adapter->erp_lock);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 
 
 	return retval;
 	return retval;
 }
 }
 
 
-int
-zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear_mask)
+int zfcp_erp_adapter_shutdown(struct zfcp_adapter *adapter, int clear_mask,
+			      u8 id, void *ref)
 {
 {
 	int retval;
 	int retval;
 
 
 	retval = zfcp_erp_adapter_reopen(adapter,
 	retval = zfcp_erp_adapter_reopen(adapter,
 					 ZFCP_STATUS_COMMON_RUNNING |
 					 ZFCP_STATUS_COMMON_RUNNING |
 					 ZFCP_STATUS_COMMON_ERP_FAILED |
 					 ZFCP_STATUS_COMMON_ERP_FAILED |
-					 clear_mask);
+					 clear_mask, id, ref);
 
 
 	return retval;
 	return retval;
 }
 }
 
 
-int
-zfcp_erp_port_shutdown(struct zfcp_port *port, int clear_mask)
+int zfcp_erp_port_shutdown(struct zfcp_port *port, int clear_mask, u8 id,
+			   void *ref)
 {
 {
 	int retval;
 	int retval;
 
 
 	retval = zfcp_erp_port_reopen(port,
 	retval = zfcp_erp_port_reopen(port,
 				      ZFCP_STATUS_COMMON_RUNNING |
 				      ZFCP_STATUS_COMMON_RUNNING |
 				      ZFCP_STATUS_COMMON_ERP_FAILED |
 				      ZFCP_STATUS_COMMON_ERP_FAILED |
-				      clear_mask);
+				      clear_mask, id, ref);
 
 
 	return retval;
 	return retval;
 }
 }
 
 
-int
-zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear_mask)
+int zfcp_erp_unit_shutdown(struct zfcp_unit *unit, int clear_mask, u8 id,
+			   void *ref)
 {
 {
 	int retval;
 	int retval;
 
 
 	retval = zfcp_erp_unit_reopen(unit,
 	retval = zfcp_erp_unit_reopen(unit,
 				      ZFCP_STATUS_COMMON_RUNNING |
 				      ZFCP_STATUS_COMMON_RUNNING |
 				      ZFCP_STATUS_COMMON_ERP_FAILED |
 				      ZFCP_STATUS_COMMON_ERP_FAILED |
-				      clear_mask);
+				      clear_mask, id, ref);
 
 
 	return retval;
 	return retval;
 }
 }
@@ -399,8 +401,7 @@ zfcp_erp_adisc_handler(unsigned long data)
 				"force physical port reopen "
 				"force physical port reopen "
 				"(adapter %s, port d_id=0x%06x)\n",
 				"(adapter %s, port d_id=0x%06x)\n",
 				zfcp_get_busid_by_adapter(adapter), d_id);
 				zfcp_get_busid_by_adapter(adapter), d_id);
-		debug_text_event(adapter->erp_dbf, 3, "forcreop");
-		if (zfcp_erp_port_forced_reopen(port, 0))
+		if (zfcp_erp_port_forced_reopen(port, 0, 63, NULL))
 			ZFCP_LOG_NORMAL("failed reopen of port "
 			ZFCP_LOG_NORMAL("failed reopen of port "
 					"(adapter %s, wwpn=0x%016Lx)\n",
 					"(adapter %s, wwpn=0x%016Lx)\n",
 					zfcp_get_busid_by_port(port),
 					zfcp_get_busid_by_port(port),
@@ -427,7 +428,7 @@ zfcp_erp_adisc_handler(unsigned long data)
 				"adisc_resp_wwpn=0x%016Lx)\n",
 				"adisc_resp_wwpn=0x%016Lx)\n",
 				zfcp_get_busid_by_port(port),
 				zfcp_get_busid_by_port(port),
 				port->wwpn, (wwn_t) adisc->wwpn);
 				port->wwpn, (wwn_t) adisc->wwpn);
-		if (zfcp_erp_port_reopen(port, 0))
+		if (zfcp_erp_port_reopen(port, 0, 64, NULL))
 			ZFCP_LOG_NORMAL("failed reopen of port "
 			ZFCP_LOG_NORMAL("failed reopen of port "
 					"(adapter %s, wwpn=0x%016Lx)\n",
 					"(adapter %s, wwpn=0x%016Lx)\n",
 					zfcp_get_busid_by_port(port),
 					zfcp_get_busid_by_port(port),
@@ -461,7 +462,7 @@ zfcp_test_link(struct zfcp_port *port)
 		ZFCP_LOG_NORMAL("reopen needed for port 0x%016Lx "
 		ZFCP_LOG_NORMAL("reopen needed for port 0x%016Lx "
 				"on adapter %s\n ", port->wwpn,
 				"on adapter %s\n ", port->wwpn,
 				zfcp_get_busid_by_port(port));
 				zfcp_get_busid_by_port(port));
-		retval = zfcp_erp_port_forced_reopen(port, 0);
+		retval = zfcp_erp_port_forced_reopen(port, 0, 65, NULL);
 		if (retval != 0) {
 		if (retval != 0) {
 			ZFCP_LOG_NORMAL("reopen of remote port 0x%016Lx "
 			ZFCP_LOG_NORMAL("reopen of remote port 0x%016Lx "
 					"on adapter %s failed\n", port->wwpn,
 					"on adapter %s failed\n", port->wwpn,
@@ -484,14 +485,11 @@ zfcp_test_link(struct zfcp_port *port)
  * returns:	0	- initiated action successfully
  * returns:	0	- initiated action successfully
  *		<0	- failed to initiate action
  *		<0	- failed to initiate action
  */
  */
-static int
-zfcp_erp_port_forced_reopen_internal(struct zfcp_port *port, int clear_mask)
+static int zfcp_erp_port_forced_reopen_internal(struct zfcp_port *port,
+						int clear_mask, u8 id,
+						void *ref)
 {
 {
 	int retval;
 	int retval;
-	struct zfcp_adapter *adapter = port->adapter;
-
-	debug_text_event(adapter->erp_dbf, 5, "pf_ro");
-	debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
 
 
 	ZFCP_LOG_DEBUG("forced reopen of port 0x%016Lx on adapter %s\n",
 	ZFCP_LOG_DEBUG("forced reopen of port 0x%016Lx on adapter %s\n",
 		       port->wwpn, zfcp_get_busid_by_port(port));
 		       port->wwpn, zfcp_get_busid_by_port(port));
@@ -502,14 +500,12 @@ zfcp_erp_port_forced_reopen_internal(struct zfcp_port *port, int clear_mask)
 		ZFCP_LOG_DEBUG("skipped forced reopen of failed port 0x%016Lx "
 		ZFCP_LOG_DEBUG("skipped forced reopen of failed port 0x%016Lx "
 			       "on adapter %s\n", port->wwpn,
 			       "on adapter %s\n", port->wwpn,
 			       zfcp_get_busid_by_port(port));
 			       zfcp_get_busid_by_port(port));
-		debug_text_event(adapter->erp_dbf, 5, "pf_ro_f");
-		debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
 		retval = -EIO;
 		retval = -EIO;
 		goto out;
 		goto out;
 	}
 	}
 
 
 	retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,
 	retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT_FORCED,
-					 port->adapter, port, NULL);
+					 port->adapter, port, NULL, id, ref);
 
 
  out:
  out:
 	return retval;
 	return retval;
@@ -524,8 +520,8 @@ zfcp_erp_port_forced_reopen_internal(struct zfcp_port *port, int clear_mask)
  * returns:	0	- initiated action successfully
  * returns:	0	- initiated action successfully
  *		<0	- failed to initiate action
  *		<0	- failed to initiate action
  */
  */
-int
-zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear_mask)
+int zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear_mask, u8 id,
+				void *ref)
 {
 {
 	int retval;
 	int retval;
 	unsigned long flags;
 	unsigned long flags;
@@ -534,7 +530,8 @@ zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear_mask)
 	adapter = port->adapter;
 	adapter = port->adapter;
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	write_lock(&adapter->erp_lock);
 	write_lock(&adapter->erp_lock);
-	retval = zfcp_erp_port_forced_reopen_internal(port, clear_mask);
+	retval = zfcp_erp_port_forced_reopen_internal(port, clear_mask, id,
+						      ref);
 	write_unlock(&adapter->erp_lock);
 	write_unlock(&adapter->erp_lock);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 
 
@@ -551,14 +548,10 @@ zfcp_erp_port_forced_reopen(struct zfcp_port *port, int clear_mask)
  * returns:	0	- initiated action successfully
  * returns:	0	- initiated action successfully
  *		<0	- failed to initiate action
  *		<0	- failed to initiate action
  */
  */
-static int
-zfcp_erp_port_reopen_internal(struct zfcp_port *port, int clear_mask)
+static int zfcp_erp_port_reopen_internal(struct zfcp_port *port, int clear_mask,
+					 u8 id, void *ref)
 {
 {
 	int retval;
 	int retval;
-	struct zfcp_adapter *adapter = port->adapter;
-
-	debug_text_event(adapter->erp_dbf, 5, "p_ro");
-	debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
 
 
 	ZFCP_LOG_DEBUG("reopen of port 0x%016Lx on adapter %s\n",
 	ZFCP_LOG_DEBUG("reopen of port 0x%016Lx on adapter %s\n",
 		       port->wwpn, zfcp_get_busid_by_port(port));
 		       port->wwpn, zfcp_get_busid_by_port(port));
@@ -569,16 +562,14 @@ zfcp_erp_port_reopen_internal(struct zfcp_port *port, int clear_mask)
 		ZFCP_LOG_DEBUG("skipped reopen of failed port 0x%016Lx "
 		ZFCP_LOG_DEBUG("skipped reopen of failed port 0x%016Lx "
 			       "on adapter %s\n", port->wwpn,
 			       "on adapter %s\n", port->wwpn,
 			       zfcp_get_busid_by_port(port));
 			       zfcp_get_busid_by_port(port));
-		debug_text_event(adapter->erp_dbf, 5, "p_ro_f");
-		debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
 		/* ensure propagation of failed status to new devices */
 		/* ensure propagation of failed status to new devices */
-		zfcp_erp_port_failed(port);
+		zfcp_erp_port_failed(port, 14, NULL);
 		retval = -EIO;
 		retval = -EIO;
 		goto out;
 		goto out;
 	}
 	}
 
 
 	retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT,
 	retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_PORT,
-					 port->adapter, port, NULL);
+					 port->adapter, port, NULL, id, ref);
 
 
  out:
  out:
 	return retval;
 	return retval;
@@ -594,8 +585,8 @@ zfcp_erp_port_reopen_internal(struct zfcp_port *port, int clear_mask)
  * correct locking. An error recovery task is initiated to do the reopen.
  * correct locking. An error recovery task is initiated to do the reopen.
  * To wait for the completion of the reopen zfcp_erp_wait should be used.
  * To wait for the completion of the reopen zfcp_erp_wait should be used.
  */
  */
-int
-zfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask)
+int zfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask, u8 id,
+			 void *ref)
 {
 {
 	int retval;
 	int retval;
 	unsigned long flags;
 	unsigned long flags;
@@ -603,7 +594,7 @@ zfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask)
 
 
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	write_lock(&adapter->erp_lock);
 	write_lock(&adapter->erp_lock);
-	retval = zfcp_erp_port_reopen_internal(port, clear_mask);
+	retval = zfcp_erp_port_reopen_internal(port, clear_mask, id, ref);
 	write_unlock(&adapter->erp_lock);
 	write_unlock(&adapter->erp_lock);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 
 
@@ -620,14 +611,12 @@ zfcp_erp_port_reopen(struct zfcp_port *port, int clear_mask)
  * returns:	0	- initiated action successfully
  * returns:	0	- initiated action successfully
  *		<0	- failed to initiate action
  *		<0	- failed to initiate action
  */
  */
-static int
-zfcp_erp_unit_reopen_internal(struct zfcp_unit *unit, int clear_mask)
+static int zfcp_erp_unit_reopen_internal(struct zfcp_unit *unit, int clear_mask,
+					 u8 id, void *ref)
 {
 {
 	int retval;
 	int retval;
 	struct zfcp_adapter *adapter = unit->port->adapter;
 	struct zfcp_adapter *adapter = unit->port->adapter;
 
 
-	debug_text_event(adapter->erp_dbf, 5, "u_ro");
-	debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, sizeof (fcp_lun_t));
 	ZFCP_LOG_DEBUG("reopen of unit 0x%016Lx on port 0x%016Lx "
 	ZFCP_LOG_DEBUG("reopen of unit 0x%016Lx on port 0x%016Lx "
 		       "on adapter %s\n", unit->fcp_lun,
 		       "on adapter %s\n", unit->fcp_lun,
 		       unit->port->wwpn, zfcp_get_busid_by_unit(unit));
 		       unit->port->wwpn, zfcp_get_busid_by_unit(unit));
@@ -639,15 +628,12 @@ zfcp_erp_unit_reopen_internal(struct zfcp_unit *unit, int clear_mask)
 			       "on port 0x%016Lx on adapter %s\n",
 			       "on port 0x%016Lx on adapter %s\n",
 			       unit->fcp_lun, unit->port->wwpn,
 			       unit->fcp_lun, unit->port->wwpn,
 			       zfcp_get_busid_by_unit(unit));
 			       zfcp_get_busid_by_unit(unit));
-		debug_text_event(adapter->erp_dbf, 5, "u_ro_f");
-		debug_event(adapter->erp_dbf, 5, &unit->fcp_lun,
-			    sizeof (fcp_lun_t));
 		retval = -EIO;
 		retval = -EIO;
 		goto out;
 		goto out;
 	}
 	}
 
 
 	retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_UNIT,
 	retval = zfcp_erp_action_enqueue(ZFCP_ERP_ACTION_REOPEN_UNIT,
-					 unit->port->adapter, unit->port, unit);
+					 adapter, unit->port, unit, id, ref);
  out:
  out:
 	return retval;
 	return retval;
 }
 }
@@ -662,8 +648,8 @@ zfcp_erp_unit_reopen_internal(struct zfcp_unit *unit, int clear_mask)
  * locking. An error recovery task is initiated to do the reopen.
  * locking. An error recovery task is initiated to do the reopen.
  * To wait for the completion of the reopen zfcp_erp_wait should be used.
  * To wait for the completion of the reopen zfcp_erp_wait should be used.
  */
  */
-int
-zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear_mask)
+int zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear_mask, u8 id,
+			 void *ref)
 {
 {
 	int retval;
 	int retval;
 	unsigned long flags;
 	unsigned long flags;
@@ -675,7 +661,7 @@ zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear_mask)
 
 
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	write_lock(&adapter->erp_lock);
 	write_lock(&adapter->erp_lock);
-	retval = zfcp_erp_unit_reopen_internal(unit, clear_mask);
+	retval = zfcp_erp_unit_reopen_internal(unit, clear_mask, id, ref);
 	write_unlock(&adapter->erp_lock);
 	write_unlock(&adapter->erp_lock);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 
 
@@ -687,19 +673,43 @@ zfcp_erp_unit_reopen(struct zfcp_unit *unit, int clear_mask)
  */
  */
 static void zfcp_erp_adapter_block(struct zfcp_adapter *adapter, int clear_mask)
 static void zfcp_erp_adapter_block(struct zfcp_adapter *adapter, int clear_mask)
 {
 {
-	debug_text_event(adapter->erp_dbf, 6, "a_bl");
-	zfcp_erp_modify_adapter_status(adapter,
+	zfcp_erp_modify_adapter_status(adapter, 15, NULL,
 				       ZFCP_STATUS_COMMON_UNBLOCKED |
 				       ZFCP_STATUS_COMMON_UNBLOCKED |
 				       clear_mask, ZFCP_CLEAR);
 				       clear_mask, ZFCP_CLEAR);
 }
 }
 
 
+/* FIXME: isn't really atomic */
+/*
+ * returns the mask which has not been set so far, i.e.
+ * 0 if no bit has been changed, !0 if some bit has been changed
+ */
+static int atomic_test_and_set_mask(unsigned long mask, atomic_t *v)
+{
+	int changed_bits = (atomic_read(v) /*XOR*/^ mask) & mask;
+	atomic_set_mask(mask, v);
+	return changed_bits;
+}
+
+/* FIXME: isn't really atomic */
+/*
+ * returns the mask which has not been cleared so far, i.e.
+ * 0 if no bit has been changed, !0 if some bit has been changed
+ */
+static int atomic_test_and_clear_mask(unsigned long mask, atomic_t *v)
+{
+	int changed_bits = atomic_read(v) & mask;
+	atomic_clear_mask(mask, v);
+	return changed_bits;
+}
+
 /**
 /**
  * zfcp_erp_adapter_unblock - mark adapter as unblocked, allow scsi requests
  * zfcp_erp_adapter_unblock - mark adapter as unblocked, allow scsi requests
  */
  */
 static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter)
 static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter)
 {
 {
-	debug_text_event(adapter->erp_dbf, 6, "a_ubl");
-	atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status);
+	if (atomic_test_and_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
+				     &adapter->status))
+		zfcp_rec_dbf_event_adapter(16, NULL, adapter);
 }
 }
 
 
 /*
 /*
@@ -714,11 +724,7 @@ static void zfcp_erp_adapter_unblock(struct zfcp_adapter *adapter)
 static void
 static void
 zfcp_erp_port_block(struct zfcp_port *port, int clear_mask)
 zfcp_erp_port_block(struct zfcp_port *port, int clear_mask)
 {
 {
-	struct zfcp_adapter *adapter = port->adapter;
-
-	debug_text_event(adapter->erp_dbf, 6, "p_bl");
-	debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));
-	zfcp_erp_modify_port_status(port,
+	zfcp_erp_modify_port_status(port, 17, NULL,
 				    ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask,
 				    ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask,
 				    ZFCP_CLEAR);
 				    ZFCP_CLEAR);
 }
 }
@@ -733,11 +739,9 @@ zfcp_erp_port_block(struct zfcp_port *port, int clear_mask)
 static void
 static void
 zfcp_erp_port_unblock(struct zfcp_port *port)
 zfcp_erp_port_unblock(struct zfcp_port *port)
 {
 {
-	struct zfcp_adapter *adapter = port->adapter;
-
-	debug_text_event(adapter->erp_dbf, 6, "p_ubl");
-	debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));
-	atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &port->status);
+	if (atomic_test_and_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
+				     &port->status))
+		zfcp_rec_dbf_event_port(18, NULL, port);
 }
 }
 
 
 /*
 /*
@@ -752,11 +756,7 @@ zfcp_erp_port_unblock(struct zfcp_port *port)
 static void
 static void
 zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask)
 zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask)
 {
 {
-	struct zfcp_adapter *adapter = unit->port->adapter;
-
-	debug_text_event(adapter->erp_dbf, 6, "u_bl");
-	debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t));
-	zfcp_erp_modify_unit_status(unit,
+	zfcp_erp_modify_unit_status(unit, 19, NULL,
 				    ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask,
 				    ZFCP_STATUS_COMMON_UNBLOCKED | clear_mask,
 				    ZFCP_CLEAR);
 				    ZFCP_CLEAR);
 }
 }
@@ -771,11 +771,9 @@ zfcp_erp_unit_block(struct zfcp_unit *unit, int clear_mask)
 static void
 static void
 zfcp_erp_unit_unblock(struct zfcp_unit *unit)
 zfcp_erp_unit_unblock(struct zfcp_unit *unit)
 {
 {
-	struct zfcp_adapter *adapter = unit->port->adapter;
-
-	debug_text_event(adapter->erp_dbf, 6, "u_ubl");
-	debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t));
-	atomic_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED, &unit->status);
+	if (atomic_test_and_set_mask(ZFCP_STATUS_COMMON_UNBLOCKED,
+				     &unit->status))
+		zfcp_rec_dbf_event_unit(20, NULL, unit);
 }
 }
 
 
 static void
 static void
@@ -783,11 +781,9 @@ zfcp_erp_action_ready(struct zfcp_erp_action *erp_action)
 {
 {
 	struct zfcp_adapter *adapter = erp_action->adapter;
 	struct zfcp_adapter *adapter = erp_action->adapter;
 
 
-	debug_text_event(adapter->erp_dbf, 4, "a_ar");
-	debug_event(adapter->erp_dbf, 4, &erp_action->action, sizeof (int));
-
 	zfcp_erp_action_to_ready(erp_action);
 	zfcp_erp_action_to_ready(erp_action);
 	up(&adapter->erp_ready_sem);
 	up(&adapter->erp_ready_sem);
+	zfcp_rec_dbf_event_thread(2, adapter, 0);
 }
 }
 
 
 /*
 /*
@@ -849,18 +845,15 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
 		if (zfcp_reqlist_find_safe(adapter, erp_action->fsf_req) &&
 		if (zfcp_reqlist_find_safe(adapter, erp_action->fsf_req) &&
 		    erp_action->fsf_req->erp_action == erp_action) {
 		    erp_action->fsf_req->erp_action == erp_action) {
 			/* fsf_req still exists */
 			/* fsf_req still exists */
-			debug_text_event(adapter->erp_dbf, 3, "a_ca_req");
-			debug_event(adapter->erp_dbf, 3, &erp_action->fsf_req,
-				    sizeof (unsigned long));
 			/* dismiss fsf_req of timed out/dismissed erp_action */
 			/* dismiss fsf_req of timed out/dismissed erp_action */
 			if (erp_action->status & (ZFCP_STATUS_ERP_DISMISSED |
 			if (erp_action->status & (ZFCP_STATUS_ERP_DISMISSED |
 						  ZFCP_STATUS_ERP_TIMEDOUT)) {
 						  ZFCP_STATUS_ERP_TIMEDOUT)) {
-				debug_text_event(adapter->erp_dbf, 3,
-						 "a_ca_disreq");
 				erp_action->fsf_req->status |=
 				erp_action->fsf_req->status |=
 					ZFCP_STATUS_FSFREQ_DISMISSED;
 					ZFCP_STATUS_FSFREQ_DISMISSED;
+				zfcp_rec_dbf_event_action(142, erp_action);
 			}
 			}
 			if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
 			if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
+				zfcp_rec_dbf_event_action(143, erp_action);
 				ZFCP_LOG_NORMAL("error: erp step timed out "
 				ZFCP_LOG_NORMAL("error: erp step timed out "
 						"(action=%d, fsf_req=%p)\n ",
 						"(action=%d, fsf_req=%p)\n ",
 						erp_action->action,
 						erp_action->action,
@@ -879,7 +872,6 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
 				erp_action->fsf_req = NULL;
 				erp_action->fsf_req = NULL;
 			}
 			}
 		} else {
 		} else {
-			debug_text_event(adapter->erp_dbf, 3, "a_ca_gonereq");
 			/*
 			/*
 			 * even if this fsf_req has gone, forget about
 			 * even if this fsf_req has gone, forget about
 			 * association between erp_action and fsf_req
 			 * association between erp_action and fsf_req
@@ -887,8 +879,7 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
 			erp_action->fsf_req = NULL;
 			erp_action->fsf_req = NULL;
 		}
 		}
 		spin_unlock(&adapter->req_list_lock);
 		spin_unlock(&adapter->req_list_lock);
-	} else
-		debug_text_event(adapter->erp_dbf, 3, "a_ca_noreq");
+	}
 }
 }
 
 
 /**
 /**
@@ -900,19 +891,11 @@ zfcp_erp_strategy_check_fsfreq(struct zfcp_erp_action *erp_action)
 static void zfcp_erp_async_handler_nolock(struct zfcp_erp_action *erp_action,
 static void zfcp_erp_async_handler_nolock(struct zfcp_erp_action *erp_action,
 					  unsigned long set_mask)
 					  unsigned long set_mask)
 {
 {
-	struct zfcp_adapter *adapter = erp_action->adapter;
-
 	if (zfcp_erp_action_exists(erp_action) == ZFCP_ERP_ACTION_RUNNING) {
 	if (zfcp_erp_action_exists(erp_action) == ZFCP_ERP_ACTION_RUNNING) {
-		debug_text_event(adapter->erp_dbf, 2, "a_asyh_ex");
-		debug_event(adapter->erp_dbf, 2, &erp_action->action,
-			    sizeof (int));
 		erp_action->status |= set_mask;
 		erp_action->status |= set_mask;
 		zfcp_erp_action_ready(erp_action);
 		zfcp_erp_action_ready(erp_action);
 	} else {
 	} else {
 		/* action is ready or gone - nothing to do */
 		/* action is ready or gone - nothing to do */
-		debug_text_event(adapter->erp_dbf, 3, "a_asyh_gone");
-		debug_event(adapter->erp_dbf, 3, &erp_action->action,
-			    sizeof (int));
 	}
 	}
 }
 }
 
 
@@ -939,10 +922,6 @@ static void
 zfcp_erp_memwait_handler(unsigned long data)
 zfcp_erp_memwait_handler(unsigned long data)
 {
 {
 	struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data;
 	struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data;
-	struct zfcp_adapter *adapter = erp_action->adapter;
-
-	debug_text_event(adapter->erp_dbf, 2, "a_mwh");
-	debug_event(adapter->erp_dbf, 2, &erp_action->action, sizeof (int));
 
 
 	zfcp_erp_async_handler(erp_action, 0);
 	zfcp_erp_async_handler(erp_action, 0);
 }
 }
@@ -955,10 +934,6 @@ zfcp_erp_memwait_handler(unsigned long data)
 static void zfcp_erp_timeout_handler(unsigned long data)
 static void zfcp_erp_timeout_handler(unsigned long data)
 {
 {
 	struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data;
 	struct zfcp_erp_action *erp_action = (struct zfcp_erp_action *) data;
-	struct zfcp_adapter *adapter = erp_action->adapter;
-
-	debug_text_event(adapter->erp_dbf, 2, "a_th");
-	debug_event(adapter->erp_dbf, 2, &erp_action->action, sizeof (int));
 
 
 	zfcp_erp_async_handler(erp_action, ZFCP_STATUS_ERP_TIMEDOUT);
 	zfcp_erp_async_handler(erp_action, ZFCP_STATUS_ERP_TIMEDOUT);
 }
 }
@@ -973,11 +948,6 @@ static void zfcp_erp_timeout_handler(unsigned long data)
  */
  */
 static void zfcp_erp_action_dismiss(struct zfcp_erp_action *erp_action)
 static void zfcp_erp_action_dismiss(struct zfcp_erp_action *erp_action)
 {
 {
-	struct zfcp_adapter *adapter = erp_action->adapter;
-
-	debug_text_event(adapter->erp_dbf, 2, "a_adis");
-	debug_event(adapter->erp_dbf, 2, &erp_action->action, sizeof (int));
-
 	erp_action->status |= ZFCP_STATUS_ERP_DISMISSED;
 	erp_action->status |= ZFCP_STATUS_ERP_DISMISSED;
 	if (zfcp_erp_action_exists(erp_action) == ZFCP_ERP_ACTION_RUNNING)
 	if (zfcp_erp_action_exists(erp_action) == ZFCP_ERP_ACTION_RUNNING)
 		zfcp_erp_action_ready(erp_action);
 		zfcp_erp_action_ready(erp_action);
@@ -995,12 +965,10 @@ zfcp_erp_thread_setup(struct zfcp_adapter *adapter)
 		ZFCP_LOG_NORMAL("error: creation of erp thread failed for "
 		ZFCP_LOG_NORMAL("error: creation of erp thread failed for "
 				"adapter %s\n",
 				"adapter %s\n",
 				zfcp_get_busid_by_adapter(adapter));
 				zfcp_get_busid_by_adapter(adapter));
-		debug_text_event(adapter->erp_dbf, 5, "a_thset_fail");
 	} else {
 	} else {
 		wait_event(adapter->erp_thread_wqh,
 		wait_event(adapter->erp_thread_wqh,
 			   atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP,
 			   atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP,
 					    &adapter->status));
 					    &adapter->status));
-		debug_text_event(adapter->erp_dbf, 5, "a_thset_ok");
 	}
 	}
 
 
 	return (retval < 0);
 	return (retval < 0);
@@ -1027,6 +995,7 @@ zfcp_erp_thread_kill(struct zfcp_adapter *adapter)
 
 
 	atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status);
 	atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL, &adapter->status);
 	up(&adapter->erp_ready_sem);
 	up(&adapter->erp_ready_sem);
+	zfcp_rec_dbf_event_thread(2, adapter, 1);
 
 
 	wait_event(adapter->erp_thread_wqh,
 	wait_event(adapter->erp_thread_wqh,
 		   !atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP,
 		   !atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP,
@@ -1035,8 +1004,6 @@ zfcp_erp_thread_kill(struct zfcp_adapter *adapter)
 	atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL,
 	atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL,
 			  &adapter->status);
 			  &adapter->status);
 
 
-	debug_text_event(adapter->erp_dbf, 5, "a_thki_ok");
-
 	return retval;
 	return retval;
 }
 }
 
 
@@ -1059,7 +1026,6 @@ zfcp_erp_thread(void *data)
 	/* Block all signals */
 	/* Block all signals */
 	siginitsetinv(&current->blocked, 0);
 	siginitsetinv(&current->blocked, 0);
 	atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
 	atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
-	debug_text_event(adapter->erp_dbf, 5, "a_th_run");
 	wake_up(&adapter->erp_thread_wqh);
 	wake_up(&adapter->erp_thread_wqh);
 
 
 	while (!atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL,
 	while (!atomic_test_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_KILL,
@@ -1084,12 +1050,12 @@ zfcp_erp_thread(void *data)
 		 * no action in 'ready' queue to be processed and
 		 * no action in 'ready' queue to be processed and
 		 * thread is not to be killed
 		 * thread is not to be killed
 		 */
 		 */
+		zfcp_rec_dbf_event_thread(4, adapter, 1);
 		down_interruptible(&adapter->erp_ready_sem);
 		down_interruptible(&adapter->erp_ready_sem);
-		debug_text_event(adapter->erp_dbf, 5, "a_th_woken");
+		zfcp_rec_dbf_event_thread(5, adapter, 1);
 	}
 	}
 
 
 	atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
 	atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_THREAD_UP, &adapter->status);
-	debug_text_event(adapter->erp_dbf, 5, "a_th_stop");
 	wake_up(&adapter->erp_thread_wqh);
 	wake_up(&adapter->erp_thread_wqh);
 
 
 	return 0;
 	return 0;
@@ -1125,7 +1091,6 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
 	/* dequeue dismissed action and leave, if required */
 	/* dequeue dismissed action and leave, if required */
 	retval = zfcp_erp_strategy_check_action(erp_action, retval);
 	retval = zfcp_erp_strategy_check_action(erp_action, retval);
 	if (retval == ZFCP_ERP_DISMISSED) {
 	if (retval == ZFCP_ERP_DISMISSED) {
-		debug_text_event(adapter->erp_dbf, 4, "a_st_dis1");
 		goto unlock;
 		goto unlock;
 	}
 	}
 
 
@@ -1176,20 +1141,17 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
 		   element was timed out.
 		   element was timed out.
 		 */
 		 */
 		if (adapter->erp_total_count == adapter->erp_low_mem_count) {
 		if (adapter->erp_total_count == adapter->erp_low_mem_count) {
-			debug_text_event(adapter->erp_dbf, 3, "a_st_lowmem");
 			ZFCP_LOG_NORMAL("error: no mempool elements available, "
 			ZFCP_LOG_NORMAL("error: no mempool elements available, "
 					"restarting I/O on adapter %s "
 					"restarting I/O on adapter %s "
 					"to free mempool\n",
 					"to free mempool\n",
 					zfcp_get_busid_by_adapter(adapter));
 					zfcp_get_busid_by_adapter(adapter));
-			zfcp_erp_adapter_reopen_internal(adapter, 0);
+			zfcp_erp_adapter_reopen_internal(adapter, 0, 66, NULL);
 		} else {
 		} else {
-		debug_text_event(adapter->erp_dbf, 2, "a_st_memw");
 		retval = zfcp_erp_strategy_memwait(erp_action);
 		retval = zfcp_erp_strategy_memwait(erp_action);
 		}
 		}
 		goto unlock;
 		goto unlock;
 	case ZFCP_ERP_CONTINUES:
 	case ZFCP_ERP_CONTINUES:
 		/* leave since this action runs asynchronously */
 		/* leave since this action runs asynchronously */
-		debug_text_event(adapter->erp_dbf, 6, "a_st_cont");
 		if (erp_action->status & ZFCP_STATUS_ERP_LOWMEM) {
 		if (erp_action->status & ZFCP_STATUS_ERP_LOWMEM) {
 			--adapter->erp_low_mem_count;
 			--adapter->erp_low_mem_count;
 			erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM;
 			erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM;
@@ -1218,7 +1180,6 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
 	 * action is repeated in order to process state change
 	 * action is repeated in order to process state change
 	 */
 	 */
 	if (retval == ZFCP_ERP_EXIT) {
 	if (retval == ZFCP_ERP_EXIT) {
-		debug_text_event(adapter->erp_dbf, 2, "a_st_exit");
 		goto unlock;
 		goto unlock;
 	}
 	}
 
 
@@ -1244,8 +1205,6 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
 	if (retval != ZFCP_ERP_DISMISSED)
 	if (retval != ZFCP_ERP_DISMISSED)
 		zfcp_erp_strategy_check_queues(adapter);
 		zfcp_erp_strategy_check_queues(adapter);
 
 
-	debug_text_event(adapter->erp_dbf, 6, "a_st_done");
-
 	return retval;
 	return retval;
 }
 }
 
 
@@ -1260,17 +1219,12 @@ zfcp_erp_strategy(struct zfcp_erp_action *erp_action)
 static int
 static int
 zfcp_erp_strategy_check_action(struct zfcp_erp_action *erp_action, int retval)
 zfcp_erp_strategy_check_action(struct zfcp_erp_action *erp_action, int retval)
 {
 {
-	struct zfcp_adapter *adapter = erp_action->adapter;
-
 	zfcp_erp_strategy_check_fsfreq(erp_action);
 	zfcp_erp_strategy_check_fsfreq(erp_action);
 
 
-	debug_event(adapter->erp_dbf, 5, &erp_action->action, sizeof (int));
 	if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) {
 	if (erp_action->status & ZFCP_STATUS_ERP_DISMISSED) {
-		debug_text_event(adapter->erp_dbf, 3, "a_stcd_dis");
 		zfcp_erp_action_dequeue(erp_action);
 		zfcp_erp_action_dequeue(erp_action);
 		retval = ZFCP_ERP_DISMISSED;
 		retval = ZFCP_ERP_DISMISSED;
-	} else
-		debug_text_event(adapter->erp_dbf, 5, "a_stcd_nodis");
+	}
 
 
 	return retval;
 	return retval;
 }
 }
@@ -1279,7 +1233,6 @@ static int
 zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action)
 zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action)
 {
 {
 	int retval = ZFCP_ERP_FAILED;
 	int retval = ZFCP_ERP_FAILED;
-	struct zfcp_adapter *adapter = erp_action->adapter;
 
 
 	/*
 	/*
 	 * try to execute/continue action as far as possible,
 	 * try to execute/continue action as far as possible,
@@ -1309,9 +1262,6 @@ zfcp_erp_strategy_do_action(struct zfcp_erp_action *erp_action)
 		break;
 		break;
 
 
 	default:
 	default:
-		debug_text_exception(adapter->erp_dbf, 1, "a_stda_bug");
-		debug_event(adapter->erp_dbf, 1, &erp_action->action,
-			    sizeof (int));
 		ZFCP_LOG_NORMAL("bug: unknown erp action requested on "
 		ZFCP_LOG_NORMAL("bug: unknown erp action requested on "
 				"adapter %s (action=%d)\n",
 				"adapter %s (action=%d)\n",
 				zfcp_get_busid_by_adapter(erp_action->adapter),
 				zfcp_get_busid_by_adapter(erp_action->adapter),
@@ -1333,10 +1283,7 @@ static int
 zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action)
 zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action)
 {
 {
 	int retval = ZFCP_ERP_CONTINUES;
 	int retval = ZFCP_ERP_CONTINUES;
-	struct zfcp_adapter *adapter = erp_action->adapter;
 
 
-	debug_text_event(adapter->erp_dbf, 6, "a_mwinit");
-	debug_event(adapter->erp_dbf, 6, &erp_action->action, sizeof (int));
 	init_timer(&erp_action->timer);
 	init_timer(&erp_action->timer);
 	erp_action->timer.function = zfcp_erp_memwait_handler;
 	erp_action->timer.function = zfcp_erp_memwait_handler;
 	erp_action->timer.data = (unsigned long) erp_action;
 	erp_action->timer.data = (unsigned long) erp_action;
@@ -1353,13 +1300,12 @@ zfcp_erp_strategy_memwait(struct zfcp_erp_action *erp_action)
  *
  *
  */
  */
 void
 void
-zfcp_erp_adapter_failed(struct zfcp_adapter *adapter)
+zfcp_erp_adapter_failed(struct zfcp_adapter *adapter, u8 id, void *ref)
 {
 {
-	zfcp_erp_modify_adapter_status(adapter,
+	zfcp_erp_modify_adapter_status(adapter, id, ref,
 				       ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
 				       ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
 	ZFCP_LOG_NORMAL("adapter erp failed on adapter %s\n",
 	ZFCP_LOG_NORMAL("adapter erp failed on adapter %s\n",
 			zfcp_get_busid_by_adapter(adapter));
 			zfcp_get_busid_by_adapter(adapter));
-	debug_text_event(adapter->erp_dbf, 2, "a_afail");
 }
 }
 
 
 /*
 /*
@@ -1369,9 +1315,9 @@ zfcp_erp_adapter_failed(struct zfcp_adapter *adapter)
  *
  *
  */
  */
 void
 void
-zfcp_erp_port_failed(struct zfcp_port *port)
+zfcp_erp_port_failed(struct zfcp_port *port, u8 id, void *ref)
 {
 {
-	zfcp_erp_modify_port_status(port,
+	zfcp_erp_modify_port_status(port, id, ref,
 				    ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
 				    ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
 
 
 	if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
 	if (atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
@@ -1381,9 +1327,6 @@ zfcp_erp_port_failed(struct zfcp_port *port)
 	else
 	else
 		ZFCP_LOG_NORMAL("port erp failed (adapter %s, wwpn=0x%016Lx)\n",
 		ZFCP_LOG_NORMAL("port erp failed (adapter %s, wwpn=0x%016Lx)\n",
 				zfcp_get_busid_by_port(port), port->wwpn);
 				zfcp_get_busid_by_port(port), port->wwpn);
-
-	debug_text_event(port->adapter->erp_dbf, 2, "p_pfail");
-	debug_event(port->adapter->erp_dbf, 2, &port->wwpn, sizeof (wwn_t));
 }
 }
 
 
 /*
 /*
@@ -1393,17 +1336,14 @@ zfcp_erp_port_failed(struct zfcp_port *port)
  *
  *
  */
  */
 void
 void
-zfcp_erp_unit_failed(struct zfcp_unit *unit)
+zfcp_erp_unit_failed(struct zfcp_unit *unit, u8 id, void *ref)
 {
 {
-	zfcp_erp_modify_unit_status(unit,
+	zfcp_erp_modify_unit_status(unit, id, ref,
 				    ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
 				    ZFCP_STATUS_COMMON_ERP_FAILED, ZFCP_SET);
 
 
 	ZFCP_LOG_NORMAL("unit erp failed on unit 0x%016Lx on port 0x%016Lx "
 	ZFCP_LOG_NORMAL("unit erp failed on unit 0x%016Lx on port 0x%016Lx "
 			" on adapter %s\n", unit->fcp_lun,
 			" on adapter %s\n", unit->fcp_lun,
 			unit->port->wwpn, zfcp_get_busid_by_unit(unit));
 			unit->port->wwpn, zfcp_get_busid_by_unit(unit));
-	debug_text_event(unit->port->adapter->erp_dbf, 2, "u_ufail");
-	debug_event(unit->port->adapter->erp_dbf, 2,
-		    &unit->fcp_lun, sizeof (fcp_lun_t));
 }
 }
 
 
 /*
 /*
@@ -1427,10 +1367,6 @@ zfcp_erp_strategy_check_target(struct zfcp_erp_action *erp_action, int result)
 	struct zfcp_port *port = erp_action->port;
 	struct zfcp_port *port = erp_action->port;
 	struct zfcp_unit *unit = erp_action->unit;
 	struct zfcp_unit *unit = erp_action->unit;
 
 
-	debug_text_event(adapter->erp_dbf, 5, "a_stct_norm");
-	debug_event(adapter->erp_dbf, 5, &erp_action->action, sizeof (int));
-	debug_event(adapter->erp_dbf, 5, &result, sizeof (int));
-
 	switch (erp_action->action) {
 	switch (erp_action->action) {
 
 
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
@@ -1457,15 +1393,14 @@ zfcp_erp_strategy_statechange(int action,
 			      struct zfcp_port *port,
 			      struct zfcp_port *port,
 			      struct zfcp_unit *unit, int retval)
 			      struct zfcp_unit *unit, int retval)
 {
 {
-	debug_text_event(adapter->erp_dbf, 3, "a_stsc");
-	debug_event(adapter->erp_dbf, 3, &action, sizeof (int));
-
 	switch (action) {
 	switch (action) {
 
 
 	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
 	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
 		if (zfcp_erp_strategy_statechange_detected(&adapter->status,
 		if (zfcp_erp_strategy_statechange_detected(&adapter->status,
 							   status)) {
 							   status)) {
-			zfcp_erp_adapter_reopen_internal(adapter, ZFCP_STATUS_COMMON_ERP_FAILED);
+			zfcp_erp_adapter_reopen_internal(adapter,
+						ZFCP_STATUS_COMMON_ERP_FAILED,
+						67, NULL);
 			retval = ZFCP_ERP_EXIT;
 			retval = ZFCP_ERP_EXIT;
 		}
 		}
 		break;
 		break;
@@ -1474,7 +1409,9 @@ zfcp_erp_strategy_statechange(int action,
 	case ZFCP_ERP_ACTION_REOPEN_PORT:
 	case ZFCP_ERP_ACTION_REOPEN_PORT:
 		if (zfcp_erp_strategy_statechange_detected(&port->status,
 		if (zfcp_erp_strategy_statechange_detected(&port->status,
 							   status)) {
 							   status)) {
-			zfcp_erp_port_reopen_internal(port, ZFCP_STATUS_COMMON_ERP_FAILED);
+			zfcp_erp_port_reopen_internal(port,
+						ZFCP_STATUS_COMMON_ERP_FAILED,
+						68, NULL);
 			retval = ZFCP_ERP_EXIT;
 			retval = ZFCP_ERP_EXIT;
 		}
 		}
 		break;
 		break;
@@ -1482,7 +1419,9 @@ zfcp_erp_strategy_statechange(int action,
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
 		if (zfcp_erp_strategy_statechange_detected(&unit->status,
 		if (zfcp_erp_strategy_statechange_detected(&unit->status,
 							   status)) {
 							   status)) {
-			zfcp_erp_unit_reopen_internal(unit, ZFCP_STATUS_COMMON_ERP_FAILED);
+			zfcp_erp_unit_reopen_internal(unit,
+						ZFCP_STATUS_COMMON_ERP_FAILED,
+						69, NULL);
 			retval = ZFCP_ERP_EXIT;
 			retval = ZFCP_ERP_EXIT;
 		}
 		}
 		break;
 		break;
@@ -1506,10 +1445,6 @@ zfcp_erp_strategy_statechange_detected(atomic_t * target_status, u32 erp_status)
 static int
 static int
 zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result)
 zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result)
 {
 {
-	debug_text_event(unit->port->adapter->erp_dbf, 5, "u_stct");
-	debug_event(unit->port->adapter->erp_dbf, 5, &unit->fcp_lun,
-		    sizeof (fcp_lun_t));
-
 	switch (result) {
 	switch (result) {
 	case ZFCP_ERP_SUCCEEDED :
 	case ZFCP_ERP_SUCCEEDED :
 		atomic_set(&unit->erp_counter, 0);
 		atomic_set(&unit->erp_counter, 0);
@@ -1518,7 +1453,7 @@ zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result)
 	case ZFCP_ERP_FAILED :
 	case ZFCP_ERP_FAILED :
 		atomic_inc(&unit->erp_counter);
 		atomic_inc(&unit->erp_counter);
 		if (atomic_read(&unit->erp_counter) > ZFCP_MAX_ERPS)
 		if (atomic_read(&unit->erp_counter) > ZFCP_MAX_ERPS)
-			zfcp_erp_unit_failed(unit);
+			zfcp_erp_unit_failed(unit, 21, NULL);
 		break;
 		break;
 	case ZFCP_ERP_EXIT :
 	case ZFCP_ERP_EXIT :
 		/* nothing */
 		/* nothing */
@@ -1536,9 +1471,6 @@ zfcp_erp_strategy_check_unit(struct zfcp_unit *unit, int result)
 static int
 static int
 zfcp_erp_strategy_check_port(struct zfcp_port *port, int result)
 zfcp_erp_strategy_check_port(struct zfcp_port *port, int result)
 {
 {
-	debug_text_event(port->adapter->erp_dbf, 5, "p_stct");
-	debug_event(port->adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
-
 	switch (result) {
 	switch (result) {
 	case ZFCP_ERP_SUCCEEDED :
 	case ZFCP_ERP_SUCCEEDED :
 		atomic_set(&port->erp_counter, 0);
 		atomic_set(&port->erp_counter, 0);
@@ -1547,7 +1479,7 @@ zfcp_erp_strategy_check_port(struct zfcp_port *port, int result)
 	case ZFCP_ERP_FAILED :
 	case ZFCP_ERP_FAILED :
 		atomic_inc(&port->erp_counter);
 		atomic_inc(&port->erp_counter);
 		if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS)
 		if (atomic_read(&port->erp_counter) > ZFCP_MAX_ERPS)
-			zfcp_erp_port_failed(port);
+			zfcp_erp_port_failed(port, 22, NULL);
 		break;
 		break;
 	case ZFCP_ERP_EXIT :
 	case ZFCP_ERP_EXIT :
 		/* nothing */
 		/* nothing */
@@ -1565,8 +1497,6 @@ zfcp_erp_strategy_check_port(struct zfcp_port *port, int result)
 static int
 static int
 zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, int result)
 zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, int result)
 {
 {
-	debug_text_event(adapter->erp_dbf, 5, "a_stct");
-
 	switch (result) {
 	switch (result) {
 	case ZFCP_ERP_SUCCEEDED :
 	case ZFCP_ERP_SUCCEEDED :
 		atomic_set(&adapter->erp_counter, 0);
 		atomic_set(&adapter->erp_counter, 0);
@@ -1575,7 +1505,7 @@ zfcp_erp_strategy_check_adapter(struct zfcp_adapter *adapter, int result)
 	case ZFCP_ERP_FAILED :
 	case ZFCP_ERP_FAILED :
 		atomic_inc(&adapter->erp_counter);
 		atomic_inc(&adapter->erp_counter);
 		if (atomic_read(&adapter->erp_counter) > ZFCP_MAX_ERPS)
 		if (atomic_read(&adapter->erp_counter) > ZFCP_MAX_ERPS)
-			zfcp_erp_adapter_failed(adapter);
+			zfcp_erp_adapter_failed(adapter, 23, NULL);
 		break;
 		break;
 	case ZFCP_ERP_EXIT :
 	case ZFCP_ERP_EXIT :
 		/* nothing */
 		/* nothing */
@@ -1658,37 +1588,34 @@ zfcp_erp_strategy_followup_actions(int action,
 				   struct zfcp_port *port,
 				   struct zfcp_port *port,
 				   struct zfcp_unit *unit, int status)
 				   struct zfcp_unit *unit, int status)
 {
 {
-	debug_text_event(adapter->erp_dbf, 5, "a_stfol");
-	debug_event(adapter->erp_dbf, 5, &action, sizeof (int));
-
 	/* initiate follow-up actions depending on success of finished action */
 	/* initiate follow-up actions depending on success of finished action */
 	switch (action) {
 	switch (action) {
 
 
 	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
 	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
 		if (status == ZFCP_ERP_SUCCEEDED)
 		if (status == ZFCP_ERP_SUCCEEDED)
-			zfcp_erp_port_reopen_all_internal(adapter, 0);
+			zfcp_erp_port_reopen_all_internal(adapter, 0, 70, NULL);
 		else
 		else
-			zfcp_erp_adapter_reopen_internal(adapter, 0);
+			zfcp_erp_adapter_reopen_internal(adapter, 0, 71, NULL);
 		break;
 		break;
 
 
 	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
 	case ZFCP_ERP_ACTION_REOPEN_PORT_FORCED:
 		if (status == ZFCP_ERP_SUCCEEDED)
 		if (status == ZFCP_ERP_SUCCEEDED)
-			zfcp_erp_port_reopen_internal(port, 0);
+			zfcp_erp_port_reopen_internal(port, 0, 72, NULL);
 		else
 		else
-			zfcp_erp_adapter_reopen_internal(adapter, 0);
+			zfcp_erp_adapter_reopen_internal(adapter, 0, 73, NULL);
 		break;
 		break;
 
 
 	case ZFCP_ERP_ACTION_REOPEN_PORT:
 	case ZFCP_ERP_ACTION_REOPEN_PORT:
 		if (status == ZFCP_ERP_SUCCEEDED)
 		if (status == ZFCP_ERP_SUCCEEDED)
-			zfcp_erp_unit_reopen_all_internal(port, 0);
+			zfcp_erp_unit_reopen_all_internal(port, 0, 74, NULL);
 		else
 		else
-			zfcp_erp_port_forced_reopen_internal(port, 0);
+			zfcp_erp_port_forced_reopen_internal(port, 0, 75, NULL);
 		break;
 		break;
 
 
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
 		/* Nothing to do if status == ZFCP_ERP_SUCCEEDED */
 		/* Nothing to do if status == ZFCP_ERP_SUCCEEDED */
 		if (status != ZFCP_ERP_SUCCEEDED)
 		if (status != ZFCP_ERP_SUCCEEDED)
-			zfcp_erp_port_reopen_internal(unit->port, 0);
+			zfcp_erp_port_reopen_internal(unit->port, 0, 76, NULL);
 		break;
 		break;
 	}
 	}
 
 
@@ -1704,12 +1631,10 @@ zfcp_erp_strategy_check_queues(struct zfcp_adapter *adapter)
 	read_lock(&adapter->erp_lock);
 	read_lock(&adapter->erp_lock);
 	if (list_empty(&adapter->erp_ready_head) &&
 	if (list_empty(&adapter->erp_ready_head) &&
 	    list_empty(&adapter->erp_running_head)) {
 	    list_empty(&adapter->erp_running_head)) {
-			debug_text_event(adapter->erp_dbf, 4, "a_cq_wake");
 			atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING,
 			atomic_clear_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING,
 					  &adapter->status);
 					  &adapter->status);
 			wake_up(&adapter->erp_done_wqh);
 			wake_up(&adapter->erp_done_wqh);
-	} else
-		debug_text_event(adapter->erp_dbf, 5, "a_cq_notempty");
+	}
 	read_unlock(&adapter->erp_lock);
 	read_unlock(&adapter->erp_lock);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 
 
@@ -1733,29 +1658,27 @@ zfcp_erp_wait(struct zfcp_adapter *adapter)
 	return retval;
 	return retval;
 }
 }
 
 
-void
-zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter,
-			       u32 mask, int set_or_clear)
+void zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter, u8 id,
+				    void *ref, u32 mask, int set_or_clear)
 {
 {
 	struct zfcp_port *port;
 	struct zfcp_port *port;
-	u32 common_mask = mask & ZFCP_COMMON_FLAGS;
+	u32 changed, common_mask = mask & ZFCP_COMMON_FLAGS;
 
 
 	if (set_or_clear == ZFCP_SET) {
 	if (set_or_clear == ZFCP_SET) {
-		atomic_set_mask(mask, &adapter->status);
-		debug_text_event(adapter->erp_dbf, 3, "a_mod_as_s");
+		changed = atomic_test_and_set_mask(mask, &adapter->status);
 	} else {
 	} else {
-		atomic_clear_mask(mask, &adapter->status);
+		changed = atomic_test_and_clear_mask(mask, &adapter->status);
 		if (mask & ZFCP_STATUS_COMMON_ERP_FAILED)
 		if (mask & ZFCP_STATUS_COMMON_ERP_FAILED)
 			atomic_set(&adapter->erp_counter, 0);
 			atomic_set(&adapter->erp_counter, 0);
-		debug_text_event(adapter->erp_dbf, 3, "a_mod_as_c");
 	}
 	}
-	debug_event(adapter->erp_dbf, 3, &mask, sizeof (u32));
+	if (changed)
+		zfcp_rec_dbf_event_adapter(id, ref, adapter);
 
 
 	/* Deal with all underlying devices, only pass common_mask */
 	/* Deal with all underlying devices, only pass common_mask */
 	if (common_mask)
 	if (common_mask)
 		list_for_each_entry(port, &adapter->port_list_head, list)
 		list_for_each_entry(port, &adapter->port_list_head, list)
-		    zfcp_erp_modify_port_status(port, common_mask,
-						set_or_clear);
+			zfcp_erp_modify_port_status(port, id, ref, common_mask,
+						    set_or_clear);
 }
 }
 
 
 /*
 /*
@@ -1764,29 +1687,27 @@ zfcp_erp_modify_adapter_status(struct zfcp_adapter *adapter,
  * purpose:	sets the port and all underlying devices to ERP_FAILED
  * purpose:	sets the port and all underlying devices to ERP_FAILED
  *
  *
  */
  */
-void
-zfcp_erp_modify_port_status(struct zfcp_port *port, u32 mask, int set_or_clear)
+void zfcp_erp_modify_port_status(struct zfcp_port *port, u8 id, void *ref,
+				 u32 mask, int set_or_clear)
 {
 {
 	struct zfcp_unit *unit;
 	struct zfcp_unit *unit;
-	u32 common_mask = mask & ZFCP_COMMON_FLAGS;
+	u32 changed, common_mask = mask & ZFCP_COMMON_FLAGS;
 
 
 	if (set_or_clear == ZFCP_SET) {
 	if (set_or_clear == ZFCP_SET) {
-		atomic_set_mask(mask, &port->status);
-		debug_text_event(port->adapter->erp_dbf, 3, "p_mod_ps_s");
+		changed = atomic_test_and_set_mask(mask, &port->status);
 	} else {
 	} else {
-		atomic_clear_mask(mask, &port->status);
+		changed = atomic_test_and_clear_mask(mask, &port->status);
 		if (mask & ZFCP_STATUS_COMMON_ERP_FAILED)
 		if (mask & ZFCP_STATUS_COMMON_ERP_FAILED)
 			atomic_set(&port->erp_counter, 0);
 			atomic_set(&port->erp_counter, 0);
-		debug_text_event(port->adapter->erp_dbf, 3, "p_mod_ps_c");
 	}
 	}
-	debug_event(port->adapter->erp_dbf, 3, &port->wwpn, sizeof (wwn_t));
-	debug_event(port->adapter->erp_dbf, 3, &mask, sizeof (u32));
+	if (changed)
+		zfcp_rec_dbf_event_port(id, ref, port);
 
 
 	/* Modify status of all underlying devices, only pass common mask */
 	/* Modify status of all underlying devices, only pass common mask */
 	if (common_mask)
 	if (common_mask)
 		list_for_each_entry(unit, &port->unit_list_head, list)
 		list_for_each_entry(unit, &port->unit_list_head, list)
-		    zfcp_erp_modify_unit_status(unit, common_mask,
-						set_or_clear);
+			zfcp_erp_modify_unit_status(unit, id, ref, common_mask,
+						    set_or_clear);
 }
 }
 
 
 /*
 /*
@@ -1795,22 +1716,21 @@ zfcp_erp_modify_port_status(struct zfcp_port *port, u32 mask, int set_or_clear)
  * purpose:	sets the unit to ERP_FAILED
  * purpose:	sets the unit to ERP_FAILED
  *
  *
  */
  */
-void
-zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u32 mask, int set_or_clear)
+void zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u8 id, void *ref,
+				 u32 mask, int set_or_clear)
 {
 {
+	u32 changed;
+
 	if (set_or_clear == ZFCP_SET) {
 	if (set_or_clear == ZFCP_SET) {
-		atomic_set_mask(mask, &unit->status);
-		debug_text_event(unit->port->adapter->erp_dbf, 3, "u_mod_us_s");
+		changed = atomic_test_and_set_mask(mask, &unit->status);
 	} else {
 	} else {
-		atomic_clear_mask(mask, &unit->status);
+		changed = atomic_test_and_clear_mask(mask, &unit->status);
 		if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) {
 		if (mask & ZFCP_STATUS_COMMON_ERP_FAILED) {
 			atomic_set(&unit->erp_counter, 0);
 			atomic_set(&unit->erp_counter, 0);
 		}
 		}
-		debug_text_event(unit->port->adapter->erp_dbf, 3, "u_mod_us_c");
 	}
 	}
-	debug_event(unit->port->adapter->erp_dbf, 3, &unit->fcp_lun,
-		    sizeof (fcp_lun_t));
-	debug_event(unit->port->adapter->erp_dbf, 3, &mask, sizeof (u32));
+	if (changed)
+		zfcp_rec_dbf_event_unit(id, ref, unit);
 }
 }
 
 
 /*
 /*
@@ -1822,30 +1742,32 @@ zfcp_erp_modify_unit_status(struct zfcp_unit *unit, u32 mask, int set_or_clear)
  * returns:	0	- initiated action successfully
  * returns:	0	- initiated action successfully
  *		<0	- failed to initiate action
  *		<0	- failed to initiate action
  */
  */
-int
-zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, int clear_mask)
+int zfcp_erp_port_reopen_all(struct zfcp_adapter *adapter, int clear_mask,
+			     u8 id, void *ref)
 {
 {
 	int retval;
 	int retval;
 	unsigned long flags;
 	unsigned long flags;
 
 
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	write_lock(&adapter->erp_lock);
 	write_lock(&adapter->erp_lock);
-	retval = zfcp_erp_port_reopen_all_internal(adapter, clear_mask);
+	retval = zfcp_erp_port_reopen_all_internal(adapter, clear_mask, id,
+						   ref);
 	write_unlock(&adapter->erp_lock);
 	write_unlock(&adapter->erp_lock);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 
 
 	return retval;
 	return retval;
 }
 }
 
 
-static int
-zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *adapter, int clear_mask)
+static int zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *adapter,
+					     int clear_mask, u8 id, void *ref)
 {
 {
 	int retval = 0;
 	int retval = 0;
 	struct zfcp_port *port;
 	struct zfcp_port *port;
 
 
 	list_for_each_entry(port, &adapter->port_list_head, list)
 	list_for_each_entry(port, &adapter->port_list_head, list)
 		if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
 		if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
-			zfcp_erp_port_reopen_internal(port, clear_mask);
+			zfcp_erp_port_reopen_internal(port, clear_mask, id,
+						      ref);
 
 
 	return retval;
 	return retval;
 }
 }
@@ -1857,14 +1779,14 @@ zfcp_erp_port_reopen_all_internal(struct zfcp_adapter *adapter, int clear_mask)
  *
  *
  * returns:	FIXME
  * returns:	FIXME
  */
  */
-static int
-zfcp_erp_unit_reopen_all_internal(struct zfcp_port *port, int clear_mask)
+static int zfcp_erp_unit_reopen_all_internal(struct zfcp_port *port,
+					     int clear_mask, u8 id, void *ref)
 {
 {
 	int retval = 0;
 	int retval = 0;
 	struct zfcp_unit *unit;
 	struct zfcp_unit *unit;
 
 
 	list_for_each_entry(unit, &port->unit_list_head, list)
 	list_for_each_entry(unit, &port->unit_list_head, list)
-	    zfcp_erp_unit_reopen_internal(unit, clear_mask);
+		zfcp_erp_unit_reopen_internal(unit, clear_mask, id, ref);
 
 
 	return retval;
 	return retval;
 }
 }
@@ -1892,10 +1814,6 @@ zfcp_erp_adapter_strategy(struct zfcp_erp_action *erp_action)
 	else
 	else
 		retval = zfcp_erp_adapter_strategy_open(erp_action);
 		retval = zfcp_erp_adapter_strategy_open(erp_action);
 
 
-	debug_text_event(adapter->erp_dbf, 3, "a_ast/ret");
-	debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int));
-	debug_event(adapter->erp_dbf, 3, &retval, sizeof (int));
-
 	if (retval == ZFCP_ERP_FAILED) {
 	if (retval == ZFCP_ERP_FAILED) {
 		ZFCP_LOG_INFO("Waiting to allow the adapter %s "
 		ZFCP_LOG_INFO("Waiting to allow the adapter %s "
 			      "to recover itself\n",
 			      "to recover itself\n",
@@ -2021,7 +1939,6 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
 			      zfcp_get_busid_by_adapter(adapter));
 			      zfcp_get_busid_by_adapter(adapter));
 		goto failed_qdio_establish;
 		goto failed_qdio_establish;
 	}
 	}
-	debug_text_event(adapter->erp_dbf, 3, "qdio_est");
 
 
 	if (qdio_activate(adapter->ccw_device, 0) != 0) {
 	if (qdio_activate(adapter->ccw_device, 0) != 0) {
 		ZFCP_LOG_INFO("error: activation of QDIO queues failed "
 		ZFCP_LOG_INFO("error: activation of QDIO queues failed "
@@ -2029,7 +1946,6 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
 			      zfcp_get_busid_by_adapter(adapter));
 			      zfcp_get_busid_by_adapter(adapter));
 		goto failed_qdio_activate;
 		goto failed_qdio_activate;
 	}
 	}
-	debug_text_event(adapter->erp_dbf, 3, "qdio_act");
 
 
 	/*
 	/*
 	 * put buffers into response queue,
 	 * put buffers into response queue,
@@ -2077,11 +1993,9 @@ zfcp_erp_adapter_strategy_open_qdio(struct zfcp_erp_action *erp_action)
 	/* NOP */
 	/* NOP */
 
 
  failed_qdio_activate:
  failed_qdio_activate:
-	debug_text_event(adapter->erp_dbf, 3, "qdio_down1a");
 	while (qdio_shutdown(adapter->ccw_device,
 	while (qdio_shutdown(adapter->ccw_device,
 			     QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS)
 			     QDIO_FLAG_CLEANUP_USING_CLEAR) == -EINPROGRESS)
 		ssleep(1);
 		ssleep(1);
-	debug_text_event(adapter->erp_dbf, 3, "qdio_down1b");
 
 
  failed_qdio_establish:
  failed_qdio_establish:
  failed_sanity:
  failed_sanity:
@@ -2127,14 +2041,12 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
 		write_unlock_irq(&adapter->erp_lock);
 		write_unlock_irq(&adapter->erp_lock);
 		if (zfcp_fsf_exchange_config_data(erp_action)) {
 		if (zfcp_fsf_exchange_config_data(erp_action)) {
 			retval = ZFCP_ERP_FAILED;
 			retval = ZFCP_ERP_FAILED;
-			debug_text_event(adapter->erp_dbf, 5, "a_fstx_xf");
 			ZFCP_LOG_INFO("error:  initiation of exchange of "
 			ZFCP_LOG_INFO("error:  initiation of exchange of "
 				      "configuration data failed for "
 				      "configuration data failed for "
 				      "adapter %s\n",
 				      "adapter %s\n",
 				      zfcp_get_busid_by_adapter(adapter));
 				      zfcp_get_busid_by_adapter(adapter));
 			break;
 			break;
 		}
 		}
-		debug_text_event(adapter->erp_dbf, 6, "a_fstx_xok");
 		ZFCP_LOG_DEBUG("Xchange underway\n");
 		ZFCP_LOG_DEBUG("Xchange underway\n");
 
 
 		/*
 		/*
@@ -2150,7 +2062,9 @@ zfcp_erp_adapter_strategy_open_fsf_xconfig(struct zfcp_erp_action *erp_action)
 		 * _must_ be the one belonging to the 'exchange config
 		 * _must_ be the one belonging to the 'exchange config
 		 * data' request.
 		 * data' request.
 		 */
 		 */
+		zfcp_rec_dbf_event_thread(6, adapter, 1);
 		down(&adapter->erp_ready_sem);
 		down(&adapter->erp_ready_sem);
+		zfcp_rec_dbf_event_thread(7, adapter, 1);
 		if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
 		if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
 			ZFCP_LOG_INFO("error: exchange of configuration data "
 			ZFCP_LOG_INFO("error: exchange of configuration data "
 				      "for adapter %s timed out\n",
 				      "for adapter %s timed out\n",
@@ -2198,16 +2112,15 @@ zfcp_erp_adapter_strategy_open_fsf_xport(struct zfcp_erp_action *erp_action)
 
 
 	ret = zfcp_fsf_exchange_port_data(erp_action);
 	ret = zfcp_fsf_exchange_port_data(erp_action);
 	if (ret == -EOPNOTSUPP) {
 	if (ret == -EOPNOTSUPP) {
-		debug_text_event(adapter->erp_dbf, 3, "a_xport_notsupp");
 		return ZFCP_ERP_SUCCEEDED;
 		return ZFCP_ERP_SUCCEEDED;
 	} else if (ret) {
 	} else if (ret) {
-		debug_text_event(adapter->erp_dbf, 3, "a_xport_failed");
 		return ZFCP_ERP_FAILED;
 		return ZFCP_ERP_FAILED;
 	}
 	}
-	debug_text_event(adapter->erp_dbf, 6, "a_xport_ok");
 
 
 	ret = ZFCP_ERP_SUCCEEDED;
 	ret = ZFCP_ERP_SUCCEEDED;
+	zfcp_rec_dbf_event_thread(8, adapter, 1);
 	down(&adapter->erp_ready_sem);
 	down(&adapter->erp_ready_sem);
+	zfcp_rec_dbf_event_thread(9, adapter, 1);
 	if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
 	if (erp_action->status & ZFCP_STATUS_ERP_TIMEDOUT) {
 		ZFCP_LOG_INFO("error: exchange port data timed out (adapter "
 		ZFCP_LOG_INFO("error: exchange port data timed out (adapter "
 			      "%s)\n", zfcp_get_busid_by_adapter(adapter));
 			      "%s)\n", zfcp_get_busid_by_adapter(adapter));
@@ -2261,7 +2174,6 @@ zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action)
 {
 {
 	int retval = ZFCP_ERP_FAILED;
 	int retval = ZFCP_ERP_FAILED;
 	struct zfcp_port *port = erp_action->port;
 	struct zfcp_port *port = erp_action->port;
-	struct zfcp_adapter *adapter = erp_action->adapter;
 
 
 	switch (erp_action->step) {
 	switch (erp_action->step) {
 
 
@@ -2298,11 +2210,6 @@ zfcp_erp_port_forced_strategy(struct zfcp_erp_action *erp_action)
 		break;
 		break;
 	}
 	}
 
 
-	debug_text_event(adapter->erp_dbf, 3, "p_pfst/ret");
-	debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof (wwn_t));
-	debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int));
-	debug_event(adapter->erp_dbf, 3, &retval, sizeof (int));
-
 	return retval;
 	return retval;
 }
 }
 
 
@@ -2320,7 +2227,6 @@ zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action)
 {
 {
 	int retval = ZFCP_ERP_FAILED;
 	int retval = ZFCP_ERP_FAILED;
 	struct zfcp_port *port = erp_action->port;
 	struct zfcp_port *port = erp_action->port;
-	struct zfcp_adapter *adapter = erp_action->adapter;
 
 
 	switch (erp_action->step) {
 	switch (erp_action->step) {
 
 
@@ -2353,11 +2259,6 @@ zfcp_erp_port_strategy(struct zfcp_erp_action *erp_action)
 		retval = zfcp_erp_port_strategy_open(erp_action);
 		retval = zfcp_erp_port_strategy_open(erp_action);
 
 
  out:
  out:
-	debug_text_event(adapter->erp_dbf, 3, "p_pst/ret");
-	debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof (wwn_t));
-	debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int));
-	debug_event(adapter->erp_dbf, 3, &retval, sizeof (int));
-
 	return retval;
 	return retval;
 }
 }
 
 
@@ -2395,7 +2296,7 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action)
 						port->wwpn,
 						port->wwpn,
 						zfcp_get_busid_by_adapter(adapter),
 						zfcp_get_busid_by_adapter(adapter),
 						adapter->peer_wwpn);
 						adapter->peer_wwpn);
-				zfcp_erp_port_failed(port);
+				zfcp_erp_port_failed(port, 25, NULL);
 				retval = ZFCP_ERP_FAILED;
 				retval = ZFCP_ERP_FAILED;
 				break;
 				break;
 			}
 			}
@@ -2421,8 +2322,8 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action)
 			/* nameserver port may live again */
 			/* nameserver port may live again */
 			atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING,
 			atomic_set_mask(ZFCP_STATUS_COMMON_RUNNING,
 					&adapter->nameserver_port->status);
 					&adapter->nameserver_port->status);
-			if (zfcp_erp_port_reopen(adapter->nameserver_port, 0)
-			    >= 0) {
+			if (zfcp_erp_port_reopen(adapter->nameserver_port, 0,
+						 77, erp_action) >= 0) {
 				erp_action->step =
 				erp_action->step =
 					ZFCP_ERP_STEP_NAMESERVER_OPEN;
 					ZFCP_ERP_STEP_NAMESERVER_OPEN;
 				retval = ZFCP_ERP_CONTINUES;
 				retval = ZFCP_ERP_CONTINUES;
@@ -2453,7 +2354,7 @@ zfcp_erp_port_strategy_open_common(struct zfcp_erp_action *erp_action)
 					       "for port 0x%016Lx "
 					       "for port 0x%016Lx "
 					       "(misconfigured WWPN?)\n",
 					       "(misconfigured WWPN?)\n",
 					       port->wwpn);
 					       port->wwpn);
-				zfcp_erp_port_failed(port);
+				zfcp_erp_port_failed(port, 26, NULL);
 				retval = ZFCP_ERP_EXIT;
 				retval = ZFCP_ERP_EXIT;
 			} else {
 			} else {
 				ZFCP_LOG_DEBUG("nameserver look-up failed for "
 				ZFCP_LOG_DEBUG("nameserver look-up failed for "
@@ -2549,17 +2450,12 @@ zfcp_erp_port_strategy_open_nameserver_wakeup(struct zfcp_erp_action
 	read_lock_irqsave(&adapter->erp_lock, flags);
 	read_lock_irqsave(&adapter->erp_lock, flags);
 	list_for_each_entry_safe(erp_action, tmp, &adapter->erp_running_head,
 	list_for_each_entry_safe(erp_action, tmp, &adapter->erp_running_head,
 				 list) {
 				 list) {
-		debug_text_event(adapter->erp_dbf, 4, "p_pstnsw_n");
-		debug_event(adapter->erp_dbf, 4, &erp_action->port->wwpn,
-			    sizeof (wwn_t));
 		if (erp_action->step == ZFCP_ERP_STEP_NAMESERVER_OPEN) {
 		if (erp_action->step == ZFCP_ERP_STEP_NAMESERVER_OPEN) {
-			debug_text_event(adapter->erp_dbf, 3, "p_pstnsw_w");
-			debug_event(adapter->erp_dbf, 3,
-				    &erp_action->port->wwpn, sizeof (wwn_t));
 			if (atomic_test_mask(
 			if (atomic_test_mask(
 				    ZFCP_STATUS_COMMON_ERP_FAILED,
 				    ZFCP_STATUS_COMMON_ERP_FAILED,
 				    &adapter->nameserver_port->status))
 				    &adapter->nameserver_port->status))
-				zfcp_erp_port_failed(erp_action->port);
+				zfcp_erp_port_failed(erp_action->port, 27,
+						     NULL);
 			zfcp_erp_action_ready(erp_action);
 			zfcp_erp_action_ready(erp_action);
 		}
 		}
 	}
 	}
@@ -2580,26 +2476,18 @@ static int
 zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *erp_action)
 zfcp_erp_port_forced_strategy_close(struct zfcp_erp_action *erp_action)
 {
 {
 	int retval;
 	int retval;
-	struct zfcp_adapter *adapter = erp_action->adapter;
-	struct zfcp_port *port = erp_action->port;
 
 
 	retval = zfcp_fsf_close_physical_port(erp_action);
 	retval = zfcp_fsf_close_physical_port(erp_action);
 	if (retval == -ENOMEM) {
 	if (retval == -ENOMEM) {
-		debug_text_event(adapter->erp_dbf, 5, "o_pfstc_nomem");
-		debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
 		retval = ZFCP_ERP_NOMEM;
 		retval = ZFCP_ERP_NOMEM;
 		goto out;
 		goto out;
 	}
 	}
 	erp_action->step = ZFCP_ERP_STEP_PHYS_PORT_CLOSING;
 	erp_action->step = ZFCP_ERP_STEP_PHYS_PORT_CLOSING;
 	if (retval != 0) {
 	if (retval != 0) {
-		debug_text_event(adapter->erp_dbf, 5, "o_pfstc_cpf");
-		debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
 		/* could not send 'open', fail */
 		/* could not send 'open', fail */
 		retval = ZFCP_ERP_FAILED;
 		retval = ZFCP_ERP_FAILED;
 		goto out;
 		goto out;
 	}
 	}
-	debug_text_event(adapter->erp_dbf, 6, "o_pfstc_cpok");
-	debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));
 	retval = ZFCP_ERP_CONTINUES;
 	retval = ZFCP_ERP_CONTINUES;
  out:
  out:
 	return retval;
 	return retval;
@@ -2609,10 +2497,6 @@ static int
 zfcp_erp_port_strategy_clearstati(struct zfcp_port *port)
 zfcp_erp_port_strategy_clearstati(struct zfcp_port *port)
 {
 {
 	int retval = 0;
 	int retval = 0;
-	struct zfcp_adapter *adapter = port->adapter;
-
-	debug_text_event(adapter->erp_dbf, 5, "p_pstclst");
-	debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
 
 
 	atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING |
 	atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING |
 			  ZFCP_STATUS_COMMON_CLOSING |
 			  ZFCP_STATUS_COMMON_CLOSING |
@@ -2636,26 +2520,18 @@ static int
 zfcp_erp_port_strategy_close(struct zfcp_erp_action *erp_action)
 zfcp_erp_port_strategy_close(struct zfcp_erp_action *erp_action)
 {
 {
 	int retval;
 	int retval;
-	struct zfcp_adapter *adapter = erp_action->adapter;
-	struct zfcp_port *port = erp_action->port;
 
 
 	retval = zfcp_fsf_close_port(erp_action);
 	retval = zfcp_fsf_close_port(erp_action);
 	if (retval == -ENOMEM) {
 	if (retval == -ENOMEM) {
-		debug_text_event(adapter->erp_dbf, 5, "p_pstc_nomem");
-		debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
 		retval = ZFCP_ERP_NOMEM;
 		retval = ZFCP_ERP_NOMEM;
 		goto out;
 		goto out;
 	}
 	}
 	erp_action->step = ZFCP_ERP_STEP_PORT_CLOSING;
 	erp_action->step = ZFCP_ERP_STEP_PORT_CLOSING;
 	if (retval != 0) {
 	if (retval != 0) {
-		debug_text_event(adapter->erp_dbf, 5, "p_pstc_cpf");
-		debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
 		/* could not send 'close', fail */
 		/* could not send 'close', fail */
 		retval = ZFCP_ERP_FAILED;
 		retval = ZFCP_ERP_FAILED;
 		goto out;
 		goto out;
 	}
 	}
-	debug_text_event(adapter->erp_dbf, 6, "p_pstc_cpok");
-	debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));
 	retval = ZFCP_ERP_CONTINUES;
 	retval = ZFCP_ERP_CONTINUES;
  out:
  out:
 	return retval;
 	return retval;
@@ -2673,26 +2549,18 @@ static int
 zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action)
 zfcp_erp_port_strategy_open_port(struct zfcp_erp_action *erp_action)
 {
 {
 	int retval;
 	int retval;
-	struct zfcp_adapter *adapter = erp_action->adapter;
-	struct zfcp_port *port = erp_action->port;
 
 
 	retval = zfcp_fsf_open_port(erp_action);
 	retval = zfcp_fsf_open_port(erp_action);
 	if (retval == -ENOMEM) {
 	if (retval == -ENOMEM) {
-		debug_text_event(adapter->erp_dbf, 5, "p_psto_nomem");
-		debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
 		retval = ZFCP_ERP_NOMEM;
 		retval = ZFCP_ERP_NOMEM;
 		goto out;
 		goto out;
 	}
 	}
 	erp_action->step = ZFCP_ERP_STEP_PORT_OPENING;
 	erp_action->step = ZFCP_ERP_STEP_PORT_OPENING;
 	if (retval != 0) {
 	if (retval != 0) {
-		debug_text_event(adapter->erp_dbf, 5, "p_psto_opf");
-		debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
 		/* could not send 'open', fail */
 		/* could not send 'open', fail */
 		retval = ZFCP_ERP_FAILED;
 		retval = ZFCP_ERP_FAILED;
 		goto out;
 		goto out;
 	}
 	}
-	debug_text_event(adapter->erp_dbf, 6, "p_psto_opok");
-	debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));
 	retval = ZFCP_ERP_CONTINUES;
 	retval = ZFCP_ERP_CONTINUES;
  out:
  out:
 	return retval;
 	return retval;
@@ -2710,26 +2578,18 @@ static int
 zfcp_erp_port_strategy_open_common_lookup(struct zfcp_erp_action *erp_action)
 zfcp_erp_port_strategy_open_common_lookup(struct zfcp_erp_action *erp_action)
 {
 {
 	int retval;
 	int retval;
-	struct zfcp_adapter *adapter = erp_action->adapter;
-	struct zfcp_port *port = erp_action->port;
 
 
 	retval = zfcp_ns_gid_pn_request(erp_action);
 	retval = zfcp_ns_gid_pn_request(erp_action);
 	if (retval == -ENOMEM) {
 	if (retval == -ENOMEM) {
-		debug_text_event(adapter->erp_dbf, 5, "p_pstn_nomem");
-		debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
 		retval = ZFCP_ERP_NOMEM;
 		retval = ZFCP_ERP_NOMEM;
 		goto out;
 		goto out;
 	}
 	}
 	erp_action->step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP;
 	erp_action->step = ZFCP_ERP_STEP_NAMESERVER_LOOKUP;
 	if (retval != 0) {
 	if (retval != 0) {
-		debug_text_event(adapter->erp_dbf, 5, "p_pstn_ref");
-		debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
 		/* could not send nameserver request, fail */
 		/* could not send nameserver request, fail */
 		retval = ZFCP_ERP_FAILED;
 		retval = ZFCP_ERP_FAILED;
 		goto out;
 		goto out;
 	}
 	}
-	debug_text_event(adapter->erp_dbf, 6, "p_pstn_reok");
-	debug_event(adapter->erp_dbf, 6, &port->wwpn, sizeof (wwn_t));
 	retval = ZFCP_ERP_CONTINUES;
 	retval = ZFCP_ERP_CONTINUES;
  out:
  out:
 	return retval;
 	return retval;
@@ -2750,7 +2610,6 @@ zfcp_erp_unit_strategy(struct zfcp_erp_action *erp_action)
 {
 {
 	int retval = ZFCP_ERP_FAILED;
 	int retval = ZFCP_ERP_FAILED;
 	struct zfcp_unit *unit = erp_action->unit;
 	struct zfcp_unit *unit = erp_action->unit;
-	struct zfcp_adapter *adapter = erp_action->adapter;
 
 
 	switch (erp_action->step) {
 	switch (erp_action->step) {
 
 
@@ -2797,10 +2656,6 @@ zfcp_erp_unit_strategy(struct zfcp_erp_action *erp_action)
 		break;
 		break;
 	}
 	}
 
 
-	debug_text_event(adapter->erp_dbf, 3, "u_ust/ret");
-	debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof (fcp_lun_t));
-	debug_event(adapter->erp_dbf, 3, &erp_action->action, sizeof (int));
-	debug_event(adapter->erp_dbf, 3, &retval, sizeof (int));
 	return retval;
 	return retval;
 }
 }
 
 
@@ -2808,10 +2663,6 @@ static int
 zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit)
 zfcp_erp_unit_strategy_clearstati(struct zfcp_unit *unit)
 {
 {
 	int retval = 0;
 	int retval = 0;
-	struct zfcp_adapter *adapter = unit->port->adapter;
-
-	debug_text_event(adapter->erp_dbf, 5, "u_ustclst");
-	debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, sizeof (fcp_lun_t));
 
 
 	atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING |
 	atomic_clear_mask(ZFCP_STATUS_COMMON_OPENING |
 			  ZFCP_STATUS_COMMON_CLOSING |
 			  ZFCP_STATUS_COMMON_CLOSING |
@@ -2835,28 +2686,18 @@ static int
 zfcp_erp_unit_strategy_close(struct zfcp_erp_action *erp_action)
 zfcp_erp_unit_strategy_close(struct zfcp_erp_action *erp_action)
 {
 {
 	int retval;
 	int retval;
-	struct zfcp_adapter *adapter = erp_action->adapter;
-	struct zfcp_unit *unit = erp_action->unit;
 
 
 	retval = zfcp_fsf_close_unit(erp_action);
 	retval = zfcp_fsf_close_unit(erp_action);
 	if (retval == -ENOMEM) {
 	if (retval == -ENOMEM) {
-		debug_text_event(adapter->erp_dbf, 5, "u_ustc_nomem");
-		debug_event(adapter->erp_dbf, 5, &unit->fcp_lun,
-			    sizeof (fcp_lun_t));
 		retval = ZFCP_ERP_NOMEM;
 		retval = ZFCP_ERP_NOMEM;
 		goto out;
 		goto out;
 	}
 	}
 	erp_action->step = ZFCP_ERP_STEP_UNIT_CLOSING;
 	erp_action->step = ZFCP_ERP_STEP_UNIT_CLOSING;
 	if (retval != 0) {
 	if (retval != 0) {
-		debug_text_event(adapter->erp_dbf, 5, "u_ustc_cuf");
-		debug_event(adapter->erp_dbf, 5, &unit->fcp_lun,
-			    sizeof (fcp_lun_t));
 		/* could not send 'close', fail */
 		/* could not send 'close', fail */
 		retval = ZFCP_ERP_FAILED;
 		retval = ZFCP_ERP_FAILED;
 		goto out;
 		goto out;
 	}
 	}
-	debug_text_event(adapter->erp_dbf, 6, "u_ustc_cuok");
-	debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t));
 	retval = ZFCP_ERP_CONTINUES;
 	retval = ZFCP_ERP_CONTINUES;
 
 
  out:
  out:
@@ -2875,28 +2716,18 @@ static int
 zfcp_erp_unit_strategy_open(struct zfcp_erp_action *erp_action)
 zfcp_erp_unit_strategy_open(struct zfcp_erp_action *erp_action)
 {
 {
 	int retval;
 	int retval;
-	struct zfcp_adapter *adapter = erp_action->adapter;
-	struct zfcp_unit *unit = erp_action->unit;
 
 
 	retval = zfcp_fsf_open_unit(erp_action);
 	retval = zfcp_fsf_open_unit(erp_action);
 	if (retval == -ENOMEM) {
 	if (retval == -ENOMEM) {
-		debug_text_event(adapter->erp_dbf, 5, "u_usto_nomem");
-		debug_event(adapter->erp_dbf, 5, &unit->fcp_lun,
-			    sizeof (fcp_lun_t));
 		retval = ZFCP_ERP_NOMEM;
 		retval = ZFCP_ERP_NOMEM;
 		goto out;
 		goto out;
 	}
 	}
 	erp_action->step = ZFCP_ERP_STEP_UNIT_OPENING;
 	erp_action->step = ZFCP_ERP_STEP_UNIT_OPENING;
 	if (retval != 0) {
 	if (retval != 0) {
-		debug_text_event(adapter->erp_dbf, 5, "u_usto_ouf");
-		debug_event(adapter->erp_dbf, 5, &unit->fcp_lun,
-			    sizeof (fcp_lun_t));
 		/* could not send 'open', fail */
 		/* could not send 'open', fail */
 		retval = ZFCP_ERP_FAILED;
 		retval = ZFCP_ERP_FAILED;
 		goto out;
 		goto out;
 	}
 	}
-	debug_text_event(adapter->erp_dbf, 6, "u_usto_ouok");
-	debug_event(adapter->erp_dbf, 6, &unit->fcp_lun, sizeof (fcp_lun_t));
 	retval = ZFCP_ERP_CONTINUES;
 	retval = ZFCP_ERP_CONTINUES;
  out:
  out:
 	return retval;
 	return retval;
@@ -2918,14 +2749,12 @@ void zfcp_erp_start_timer(struct zfcp_fsf_req *fsf_req)
  *
  *
  * returns:
  * returns:
  */
  */
-static int
-zfcp_erp_action_enqueue(int action,
-			struct zfcp_adapter *adapter,
-			struct zfcp_port *port, struct zfcp_unit *unit)
+static int zfcp_erp_action_enqueue(int want, struct zfcp_adapter *adapter,
+				   struct zfcp_port *port,
+				   struct zfcp_unit *unit, u8 id, void *ref)
 {
 {
-	int retval = 1;
+	int retval = 1, need = want;
 	struct zfcp_erp_action *erp_action = NULL;
 	struct zfcp_erp_action *erp_action = NULL;
-	int stronger_action = 0;
 	u32 status = 0;
 	u32 status = 0;
 
 
 	/*
 	/*
@@ -2944,17 +2773,11 @@ zfcp_erp_action_enqueue(int action,
 			      &adapter->status))
 			      &adapter->status))
 		return -EIO;
 		return -EIO;
 
 
-	debug_event(adapter->erp_dbf, 4, &action, sizeof (int));
 	/* check whether we really need this */
 	/* check whether we really need this */
-	switch (action) {
+	switch (want) {
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
 		if (atomic_test_mask
 		if (atomic_test_mask
 		    (ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status)) {
 		    (ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status)) {
-			debug_text_event(adapter->erp_dbf, 4, "u_actenq_drp");
-			debug_event(adapter->erp_dbf, 4, &port->wwpn,
-				    sizeof (wwn_t));
-			debug_event(adapter->erp_dbf, 4, &unit->fcp_lun,
-				    sizeof (fcp_lun_t));
 			goto out;
 			goto out;
 		}
 		}
 		if (!atomic_test_mask
 		if (!atomic_test_mask
@@ -2964,18 +2787,13 @@ zfcp_erp_action_enqueue(int action,
 			goto out;
 			goto out;
 		}
 		}
 		if (!atomic_test_mask
 		if (!atomic_test_mask
-		    (ZFCP_STATUS_COMMON_UNBLOCKED, &port->status)) {
-			stronger_action = ZFCP_ERP_ACTION_REOPEN_PORT;
-			unit = NULL;
-		}
+		    (ZFCP_STATUS_COMMON_UNBLOCKED, &port->status))
+			need = ZFCP_ERP_ACTION_REOPEN_PORT;
 		/* fall through !!! */
 		/* fall through !!! */
 
 
 	case ZFCP_ERP_ACTION_REOPEN_PORT:
 	case ZFCP_ERP_ACTION_REOPEN_PORT:
 		if (atomic_test_mask
 		if (atomic_test_mask
 		    (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status)) {
 		    (ZFCP_STATUS_COMMON_ERP_INUSE, &port->status)) {
-			debug_text_event(adapter->erp_dbf, 4, "p_actenq_drp");
-			debug_event(adapter->erp_dbf, 4, &port->wwpn,
-				    sizeof (wwn_t));
 			goto out;
 			goto out;
 		}
 		}
 		/* fall through !!! */
 		/* fall through !!! */
@@ -2987,15 +2805,9 @@ zfcp_erp_action_enqueue(int action,
 			    ZFCP_ERP_ACTION_REOPEN_PORT_FORCED) {
 			    ZFCP_ERP_ACTION_REOPEN_PORT_FORCED) {
 				ZFCP_LOG_INFO("dropped erp action %i (port "
 				ZFCP_LOG_INFO("dropped erp action %i (port "
 					      "0x%016Lx, action in use: %i)\n",
 					      "0x%016Lx, action in use: %i)\n",
-					      action, port->wwpn,
+					      want, port->wwpn,
 					      port->erp_action.action);
 					      port->erp_action.action);
-				debug_text_event(adapter->erp_dbf, 4,
-						 "pf_actenq_drp");
-			} else
-				debug_text_event(adapter->erp_dbf, 4,
-						 "pf_actenq_drpcp");
-			debug_event(adapter->erp_dbf, 4, &port->wwpn,
-				    sizeof (wwn_t));
+			}
 			goto out;
 			goto out;
 		}
 		}
 		if (!atomic_test_mask
 		if (!atomic_test_mask
@@ -3005,46 +2817,36 @@ zfcp_erp_action_enqueue(int action,
 			goto out;
 			goto out;
 		}
 		}
 		if (!atomic_test_mask
 		if (!atomic_test_mask
-		    (ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status)) {
-			stronger_action = ZFCP_ERP_ACTION_REOPEN_ADAPTER;
-			port = NULL;
-		}
+		    (ZFCP_STATUS_COMMON_UNBLOCKED, &adapter->status))
+			need = ZFCP_ERP_ACTION_REOPEN_ADAPTER;
 		/* fall through !!! */
 		/* fall through !!! */
 
 
 	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
 	case ZFCP_ERP_ACTION_REOPEN_ADAPTER:
 		if (atomic_test_mask
 		if (atomic_test_mask
 		    (ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status)) {
 		    (ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status)) {
-			debug_text_event(adapter->erp_dbf, 4, "a_actenq_drp");
 			goto out;
 			goto out;
 		}
 		}
 		break;
 		break;
 
 
 	default:
 	default:
-		debug_text_exception(adapter->erp_dbf, 1, "a_actenq_bug");
-		debug_event(adapter->erp_dbf, 1, &action, sizeof (int));
 		ZFCP_LOG_NORMAL("bug: unknown erp action requested "
 		ZFCP_LOG_NORMAL("bug: unknown erp action requested "
 				"on adapter %s (action=%d)\n",
 				"on adapter %s (action=%d)\n",
-				zfcp_get_busid_by_adapter(adapter), action);
+				zfcp_get_busid_by_adapter(adapter), want);
 		goto out;
 		goto out;
 	}
 	}
 
 
 	/* check whether we need something stronger first */
 	/* check whether we need something stronger first */
-	if (stronger_action) {
-		debug_text_event(adapter->erp_dbf, 4, "a_actenq_str");
-		debug_event(adapter->erp_dbf, 4, &stronger_action,
-			    sizeof (int));
+	if (need) {
 		ZFCP_LOG_DEBUG("stronger erp action %d needed before "
 		ZFCP_LOG_DEBUG("stronger erp action %d needed before "
 			       "erp action %d on adapter %s\n",
 			       "erp action %d on adapter %s\n",
-			       stronger_action, action,
-			       zfcp_get_busid_by_adapter(adapter));
-		action = stronger_action;
+			       need, want, zfcp_get_busid_by_adapter(adapter));
 	}
 	}
 
 
 	/* mark adapter to have some error recovery pending */
 	/* mark adapter to have some error recovery pending */
 	atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, &adapter->status);
 	atomic_set_mask(ZFCP_STATUS_ADAPTER_ERP_PENDING, &adapter->status);
 
 
 	/* setup error recovery action */
 	/* setup error recovery action */
-	switch (action) {
+	switch (need) {
 
 
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
 		zfcp_unit_get(unit);
 		zfcp_unit_get(unit);
@@ -3077,13 +2879,11 @@ zfcp_erp_action_enqueue(int action,
 		break;
 		break;
 	}
 	}
 
 
-	debug_text_event(adapter->erp_dbf, 4, "a_actenq");
-
 	memset(erp_action, 0, sizeof (struct zfcp_erp_action));
 	memset(erp_action, 0, sizeof (struct zfcp_erp_action));
 	erp_action->adapter = adapter;
 	erp_action->adapter = adapter;
 	erp_action->port = port;
 	erp_action->port = port;
 	erp_action->unit = unit;
 	erp_action->unit = unit;
-	erp_action->action = action;
+	erp_action->action = need;
 	erp_action->status = status;
 	erp_action->status = status;
 
 
 	++adapter->erp_total_count;
 	++adapter->erp_total_count;
@@ -3091,8 +2891,11 @@ zfcp_erp_action_enqueue(int action,
 	/* finally put it into 'ready' queue and kick erp thread */
 	/* finally put it into 'ready' queue and kick erp thread */
 	list_add_tail(&erp_action->list, &adapter->erp_ready_head);
 	list_add_tail(&erp_action->list, &adapter->erp_ready_head);
 	up(&adapter->erp_ready_sem);
 	up(&adapter->erp_ready_sem);
+	zfcp_rec_dbf_event_thread(1, adapter, 0);
 	retval = 0;
 	retval = 0;
  out:
  out:
+	zfcp_rec_dbf_event_trigger(id, ref, want, need, erp_action,
+				   adapter, port, unit);
 	return retval;
 	return retval;
 }
 }
 
 
@@ -3108,9 +2911,9 @@ zfcp_erp_action_dequeue(struct zfcp_erp_action *erp_action)
 		erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM;
 		erp_action->status &= ~ZFCP_STATUS_ERP_LOWMEM;
 	}
 	}
 
 
-	debug_text_event(adapter->erp_dbf, 4, "a_actdeq");
-	debug_event(adapter->erp_dbf, 4, &erp_action->action, sizeof (int));
 	list_del(&erp_action->list);
 	list_del(&erp_action->list);
+	zfcp_rec_dbf_event_action(144, erp_action);
+
 	switch (erp_action->action) {
 	switch (erp_action->action) {
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
 	case ZFCP_ERP_ACTION_REOPEN_UNIT:
 		atomic_clear_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
 		atomic_clear_mask(ZFCP_STATUS_COMMON_ERP_INUSE,
@@ -3215,7 +3018,6 @@ static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
 {
 {
 	struct zfcp_port *port;
 	struct zfcp_port *port;
 
 
-	debug_text_event(adapter->erp_dbf, 5, "a_actab");
 	if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status))
 	if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &adapter->status))
 		zfcp_erp_action_dismiss(&adapter->erp_action);
 		zfcp_erp_action_dismiss(&adapter->erp_action);
 	else
 	else
@@ -3226,10 +3028,7 @@ static void zfcp_erp_action_dismiss_adapter(struct zfcp_adapter *adapter)
 static void zfcp_erp_action_dismiss_port(struct zfcp_port *port)
 static void zfcp_erp_action_dismiss_port(struct zfcp_port *port)
 {
 {
 	struct zfcp_unit *unit;
 	struct zfcp_unit *unit;
-	struct zfcp_adapter *adapter = port->adapter;
 
 
-	debug_text_event(adapter->erp_dbf, 5, "p_actab");
-	debug_event(adapter->erp_dbf, 5, &port->wwpn, sizeof (wwn_t));
 	if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status))
 	if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &port->status))
 		zfcp_erp_action_dismiss(&port->erp_action);
 		zfcp_erp_action_dismiss(&port->erp_action);
 	else
 	else
@@ -3239,92 +3038,60 @@ static void zfcp_erp_action_dismiss_port(struct zfcp_port *port)
 
 
 static void zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit)
 static void zfcp_erp_action_dismiss_unit(struct zfcp_unit *unit)
 {
 {
-	struct zfcp_adapter *adapter = unit->port->adapter;
-
-	debug_text_event(adapter->erp_dbf, 5, "u_actab");
-	debug_event(adapter->erp_dbf, 5, &unit->fcp_lun, sizeof (fcp_lun_t));
 	if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status))
 	if (atomic_test_mask(ZFCP_STATUS_COMMON_ERP_INUSE, &unit->status))
 		zfcp_erp_action_dismiss(&unit->erp_action);
 		zfcp_erp_action_dismiss(&unit->erp_action);
 }
 }
 
 
 static void zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action)
 static void zfcp_erp_action_to_running(struct zfcp_erp_action *erp_action)
 {
 {
-	struct zfcp_adapter *adapter = erp_action->adapter;
-
-	debug_text_event(adapter->erp_dbf, 6, "a_toru");
-	debug_event(adapter->erp_dbf, 6, &erp_action->action, sizeof (int));
 	list_move(&erp_action->list, &erp_action->adapter->erp_running_head);
 	list_move(&erp_action->list, &erp_action->adapter->erp_running_head);
+	zfcp_rec_dbf_event_action(145, erp_action);
 }
 }
 
 
 static void zfcp_erp_action_to_ready(struct zfcp_erp_action *erp_action)
 static void zfcp_erp_action_to_ready(struct zfcp_erp_action *erp_action)
 {
 {
-	struct zfcp_adapter *adapter = erp_action->adapter;
-
-	debug_text_event(adapter->erp_dbf, 6, "a_tore");
-	debug_event(adapter->erp_dbf, 6, &erp_action->action, sizeof (int));
 	list_move(&erp_action->list, &erp_action->adapter->erp_ready_head);
 	list_move(&erp_action->list, &erp_action->adapter->erp_ready_head);
+	zfcp_rec_dbf_event_action(146, erp_action);
 }
 }
 
 
-void
-zfcp_erp_port_boxed(struct zfcp_port *port)
+void zfcp_erp_port_boxed(struct zfcp_port *port, u8 id, void *ref)
 {
 {
-	struct zfcp_adapter *adapter = port->adapter;
 	unsigned long flags;
 	unsigned long flags;
 
 
-	debug_text_event(adapter->erp_dbf, 3, "p_access_boxed");
-	debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	zfcp_erp_modify_port_status(port,
-			ZFCP_STATUS_COMMON_ACCESS_BOXED,
-			ZFCP_SET);
+	zfcp_erp_modify_port_status(port, id, ref,
+				    ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
-	zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED);
+	zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref);
 }
 }
 
 
-void
-zfcp_erp_unit_boxed(struct zfcp_unit *unit)
+void zfcp_erp_unit_boxed(struct zfcp_unit *unit, u8 id, void *ref)
 {
 {
-	struct zfcp_adapter *adapter = unit->port->adapter;
-
-	debug_text_event(adapter->erp_dbf, 3, "u_access_boxed");
-	debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));
-	zfcp_erp_modify_unit_status(unit,
-			ZFCP_STATUS_COMMON_ACCESS_BOXED,
-			ZFCP_SET);
-	zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED);
+	zfcp_erp_modify_unit_status(unit, id, ref,
+				    ZFCP_STATUS_COMMON_ACCESS_BOXED, ZFCP_SET);
+	zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref);
 }
 }
 
 
-void
-zfcp_erp_port_access_denied(struct zfcp_port *port)
+void zfcp_erp_port_access_denied(struct zfcp_port *port, u8 id, void *ref)
 {
 {
-	struct zfcp_adapter *adapter = port->adapter;
 	unsigned long flags;
 	unsigned long flags;
 
 
-	debug_text_event(adapter->erp_dbf, 3, "p_access_denied");
-	debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
-	zfcp_erp_modify_port_status(port,
-			ZFCP_STATUS_COMMON_ERP_FAILED |
-			ZFCP_STATUS_COMMON_ACCESS_DENIED,
-			ZFCP_SET);
+	zfcp_erp_modify_port_status(port, id, ref,
+				    ZFCP_STATUS_COMMON_ERP_FAILED |
+				    ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 }
 }
 
 
-void
-zfcp_erp_unit_access_denied(struct zfcp_unit *unit)
+void zfcp_erp_unit_access_denied(struct zfcp_unit *unit, u8 id, void *ref)
 {
 {
-	struct zfcp_adapter *adapter = unit->port->adapter;
-
-	debug_text_event(adapter->erp_dbf, 3, "u_access_denied");
-	debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));
-	zfcp_erp_modify_unit_status(unit,
-			ZFCP_STATUS_COMMON_ERP_FAILED |
-			ZFCP_STATUS_COMMON_ACCESS_DENIED,
-			ZFCP_SET);
+	zfcp_erp_modify_unit_status(unit, id, ref,
+				    ZFCP_STATUS_COMMON_ERP_FAILED |
+				    ZFCP_STATUS_COMMON_ACCESS_DENIED, ZFCP_SET);
 }
 }
 
 
-void
-zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter)
+void zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter, u8 id,
+				     void *ref)
 {
 {
 	struct zfcp_port *port;
 	struct zfcp_port *port;
 	unsigned long flags;
 	unsigned long flags;
@@ -3332,54 +3099,43 @@ zfcp_erp_adapter_access_changed(struct zfcp_adapter *adapter)
 	if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
 	if (adapter->connection_features & FSF_FEATURE_NPIV_MODE)
 		return;
 		return;
 
 
-	debug_text_event(adapter->erp_dbf, 3, "a_access_recover");
-	debug_event(adapter->erp_dbf, 3, zfcp_get_busid_by_adapter(adapter), 8);
-
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	read_lock_irqsave(&zfcp_data.config_lock, flags);
 	if (adapter->nameserver_port)
 	if (adapter->nameserver_port)
-		zfcp_erp_port_access_changed(adapter->nameserver_port);
+		zfcp_erp_port_access_changed(adapter->nameserver_port, id, ref);
 	list_for_each_entry(port, &adapter->port_list_head, list)
 	list_for_each_entry(port, &adapter->port_list_head, list)
 		if (port != adapter->nameserver_port)
 		if (port != adapter->nameserver_port)
-			zfcp_erp_port_access_changed(port);
+			zfcp_erp_port_access_changed(port, id, ref);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 	read_unlock_irqrestore(&zfcp_data.config_lock, flags);
 }
 }
 
 
-void
-zfcp_erp_port_access_changed(struct zfcp_port *port)
+void zfcp_erp_port_access_changed(struct zfcp_port *port, u8 id, void *ref)
 {
 {
 	struct zfcp_adapter *adapter = port->adapter;
 	struct zfcp_adapter *adapter = port->adapter;
 	struct zfcp_unit *unit;
 	struct zfcp_unit *unit;
 
 
-	debug_text_event(adapter->erp_dbf, 3, "p_access_recover");
-	debug_event(adapter->erp_dbf, 3, &port->wwpn, sizeof(wwn_t));
-
 	if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED,
 	if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED,
 			      &port->status) &&
 			      &port->status) &&
 	    !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED,
 	    !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED,
 			      &port->status)) {
 			      &port->status)) {
 		if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
 		if (!atomic_test_mask(ZFCP_STATUS_PORT_WKA, &port->status))
 			list_for_each_entry(unit, &port->unit_list_head, list)
 			list_for_each_entry(unit, &port->unit_list_head, list)
-				zfcp_erp_unit_access_changed(unit);
+				zfcp_erp_unit_access_changed(unit, id, ref);
 		return;
 		return;
 	}
 	}
 
 
 	ZFCP_LOG_NORMAL("reopen of port 0x%016Lx on adapter %s "
 	ZFCP_LOG_NORMAL("reopen of port 0x%016Lx on adapter %s "
 			"(due to ACT update)\n",
 			"(due to ACT update)\n",
 			port->wwpn, zfcp_get_busid_by_adapter(adapter));
 			port->wwpn, zfcp_get_busid_by_adapter(adapter));
-	if (zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED) != 0)
+	if (zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref))
 		ZFCP_LOG_NORMAL("failed reopen of port"
 		ZFCP_LOG_NORMAL("failed reopen of port"
 				"(adapter %s, wwpn=0x%016Lx)\n",
 				"(adapter %s, wwpn=0x%016Lx)\n",
 				zfcp_get_busid_by_adapter(adapter), port->wwpn);
 				zfcp_get_busid_by_adapter(adapter), port->wwpn);
 }
 }
 
 
-void
-zfcp_erp_unit_access_changed(struct zfcp_unit *unit)
+void zfcp_erp_unit_access_changed(struct zfcp_unit *unit, u8 id, void *ref)
 {
 {
 	struct zfcp_adapter *adapter = unit->port->adapter;
 	struct zfcp_adapter *adapter = unit->port->adapter;
 
 
-	debug_text_event(adapter->erp_dbf, 3, "u_access_recover");
-	debug_event(adapter->erp_dbf, 3, &unit->fcp_lun, sizeof(fcp_lun_t));
-
 	if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED,
 	if (!atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_DENIED,
 			      &unit->status) &&
 			      &unit->status) &&
 	    !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED,
 	    !atomic_test_mask(ZFCP_STATUS_COMMON_ACCESS_BOXED,
@@ -3390,7 +3146,7 @@ zfcp_erp_unit_access_changed(struct zfcp_unit *unit)
 			" on adapter %s (due to ACT update)\n",
 			" on adapter %s (due to ACT update)\n",
 			unit->fcp_lun, unit->port->wwpn,
 			unit->fcp_lun, unit->port->wwpn,
 			zfcp_get_busid_by_adapter(adapter));
 			zfcp_get_busid_by_adapter(adapter));
-	if (zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED) != 0)
+	if (zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, id, ref))
 		ZFCP_LOG_NORMAL("failed reopen of unit (adapter %s, "
 		ZFCP_LOG_NORMAL("failed reopen of unit (adapter %s, "
 				"wwpn=0x%016Lx, fcp_lun=0x%016Lx)\n",
 				"wwpn=0x%016Lx, fcp_lun=0x%016Lx)\n",
 				zfcp_get_busid_by_adapter(adapter),
 				zfcp_get_busid_by_adapter(adapter),

+ 36 - 23
drivers/s390/scsi/zfcp_ext.h

@@ -131,22 +131,25 @@ extern int zfcp_scsi_command_sync(struct zfcp_unit *, struct scsi_cmnd *, int);
 extern struct fc_function_template zfcp_transport_functions;
 extern struct fc_function_template zfcp_transport_functions;
 
 
 /******************************** ERP ****************************************/
 /******************************** ERP ****************************************/
-extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, u32, int);
-extern int  zfcp_erp_adapter_reopen(struct zfcp_adapter *, int);
-extern int  zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int);
-extern void zfcp_erp_adapter_failed(struct zfcp_adapter *);
-
-extern void zfcp_erp_modify_port_status(struct zfcp_port *, u32, int);
-extern int  zfcp_erp_port_reopen(struct zfcp_port *, int);
-extern int  zfcp_erp_port_shutdown(struct zfcp_port *, int);
-extern int  zfcp_erp_port_forced_reopen(struct zfcp_port *, int);
-extern void zfcp_erp_port_failed(struct zfcp_port *);
-extern int  zfcp_erp_port_reopen_all(struct zfcp_adapter *, int);
-
-extern void zfcp_erp_modify_unit_status(struct zfcp_unit *, u32, int);
-extern int  zfcp_erp_unit_reopen(struct zfcp_unit *, int);
-extern int  zfcp_erp_unit_shutdown(struct zfcp_unit *, int);
-extern void zfcp_erp_unit_failed(struct zfcp_unit *);
+extern void zfcp_erp_modify_adapter_status(struct zfcp_adapter *, u8, void *,
+					   u32, int);
+extern int  zfcp_erp_adapter_reopen(struct zfcp_adapter *, int, u8, void *);
+extern int  zfcp_erp_adapter_shutdown(struct zfcp_adapter *, int, u8, void *);
+extern void zfcp_erp_adapter_failed(struct zfcp_adapter *, u8, void *);
+
+extern void zfcp_erp_modify_port_status(struct zfcp_port *, u8, void *, u32,
+					int);
+extern int  zfcp_erp_port_reopen(struct zfcp_port *, int, u8, void *);
+extern int  zfcp_erp_port_shutdown(struct zfcp_port *, int, u8, void *);
+extern int  zfcp_erp_port_forced_reopen(struct zfcp_port *, int, u8, void *);
+extern void zfcp_erp_port_failed(struct zfcp_port *, u8, void *);
+extern int  zfcp_erp_port_reopen_all(struct zfcp_adapter *, int, u8, void *);
+
+extern void zfcp_erp_modify_unit_status(struct zfcp_unit *, u8, void *, u32,
+					int);
+extern int  zfcp_erp_unit_reopen(struct zfcp_unit *, int, u8, void *);
+extern int  zfcp_erp_unit_shutdown(struct zfcp_unit *, int, u8, void *);
+extern void zfcp_erp_unit_failed(struct zfcp_unit *, u8, void *);
 
 
 extern int  zfcp_erp_thread_setup(struct zfcp_adapter *);
 extern int  zfcp_erp_thread_setup(struct zfcp_adapter *);
 extern int  zfcp_erp_thread_kill(struct zfcp_adapter *);
 extern int  zfcp_erp_thread_kill(struct zfcp_adapter *);
@@ -155,15 +158,25 @@ extern void zfcp_erp_async_handler(struct zfcp_erp_action *, unsigned long);
 
 
 extern int  zfcp_test_link(struct zfcp_port *);
 extern int  zfcp_test_link(struct zfcp_port *);
 
 
-extern void zfcp_erp_port_boxed(struct zfcp_port *);
-extern void zfcp_erp_unit_boxed(struct zfcp_unit *);
-extern void zfcp_erp_port_access_denied(struct zfcp_port *);
-extern void zfcp_erp_unit_access_denied(struct zfcp_unit *);
-extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *);
-extern void zfcp_erp_port_access_changed(struct zfcp_port *);
-extern void zfcp_erp_unit_access_changed(struct zfcp_unit *);
+extern void zfcp_erp_port_boxed(struct zfcp_port *, u8 id, void *ref);
+extern void zfcp_erp_unit_boxed(struct zfcp_unit *, u8 id, void *ref);
+extern void zfcp_erp_port_access_denied(struct zfcp_port *, u8 id, void *ref);
+extern void zfcp_erp_unit_access_denied(struct zfcp_unit *, u8 id, void *ref);
+extern void zfcp_erp_adapter_access_changed(struct zfcp_adapter *, u8, void *);
+extern void zfcp_erp_port_access_changed(struct zfcp_port *, u8, void *);
+extern void zfcp_erp_unit_access_changed(struct zfcp_unit *, u8, void *);
 
 
 /******************************** AUX ****************************************/
 /******************************** AUX ****************************************/
+extern void zfcp_rec_dbf_event_thread(u8 id, struct zfcp_adapter *adapter,
+				      int lock);
+extern void zfcp_rec_dbf_event_adapter(u8 id, void *ref, struct zfcp_adapter *);
+extern void zfcp_rec_dbf_event_port(u8 id, void *ref, struct zfcp_port *port);
+extern void zfcp_rec_dbf_event_unit(u8 id, void *ref, struct zfcp_unit *unit);
+extern void zfcp_rec_dbf_event_trigger(u8 id, void *ref, u8 want, u8 need,
+				       void *action, struct zfcp_adapter *,
+				       struct zfcp_port *, struct zfcp_unit *);
+extern void zfcp_rec_dbf_event_action(u8 id, struct zfcp_erp_action *);
+
 extern void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *);
 extern void zfcp_hba_dbf_event_fsf_response(struct zfcp_fsf_req *);
 extern void zfcp_hba_dbf_event_fsf_unsol(const char *, struct zfcp_adapter *,
 extern void zfcp_hba_dbf_event_fsf_unsol(const char *, struct zfcp_adapter *,
 					 struct fsf_status_read_buffer *);
 					 struct fsf_status_read_buffer *);

+ 90 - 307
drivers/s390/scsi/zfcp_fsf.c

@@ -46,7 +46,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *);
 static int zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *);
 static int zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *);
 static int zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *);
 static int zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *);
 static int zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *);
 static int zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *);
-static void zfcp_fsf_link_down_info_eval(struct zfcp_adapter *,
+static void zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *, u8,
 	struct fsf_link_down_info *);
 	struct fsf_link_down_info *);
 static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *);
 static int zfcp_fsf_req_dispatch(struct zfcp_fsf_req *);
 
 
@@ -284,37 +284,6 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
 		goto skip_protstatus;
 		goto skip_protstatus;
 	}
 	}
 
 
-	/* log additional information provided by FSF (if any) */
-	if (likely(qtcb->header.log_length)) {
-		/* do not trust them ;-) */
-		if (unlikely(qtcb->header.log_start >
-			     sizeof(struct fsf_qtcb))) {
-			ZFCP_LOG_NORMAL
-			    ("bug: ULP (FSF logging) log data starts "
-			     "beyond end of packet header. Ignored. "
-			     "(start=%i, size=%li)\n",
-			     qtcb->header.log_start,
-			     sizeof(struct fsf_qtcb));
-			goto forget_log;
-		}
-		if (unlikely((size_t) (qtcb->header.log_start +
-				       qtcb->header.log_length) >
-			     sizeof(struct fsf_qtcb))) {
-			ZFCP_LOG_NORMAL("bug: ULP (FSF logging) log data ends "
-					"beyond end of packet header. Ignored. "
-					"(start=%i, length=%i, size=%li)\n",
-					qtcb->header.log_start,
-					qtcb->header.log_length,
-					sizeof(struct fsf_qtcb));
-			goto forget_log;
-		}
-		ZFCP_LOG_TRACE("ULP log data: \n");
-		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_TRACE,
-			      (char *) qtcb + qtcb->header.log_start,
-			      qtcb->header.log_length);
-	}
- forget_log:
-
 	/* evaluate FSF Protocol Status */
 	/* evaluate FSF Protocol Status */
 	switch (qtcb->prefix.prot_status) {
 	switch (qtcb->prefix.prot_status) {
 
 
@@ -329,7 +298,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
 				zfcp_get_busid_by_adapter(adapter),
 				zfcp_get_busid_by_adapter(adapter),
 				prot_status_qual->version_error.fsf_version,
 				prot_status_qual->version_error.fsf_version,
 				ZFCP_QTCB_VERSION);
 				ZFCP_QTCB_VERSION);
-		zfcp_erp_adapter_shutdown(adapter, 0);
+		zfcp_erp_adapter_shutdown(adapter, 0, 117, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -340,7 +309,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
 				qtcb->prefix.req_seq_no,
 				qtcb->prefix.req_seq_no,
 				zfcp_get_busid_by_adapter(adapter),
 				zfcp_get_busid_by_adapter(adapter),
 				prot_status_qual->sequence_error.exp_req_seq_no);
 				prot_status_qual->sequence_error.exp_req_seq_no);
-		zfcp_erp_adapter_reopen(adapter, 0);
+		zfcp_erp_adapter_reopen(adapter, 0, 98, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
@@ -351,7 +320,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
 				"that used on adapter %s. "
 				"that used on adapter %s. "
 				"Stopping all operations on this adapter.\n",
 				"Stopping all operations on this adapter.\n",
 				zfcp_get_busid_by_adapter(adapter));
 				zfcp_get_busid_by_adapter(adapter));
-		zfcp_erp_adapter_shutdown(adapter, 0);
+		zfcp_erp_adapter_shutdown(adapter, 0, 118, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -368,14 +337,15 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
 				*(unsigned long long*)
 				*(unsigned long long*)
 				(&qtcb->bottom.support.req_handle),
 				(&qtcb->bottom.support.req_handle),
 					zfcp_get_busid_by_adapter(adapter));
 					zfcp_get_busid_by_adapter(adapter));
-		zfcp_erp_adapter_shutdown(adapter, 0);
+		zfcp_erp_adapter_shutdown(adapter, 0, 78, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
 	case FSF_PROT_LINK_DOWN:
 	case FSF_PROT_LINK_DOWN:
-		zfcp_fsf_link_down_info_eval(adapter,
+		zfcp_fsf_link_down_info_eval(fsf_req, 37,
 					     &prot_status_qual->link_down_info);
 					     &prot_status_qual->link_down_info);
-		zfcp_erp_adapter_reopen(adapter, 0);
+		/* FIXME: reopening adapter now? better wait for link up */
+		zfcp_erp_adapter_reopen(adapter, 0, 79, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -385,12 +355,13 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
 			      "Re-starting operations on this adapter.\n",
 			      "Re-starting operations on this adapter.\n",
 			      zfcp_get_busid_by_adapter(adapter));
 			      zfcp_get_busid_by_adapter(adapter));
 		/* All ports should be marked as ready to run again */
 		/* All ports should be marked as ready to run again */
-		zfcp_erp_modify_adapter_status(adapter,
+		zfcp_erp_modify_adapter_status(adapter, 28, NULL,
 					       ZFCP_STATUS_COMMON_RUNNING,
 					       ZFCP_STATUS_COMMON_RUNNING,
 					       ZFCP_SET);
 					       ZFCP_SET);
 		zfcp_erp_adapter_reopen(adapter,
 		zfcp_erp_adapter_reopen(adapter,
 					ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED
 					ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED
-					| ZFCP_STATUS_COMMON_ERP_FAILED);
+					| ZFCP_STATUS_COMMON_ERP_FAILED,
+					99, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -400,7 +371,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
 				"Restarting all operations on this "
 				"Restarting all operations on this "
 				"adapter.\n",
 				"adapter.\n",
 				zfcp_get_busid_by_adapter(adapter));
 				zfcp_get_busid_by_adapter(adapter));
-		zfcp_erp_adapter_reopen(adapter, 0);
+		zfcp_erp_adapter_reopen(adapter, 0, 100, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_RETRY;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
@@ -413,7 +384,7 @@ zfcp_fsf_protstatus_eval(struct zfcp_fsf_req *fsf_req)
 				"(debug info 0x%x).\n",
 				"(debug info 0x%x).\n",
 				zfcp_get_busid_by_adapter(adapter),
 				zfcp_get_busid_by_adapter(adapter),
 				qtcb->prefix.prot_status);
 				qtcb->prefix.prot_status);
-		zfcp_erp_adapter_shutdown(adapter, 0);
+		zfcp_erp_adapter_shutdown(adapter, 0, 119, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 	}
 	}
 
 
@@ -452,7 +423,7 @@ zfcp_fsf_fsfstatus_eval(struct zfcp_fsf_req *fsf_req)
 				"(debug info 0x%x).\n",
 				"(debug info 0x%x).\n",
 				zfcp_get_busid_by_adapter(fsf_req->adapter),
 				zfcp_get_busid_by_adapter(fsf_req->adapter),
 				fsf_req->qtcb->header.fsf_command);
 				fsf_req->qtcb->header.fsf_command);
-		zfcp_erp_adapter_shutdown(fsf_req->adapter, 0);
+		zfcp_erp_adapter_shutdown(fsf_req->adapter, 0, 120, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -506,7 +477,7 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req)
 				"problem on the adapter %s "
 				"problem on the adapter %s "
 				"Stopping all operations on this adapter. ",
 				"Stopping all operations on this adapter. ",
 				zfcp_get_busid_by_adapter(fsf_req->adapter));
 				zfcp_get_busid_by_adapter(fsf_req->adapter));
-		zfcp_erp_adapter_shutdown(fsf_req->adapter, 0);
+		zfcp_erp_adapter_shutdown(fsf_req->adapter, 0, 121, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 	case FSF_SQ_ULP_PROGRAMMING_ERROR:
 	case FSF_SQ_ULP_PROGRAMMING_ERROR:
@@ -537,9 +508,11 @@ zfcp_fsf_fsfstatus_qual_eval(struct zfcp_fsf_req *fsf_req)
  * zfcp_fsf_link_down_info_eval - evaluate link down information block
  * zfcp_fsf_link_down_info_eval - evaluate link down information block
  */
  */
 static void
 static void
-zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter,
+zfcp_fsf_link_down_info_eval(struct zfcp_fsf_req *fsf_req, u8 id,
 			     struct fsf_link_down_info *link_down)
 			     struct fsf_link_down_info *link_down)
 {
 {
+	struct zfcp_adapter *adapter = fsf_req->adapter;
+
 	if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
 	if (atomic_test_mask(ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED,
 	                     &adapter->status))
 	                     &adapter->status))
 		return;
 		return;
@@ -630,7 +603,7 @@ zfcp_fsf_link_down_info_eval(struct zfcp_adapter *adapter,
 				link_down->vendor_specific_code);
 				link_down->vendor_specific_code);
 
 
  out:
  out:
-	zfcp_erp_adapter_failed(adapter);
+	zfcp_erp_adapter_failed(adapter, id, fsf_req);
 }
 }
 
 
 /*
 /*
@@ -824,19 +797,14 @@ zfcp_fsf_status_read_port_closed(struct zfcp_fsf_req *fsf_req)
 	switch (status_buffer->status_subtype) {
 	switch (status_buffer->status_subtype) {
 
 
 	case FSF_STATUS_READ_SUB_CLOSE_PHYS_PORT:
 	case FSF_STATUS_READ_SUB_CLOSE_PHYS_PORT:
-		debug_text_event(adapter->erp_dbf, 3, "unsol_pc_phys:");
-		zfcp_erp_port_reopen(port, 0);
+		zfcp_erp_port_reopen(port, 0, 101, fsf_req);
 		break;
 		break;
 
 
 	case FSF_STATUS_READ_SUB_ERROR_PORT:
 	case FSF_STATUS_READ_SUB_ERROR_PORT:
-		debug_text_event(adapter->erp_dbf, 1, "unsol_pc_err:");
-		zfcp_erp_port_shutdown(port, 0);
+		zfcp_erp_port_shutdown(port, 0, 122, fsf_req);
 		break;
 		break;
 
 
 	default:
 	default:
-		debug_text_event(adapter->erp_dbf, 0, "unsol_unk_sub:");
-		debug_exception(adapter->erp_dbf, 0,
-				&status_buffer->status_subtype, sizeof (u32));
 		ZFCP_LOG_NORMAL("bug: Undefined status subtype received "
 		ZFCP_LOG_NORMAL("bug: Undefined status subtype received "
 				"for a reopen indication on port with "
 				"for a reopen indication on port with "
 				"d_id 0x%06x on the adapter %s. "
 				"d_id 0x%06x on the adapter %s. "
@@ -928,7 +896,7 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
 		case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
 		case FSF_STATUS_READ_SUB_NO_PHYSICAL_LINK:
 			ZFCP_LOG_INFO("Physical link to adapter %s is down\n",
 			ZFCP_LOG_INFO("Physical link to adapter %s is down\n",
 				      zfcp_get_busid_by_adapter(adapter));
 				      zfcp_get_busid_by_adapter(adapter));
-			zfcp_fsf_link_down_info_eval(adapter,
+			zfcp_fsf_link_down_info_eval(fsf_req, 38,
 				(struct fsf_link_down_info *)
 				(struct fsf_link_down_info *)
 				&status_buffer->payload);
 				&status_buffer->payload);
 			break;
 			break;
@@ -936,7 +904,7 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
 			ZFCP_LOG_INFO("Local link to adapter %s is down "
 			ZFCP_LOG_INFO("Local link to adapter %s is down "
 				      "due to failed FDISC login\n",
 				      "due to failed FDISC login\n",
 				      zfcp_get_busid_by_adapter(adapter));
 				      zfcp_get_busid_by_adapter(adapter));
-			zfcp_fsf_link_down_info_eval(adapter,
+			zfcp_fsf_link_down_info_eval(fsf_req, 39,
 				(struct fsf_link_down_info *)
 				(struct fsf_link_down_info *)
 				&status_buffer->payload);
 				&status_buffer->payload);
 			break;
 			break;
@@ -944,13 +912,13 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
 			ZFCP_LOG_INFO("Local link to adapter %s is down "
 			ZFCP_LOG_INFO("Local link to adapter %s is down "
 				      "due to firmware update on adapter\n",
 				      "due to firmware update on adapter\n",
 				      zfcp_get_busid_by_adapter(adapter));
 				      zfcp_get_busid_by_adapter(adapter));
-			zfcp_fsf_link_down_info_eval(adapter, NULL);
+			zfcp_fsf_link_down_info_eval(fsf_req, 40, NULL);
 			break;
 			break;
 		default:
 		default:
 			ZFCP_LOG_INFO("Local link to adapter %s is down "
 			ZFCP_LOG_INFO("Local link to adapter %s is down "
 				      "due to unknown reason\n",
 				      "due to unknown reason\n",
 				      zfcp_get_busid_by_adapter(adapter));
 				      zfcp_get_busid_by_adapter(adapter));
-			zfcp_fsf_link_down_info_eval(adapter, NULL);
+			zfcp_fsf_link_down_info_eval(fsf_req, 41, NULL);
 		};
 		};
 		break;
 		break;
 
 
@@ -959,12 +927,13 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
 				"Restarting operations on this adapter\n",
 				"Restarting operations on this adapter\n",
 				zfcp_get_busid_by_adapter(adapter));
 				zfcp_get_busid_by_adapter(adapter));
 		/* All ports should be marked as ready to run again */
 		/* All ports should be marked as ready to run again */
-		zfcp_erp_modify_adapter_status(adapter,
+		zfcp_erp_modify_adapter_status(adapter, 30, NULL,
 					       ZFCP_STATUS_COMMON_RUNNING,
 					       ZFCP_STATUS_COMMON_RUNNING,
 					       ZFCP_SET);
 					       ZFCP_SET);
 		zfcp_erp_adapter_reopen(adapter,
 		zfcp_erp_adapter_reopen(adapter,
 					ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED
 					ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED
-					| ZFCP_STATUS_COMMON_ERP_FAILED);
+					| ZFCP_STATUS_COMMON_ERP_FAILED,
+					102, fsf_req);
 		break;
 		break;
 
 
 	case FSF_STATUS_READ_NOTIFICATION_LOST:
 	case FSF_STATUS_READ_NOTIFICATION_LOST:
@@ -998,13 +967,13 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
 
 
 		if (status_buffer->status_subtype &
 		if (status_buffer->status_subtype &
 		    FSF_STATUS_READ_SUB_ACT_UPDATED)
 		    FSF_STATUS_READ_SUB_ACT_UPDATED)
-			zfcp_erp_adapter_access_changed(adapter);
+			zfcp_erp_adapter_access_changed(adapter, 135, fsf_req);
 		break;
 		break;
 
 
 	case FSF_STATUS_READ_CFDC_UPDATED:
 	case FSF_STATUS_READ_CFDC_UPDATED:
 		ZFCP_LOG_NORMAL("CFDC has been updated on the adapter %s\n",
 		ZFCP_LOG_NORMAL("CFDC has been updated on the adapter %s\n",
 			      zfcp_get_busid_by_adapter(adapter));
 			      zfcp_get_busid_by_adapter(adapter));
-		zfcp_erp_adapter_access_changed(adapter);
+		zfcp_erp_adapter_access_changed(adapter, 136, fsf_req);
 		break;
 		break;
 
 
 	case FSF_STATUS_READ_CFDC_HARDENED:
 	case FSF_STATUS_READ_CFDC_HARDENED:
@@ -1025,7 +994,6 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
 		break;
 		break;
 
 
 	case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:
 	case FSF_STATUS_READ_FEATURE_UPDATE_ALERT:
-		debug_text_event(adapter->erp_dbf, 2, "unsol_features:");
 		ZFCP_LOG_INFO("List of supported features on adapter %s has "
 		ZFCP_LOG_INFO("List of supported features on adapter %s has "
 			      "been changed from 0x%08X to 0x%08X\n",
 			      "been changed from 0x%08X to 0x%08X\n",
 			      zfcp_get_busid_by_adapter(adapter),
 			      zfcp_get_busid_by_adapter(adapter),
@@ -1073,7 +1041,7 @@ zfcp_fsf_status_read_handler(struct zfcp_fsf_req *fsf_req)
 			ZFCP_LOG_INFO("restart adapter %s due to status read "
 			ZFCP_LOG_INFO("restart adapter %s due to status read "
 				      "buffer shortage\n",
 				      "buffer shortage\n",
 				      zfcp_get_busid_by_adapter(adapter));
 				      zfcp_get_busid_by_adapter(adapter));
-			zfcp_erp_adapter_reopen(adapter, 0);
+			zfcp_erp_adapter_reopen(adapter, 0, 103, fsf_req);
 		}
 		}
 	}
 	}
  out:
  out:
@@ -1174,8 +1142,6 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req)
 
 
 	case FSF_PORT_HANDLE_NOT_VALID:
 	case FSF_PORT_HANDLE_NOT_VALID:
 		if (fsf_stat_qual->word[0] != fsf_stat_qual->word[1]) {
 		if (fsf_stat_qual->word[0] != fsf_stat_qual->word[1]) {
-			debug_text_event(new_fsf_req->adapter->erp_dbf, 3,
-					 "fsf_s_phand_nv0");
 			/*
 			/*
 			 * In this case a command that was sent prior to a port
 			 * In this case a command that was sent prior to a port
 			 * reopen was aborted (handles are different). This is
 			 * reopen was aborted (handles are different). This is
@@ -1194,17 +1160,14 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req)
 				      fsf_status_qual,
 				      fsf_status_qual,
 				      sizeof (union fsf_status_qual));
 				      sizeof (union fsf_status_qual));
 			/* Let's hope this sorts out the mess */
 			/* Let's hope this sorts out the mess */
-			debug_text_event(new_fsf_req->adapter->erp_dbf, 1,
-					 "fsf_s_phand_nv1");
-			zfcp_erp_adapter_reopen(unit->port->adapter, 0);
+			zfcp_erp_adapter_reopen(unit->port->adapter, 0, 104,
+						new_fsf_req);
 			new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		}
 		}
 		break;
 		break;
 
 
 	case FSF_LUN_HANDLE_NOT_VALID:
 	case FSF_LUN_HANDLE_NOT_VALID:
 		if (fsf_stat_qual->word[0] != fsf_stat_qual->word[1]) {
 		if (fsf_stat_qual->word[0] != fsf_stat_qual->word[1]) {
-			debug_text_event(new_fsf_req->adapter->erp_dbf, 3,
-					 "fsf_s_lhand_nv0");
 			/*
 			/*
 			 * In this case a command that was sent prior to a unit
 			 * In this case a command that was sent prior to a unit
 			 * reopen was aborted (handles are different).
 			 * reopen was aborted (handles are different).
@@ -1226,17 +1189,13 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req)
 				      fsf_status_qual,
 				      fsf_status_qual,
 				      sizeof (union fsf_status_qual));
 				      sizeof (union fsf_status_qual));
 			/* Let's hope this sorts out the mess */
 			/* Let's hope this sorts out the mess */
-			debug_text_event(new_fsf_req->adapter->erp_dbf, 1,
-					 "fsf_s_lhand_nv1");
-			zfcp_erp_port_reopen(unit->port, 0);
+			zfcp_erp_port_reopen(unit->port, 0, 105, new_fsf_req);
 			new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		}
 		}
 		break;
 		break;
 
 
 	case FSF_FCP_COMMAND_DOES_NOT_EXIST:
 	case FSF_FCP_COMMAND_DOES_NOT_EXIST:
 		retval = 0;
 		retval = 0;
-		debug_text_event(new_fsf_req->adapter->erp_dbf, 3,
-				 "fsf_s_no_exist");
 		new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED;
 		new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ABORTNOTNEEDED;
 		break;
 		break;
 
 
@@ -1244,9 +1203,7 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req)
 		ZFCP_LOG_INFO("Remote port 0x%016Lx on adapter %s needs to "
 		ZFCP_LOG_INFO("Remote port 0x%016Lx on adapter %s needs to "
 			      "be reopened\n", unit->port->wwpn,
 			      "be reopened\n", unit->port->wwpn,
 			      zfcp_get_busid_by_unit(unit));
 			      zfcp_get_busid_by_unit(unit));
-		debug_text_event(new_fsf_req->adapter->erp_dbf, 2,
-				 "fsf_s_pboxed");
-		zfcp_erp_port_boxed(unit->port);
+		zfcp_erp_port_boxed(unit->port, 47, new_fsf_req);
 		new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
 		new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
 		    | ZFCP_STATUS_FSFREQ_RETRY;
 		    | ZFCP_STATUS_FSFREQ_RETRY;
 		break;
 		break;
@@ -1257,8 +1214,7 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req)
                         "to be reopened\n",
                         "to be reopened\n",
                         unit->fcp_lun, unit->port->wwpn,
                         unit->fcp_lun, unit->port->wwpn,
                         zfcp_get_busid_by_unit(unit));
                         zfcp_get_busid_by_unit(unit));
-                debug_text_event(new_fsf_req->adapter->erp_dbf, 1, "fsf_s_lboxed");
-		zfcp_erp_unit_boxed(unit);
+		zfcp_erp_unit_boxed(unit, 48, new_fsf_req);
                 new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
                 new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
                         | ZFCP_STATUS_FSFREQ_RETRY;
                         | ZFCP_STATUS_FSFREQ_RETRY;
                 break;
                 break;
@@ -1266,26 +1222,17 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req)
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		switch (new_fsf_req->qtcb->header.fsf_status_qual.word[0]) {
 		switch (new_fsf_req->qtcb->header.fsf_status_qual.word[0]) {
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-			debug_text_event(new_fsf_req->adapter->erp_dbf, 1,
-					 "fsf_sq_ltest");
 			zfcp_test_link(unit->port);
 			zfcp_test_link(unit->port);
 			new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 			break;
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 			/* SCSI stack will escalate */
 			/* SCSI stack will escalate */
-			debug_text_event(new_fsf_req->adapter->erp_dbf, 1,
-					 "fsf_sq_ulp");
 			new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			new_fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 			break;
 		default:
 		default:
 			ZFCP_LOG_NORMAL
 			ZFCP_LOG_NORMAL
 			    ("bug: Wrong status qualifier 0x%x arrived.\n",
 			    ("bug: Wrong status qualifier 0x%x arrived.\n",
 			     new_fsf_req->qtcb->header.fsf_status_qual.word[0]);
 			     new_fsf_req->qtcb->header.fsf_status_qual.word[0]);
-			debug_text_event(new_fsf_req->adapter->erp_dbf, 0,
-					 "fsf_sq_inval:");
-			debug_exception(new_fsf_req->adapter->erp_dbf, 0,
-					&new_fsf_req->qtcb->header.
-					fsf_status_qual.word[0], sizeof (u32));
 			break;
 			break;
 		}
 		}
 		break;
 		break;
@@ -1299,11 +1246,6 @@ zfcp_fsf_abort_fcp_command_handler(struct zfcp_fsf_req *new_fsf_req)
 		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
 		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
 				"(debug info 0x%x)\n",
 				"(debug info 0x%x)\n",
 				new_fsf_req->qtcb->header.fsf_status);
 				new_fsf_req->qtcb->header.fsf_status);
-		debug_text_event(new_fsf_req->adapter->erp_dbf, 0,
-				 "fsf_s_inval:");
-		debug_exception(new_fsf_req->adapter->erp_dbf, 0,
-				&new_fsf_req->qtcb->header.fsf_status,
-				sizeof (u32));
 		break;
 		break;
 	}
 	}
  skip_fsfstatus:
  skip_fsfstatus:
@@ -1506,8 +1448,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req)
 			      zfcp_get_busid_by_port(port),
 			      zfcp_get_busid_by_port(port),
 			      ZFCP_FC_SERVICE_CLASS_DEFAULT);
 			      ZFCP_FC_SERVICE_CLASS_DEFAULT);
 		/* stop operation for this adapter */
 		/* stop operation for this adapter */
-		debug_text_exception(adapter->erp_dbf, 0, "fsf_s_class_nsup");
-		zfcp_erp_adapter_shutdown(adapter, 0);
+		zfcp_erp_adapter_shutdown(adapter, 0, 123, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -1515,13 +1456,11 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req)
                 switch (header->fsf_status_qual.word[0]){
                 switch (header->fsf_status_qual.word[0]){
                 case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
                 case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
 			/* reopening link to port */
 			/* reopening link to port */
-			debug_text_event(adapter->erp_dbf, 1, "fsf_sq_ltest");
 			zfcp_test_link(port);
 			zfcp_test_link(port);
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 			break;
                 case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
                 case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 			/* ERP strategy will escalate */
 			/* ERP strategy will escalate */
-			debug_text_event(adapter->erp_dbf, 1, "fsf_sq_ulp");
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 			break;
                 default:
                 default:
@@ -1549,8 +1488,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req)
 				break;
 				break;
 			}
 			}
 		}
 		}
-		debug_text_event(adapter->erp_dbf, 1, "fsf_s_access");
-		zfcp_erp_port_access_denied(port);
+		zfcp_erp_port_access_denied(port, 55, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -1562,7 +1500,6 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO,
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO,
 			      (char *) &header->fsf_status_qual,
 			      (char *) &header->fsf_status_qual,
 			      sizeof (union fsf_status_qual));
 			      sizeof (union fsf_status_qual));
-		debug_text_event(adapter->erp_dbf, 1, "fsf_s_gcom_rej");
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -1575,8 +1512,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO,
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_INFO,
 			      (char *) &header->fsf_status_qual,
 			      (char *) &header->fsf_status_qual,
 			      sizeof (union fsf_status_qual));
 			      sizeof (union fsf_status_qual));
-		debug_text_event(adapter->erp_dbf, 1, "fsf_s_phandle_nv");
-		zfcp_erp_adapter_reopen(adapter, 0);
+		zfcp_erp_adapter_reopen(adapter, 0, 106, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -1584,8 +1520,7 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_LOG_INFO("port needs to be reopened "
 		ZFCP_LOG_INFO("port needs to be reopened "
 			      "(adapter %s, port d_id=0x%06x)\n",
 			      "(adapter %s, port d_id=0x%06x)\n",
 			      zfcp_get_busid_by_port(port), port->d_id);
 			      zfcp_get_busid_by_port(port), port->d_id);
-		debug_text_event(adapter->erp_dbf, 2, "fsf_s_pboxed");
-		zfcp_erp_port_boxed(port);
+		zfcp_erp_port_boxed(port, 49, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
 		    | ZFCP_STATUS_FSFREQ_RETRY;
 		    | ZFCP_STATUS_FSFREQ_RETRY;
 		break;
 		break;
@@ -1624,9 +1559,6 @@ zfcp_fsf_send_ct_handler(struct zfcp_fsf_req *fsf_req)
        default:
        default:
 		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
 		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
 				"(debug info 0x%x)\n", header->fsf_status);
 				"(debug info 0x%x)\n", header->fsf_status);
-		debug_text_event(adapter->erp_dbf, 0, "fsf_sq_inval:");
-		debug_exception(adapter->erp_dbf, 0,
-				&header->fsf_status_qual.word[0], sizeof (u32));
 		break;
 		break;
 	}
 	}
 
 
@@ -1810,21 +1742,18 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req)
 			      zfcp_get_busid_by_adapter(adapter),
 			      zfcp_get_busid_by_adapter(adapter),
 			      ZFCP_FC_SERVICE_CLASS_DEFAULT);
 			      ZFCP_FC_SERVICE_CLASS_DEFAULT);
 		/* stop operation for this adapter */
 		/* stop operation for this adapter */
-		debug_text_exception(adapter->erp_dbf, 0, "fsf_s_class_nsup");
-		zfcp_erp_adapter_shutdown(adapter, 0);
+		zfcp_erp_adapter_shutdown(adapter, 0, 124, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		switch (header->fsf_status_qual.word[0]){
 		switch (header->fsf_status_qual.word[0]){
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-			debug_text_event(adapter->erp_dbf, 1, "fsf_sq_ltest");
 			if (port && (send_els->ls_code != ZFCP_LS_ADISC))
 			if (port && (send_els->ls_code != ZFCP_LS_ADISC))
 				zfcp_test_link(port);
 				zfcp_test_link(port);
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 			break;
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
-			debug_text_event(adapter->erp_dbf, 1, "fsf_sq_ulp");
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			retval =
 			retval =
 			  zfcp_handle_els_rjt(header->fsf_status_qual.word[1],
 			  zfcp_handle_els_rjt(header->fsf_status_qual.word[1],
@@ -1832,7 +1761,6 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req)
 					      &header->fsf_status_qual.word[2]);
 					      &header->fsf_status_qual.word[2]);
 			break;
 			break;
 		case FSF_SQ_RETRY_IF_POSSIBLE:
 		case FSF_SQ_RETRY_IF_POSSIBLE:
-			debug_text_event(adapter->erp_dbf, 1, "fsf_sq_retry");
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 			break;
 		default:
 		default:
@@ -1909,9 +1837,8 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req)
 				break;
 				break;
 			}
 			}
 		}
 		}
-		debug_text_event(adapter->erp_dbf, 1, "fsf_s_access");
 		if (port != NULL)
 		if (port != NULL)
-			zfcp_erp_port_access_denied(port);
+			zfcp_erp_port_access_denied(port, 56, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -1921,9 +1848,6 @@ static int zfcp_fsf_send_els_handler(struct zfcp_fsf_req *fsf_req)
 			"(adapter: %s, fsf_status=0x%08x)\n",
 			"(adapter: %s, fsf_status=0x%08x)\n",
 			zfcp_get_busid_by_adapter(adapter),
 			zfcp_get_busid_by_adapter(adapter),
 			header->fsf_status);
 			header->fsf_status);
-		debug_text_event(adapter->erp_dbf, 0, "fsf_sq_inval");
-		debug_exception(adapter->erp_dbf, 0,
-			&header->fsf_status_qual.word[0], sizeof(u32));
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 	}
 	}
@@ -2132,8 +2056,7 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
 				"versions in comparison to this device "
 				"versions in comparison to this device "
 				"driver (try updated device driver)\n",
 				"driver (try updated device driver)\n",
 				zfcp_get_busid_by_adapter(adapter));
 				zfcp_get_busid_by_adapter(adapter));
-		debug_text_event(adapter->erp_dbf, 0, "low_qtcb_ver");
-		zfcp_erp_adapter_shutdown(adapter, 0);
+		zfcp_erp_adapter_shutdown(adapter, 0, 125, fsf_req);
 		return -EIO;
 		return -EIO;
 	}
 	}
 	if (ZFCP_QTCB_VERSION > bottom->high_qtcb_version) {
 	if (ZFCP_QTCB_VERSION > bottom->high_qtcb_version) {
@@ -2142,8 +2065,7 @@ zfcp_fsf_exchange_config_evaluate(struct zfcp_fsf_req *fsf_req, int xchg_ok)
 				"versions than this device driver uses"
 				"versions than this device driver uses"
 				"(consider a microcode upgrade)\n",
 				"(consider a microcode upgrade)\n",
 				zfcp_get_busid_by_adapter(adapter));
 				zfcp_get_busid_by_adapter(adapter));
-		debug_text_event(adapter->erp_dbf, 0, "high_qtcb_ver");
-		zfcp_erp_adapter_shutdown(adapter, 0);
+		zfcp_erp_adapter_shutdown(adapter, 0, 126, fsf_req);
 		return -EIO;
 		return -EIO;
 	}
 	}
 	return 0;
 	return 0;
@@ -2183,17 +2105,13 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
 					adapter->peer_wwnn,
 					adapter->peer_wwnn,
 					adapter->peer_wwpn,
 					adapter->peer_wwpn,
 					adapter->peer_d_id);
 					adapter->peer_d_id);
-			debug_text_event(fsf_req->adapter->erp_dbf, 0,
-					"top-p-to-p");
 			break;
 			break;
 		case FC_PORTTYPE_NLPORT:
 		case FC_PORTTYPE_NLPORT:
 			ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel "
 			ZFCP_LOG_NORMAL("error: Arbitrated loop fibrechannel "
 					"topology detected at adapter %s "
 					"topology detected at adapter %s "
 					"unsupported, shutting down adapter\n",
 					"unsupported, shutting down adapter\n",
 					zfcp_get_busid_by_adapter(adapter));
 					zfcp_get_busid_by_adapter(adapter));
-			debug_text_event(fsf_req->adapter->erp_dbf, 0,
-					 "top-al");
-			zfcp_erp_adapter_shutdown(adapter, 0);
+			zfcp_erp_adapter_shutdown(adapter, 0, 127, fsf_req);
 			return -EIO;
 			return -EIO;
 		case FC_PORTTYPE_NPORT:
 		case FC_PORTTYPE_NPORT:
 			ZFCP_LOG_NORMAL("Switched fabric fibrechannel "
 			ZFCP_LOG_NORMAL("Switched fabric fibrechannel "
@@ -2208,9 +2126,7 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
 					"of a type known to the zfcp "
 					"of a type known to the zfcp "
 					"driver, shutting down adapter\n",
 					"driver, shutting down adapter\n",
 					zfcp_get_busid_by_adapter(adapter));
 					zfcp_get_busid_by_adapter(adapter));
-			debug_text_exception(fsf_req->adapter->erp_dbf, 0,
-					     "unknown-topo");
-			zfcp_erp_adapter_shutdown(adapter, 0);
+			zfcp_erp_adapter_shutdown(adapter, 0, 128, fsf_req);
 			return -EIO;
 			return -EIO;
 		}
 		}
 		bottom = &qtcb->bottom.config;
 		bottom = &qtcb->bottom.config;
@@ -2222,33 +2138,24 @@ zfcp_fsf_exchange_config_data_handler(struct zfcp_fsf_req *fsf_req)
 					bottom->max_qtcb_size,
 					bottom->max_qtcb_size,
 					zfcp_get_busid_by_adapter(adapter),
 					zfcp_get_busid_by_adapter(adapter),
 					sizeof(struct fsf_qtcb));
 					sizeof(struct fsf_qtcb));
-			debug_text_event(fsf_req->adapter->erp_dbf, 0,
-					 "qtcb-size");
-			debug_event(fsf_req->adapter->erp_dbf, 0,
-				    &bottom->max_qtcb_size, sizeof (u32));
-			zfcp_erp_adapter_shutdown(adapter, 0);
+			zfcp_erp_adapter_shutdown(adapter, 0, 129, fsf_req);
 			return -EIO;
 			return -EIO;
 		}
 		}
 		atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
 		atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
 				&adapter->status);
 				&adapter->status);
 		break;
 		break;
 	case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
 	case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
-		debug_text_event(adapter->erp_dbf, 0, "xchg-inco");
-
 		if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0))
 		if (zfcp_fsf_exchange_config_evaluate(fsf_req, 0))
 			return -EIO;
 			return -EIO;
 
 
 		atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
 		atomic_set_mask(ZFCP_STATUS_ADAPTER_XCONFIG_OK,
 				&adapter->status);
 				&adapter->status);
 
 
-		zfcp_fsf_link_down_info_eval(adapter,
+		zfcp_fsf_link_down_info_eval(fsf_req, 42,
 			&qtcb->header.fsf_status_qual.link_down_info);
 			&qtcb->header.fsf_status_qual.link_down_info);
 		break;
 		break;
 	default:
 	default:
-		debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf-stat-ng");
-		debug_event(fsf_req->adapter->erp_dbf, 0,
-			    &fsf_req->qtcb->header.fsf_status, sizeof(u32));
-		zfcp_erp_adapter_shutdown(adapter, 0);
+		zfcp_erp_adapter_shutdown(adapter, 0, 130, fsf_req);
 		return -EIO;
 		return -EIO;
 	}
 	}
 	return 0;
 	return 0;
@@ -2424,13 +2331,9 @@ zfcp_fsf_exchange_port_data_handler(struct zfcp_fsf_req *fsf_req)
 	case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
 	case FSF_EXCHANGE_CONFIG_DATA_INCOMPLETE:
 		zfcp_fsf_exchange_port_evaluate(fsf_req, 0);
 		zfcp_fsf_exchange_port_evaluate(fsf_req, 0);
 		atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
 		atomic_set_mask(ZFCP_STATUS_ADAPTER_XPORT_OK, &adapter->status);
-		zfcp_fsf_link_down_info_eval(adapter,
+		zfcp_fsf_link_down_info_eval(fsf_req, 43,
 			&qtcb->header.fsf_status_qual.link_down_info);
 			&qtcb->header.fsf_status_qual.link_down_info);
                 break;
                 break;
-        default:
-		debug_text_event(adapter->erp_dbf, 0, "xchg-port-ng");
-		debug_event(adapter->erp_dbf, 0,
-			    &fsf_req->qtcb->header.fsf_status, sizeof(u32));
 	}
 	}
 }
 }
 
 
@@ -2528,8 +2431,6 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_LOG_NORMAL("bug: remote port 0x%016Lx on adapter %s "
 		ZFCP_LOG_NORMAL("bug: remote port 0x%016Lx on adapter %s "
 				"is already open.\n",
 				"is already open.\n",
 				port->wwpn, zfcp_get_busid_by_port(port));
 				port->wwpn, zfcp_get_busid_by_port(port));
-		debug_text_exception(fsf_req->adapter->erp_dbf, 0,
-				     "fsf_s_popen");
 		/*
 		/*
 		 * This is a bug, however operation should continue normally
 		 * This is a bug, however operation should continue normally
 		 * if it is simply ignored
 		 * if it is simply ignored
@@ -2553,8 +2454,7 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
 				break;
 				break;
 			}
 			}
 		}
 		}
-		debug_text_event(fsf_req->adapter->erp_dbf, 1, "fsf_s_access");
-		zfcp_erp_port_access_denied(port);
+		zfcp_erp_port_access_denied(port, 57, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -2563,24 +2463,18 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
 			      "The remote port 0x%016Lx on adapter %s "
 			      "The remote port 0x%016Lx on adapter %s "
 			      "could not be opened. Disabling it.\n",
 			      "could not be opened. Disabling it.\n",
 			      port->wwpn, zfcp_get_busid_by_port(port));
 			      port->wwpn, zfcp_get_busid_by_port(port));
-		debug_text_event(fsf_req->adapter->erp_dbf, 1,
-				 "fsf_s_max_ports");
-		zfcp_erp_port_failed(port);
+		zfcp_erp_port_failed(port, 31, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		switch (header->fsf_status_qual.word[0]) {
 		switch (header->fsf_status_qual.word[0]) {
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-			debug_text_event(fsf_req->adapter->erp_dbf, 1,
-					 "fsf_sq_ltest");
 			/* ERP strategy will escalate */
 			/* ERP strategy will escalate */
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 			break;
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 			/* ERP strategy will escalate */
 			/* ERP strategy will escalate */
-			debug_text_event(fsf_req->adapter->erp_dbf, 1,
-					 "fsf_sq_ulp");
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 			break;
 		case FSF_SQ_NO_RETRY_POSSIBLE:
 		case FSF_SQ_NO_RETRY_POSSIBLE:
@@ -2589,21 +2483,13 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
 					"Disabling it.\n",
 					"Disabling it.\n",
 					port->wwpn,
 					port->wwpn,
 					zfcp_get_busid_by_port(port));
 					zfcp_get_busid_by_port(port));
-			debug_text_exception(fsf_req->adapter->erp_dbf, 0,
-					     "fsf_sq_no_retry");
-			zfcp_erp_port_failed(port);
+			zfcp_erp_port_failed(port, 32, fsf_req);
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 			break;
 		default:
 		default:
 			ZFCP_LOG_NORMAL
 			ZFCP_LOG_NORMAL
 			    ("bug: Wrong status qualifier 0x%x arrived.\n",
 			    ("bug: Wrong status qualifier 0x%x arrived.\n",
 			     header->fsf_status_qual.word[0]);
 			     header->fsf_status_qual.word[0]);
-			debug_text_event(fsf_req->adapter->erp_dbf, 0,
-					 "fsf_sq_inval:");
-			debug_exception(
-				fsf_req->adapter->erp_dbf, 0,
-				&header->fsf_status_qual.word[0],
-				sizeof (u32));
 			break;
 			break;
 		}
 		}
 		break;
 		break;
@@ -2646,17 +2532,12 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
 					"warning: insufficient length of "
 					"warning: insufficient length of "
 					"PLOGI payload (%i)\n",
 					"PLOGI payload (%i)\n",
 					fsf_req->qtcb->bottom.support.els1_length);
 					fsf_req->qtcb->bottom.support.els1_length);
-				debug_text_event(fsf_req->adapter->erp_dbf, 0,
-						 "fsf_s_short_plogi:");
 				/* skip sanity check and assume wwpn is ok */
 				/* skip sanity check and assume wwpn is ok */
 			} else {
 			} else {
 				if (plogi->serv_param.wwpn != port->wwpn) {
 				if (plogi->serv_param.wwpn != port->wwpn) {
 					ZFCP_LOG_INFO("warning: d_id of port "
 					ZFCP_LOG_INFO("warning: d_id of port "
 						      "0x%016Lx changed during "
 						      "0x%016Lx changed during "
 						      "open\n", port->wwpn);
 						      "open\n", port->wwpn);
-					debug_text_event(
-						fsf_req->adapter->erp_dbf, 0,
-						"fsf_s_did_change:");
 					atomic_clear_mask(
 					atomic_clear_mask(
 						ZFCP_STATUS_PORT_DID_DID,
 						ZFCP_STATUS_PORT_DID_DID,
 						&port->status);
 						&port->status);
@@ -2681,9 +2562,6 @@ zfcp_fsf_open_port_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
 		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
 				"(debug info 0x%x)\n",
 				"(debug info 0x%x)\n",
 				header->fsf_status);
 				header->fsf_status);
-		debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf_s_inval:");
-		debug_exception(fsf_req->adapter->erp_dbf, 0,
-				&header->fsf_status, sizeof (u32));
 		break;
 		break;
 	}
 	}
 
 
@@ -2787,9 +2665,7 @@ zfcp_fsf_close_port_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
 			      (char *) &fsf_req->qtcb->header.fsf_status_qual,
 			      (char *) &fsf_req->qtcb->header.fsf_status_qual,
 			      sizeof (union fsf_status_qual));
 			      sizeof (union fsf_status_qual));
-		debug_text_event(fsf_req->adapter->erp_dbf, 1,
-				 "fsf_s_phand_nv");
-		zfcp_erp_adapter_reopen(port->adapter, 0);
+		zfcp_erp_adapter_reopen(port->adapter, 0, 107, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -2804,7 +2680,7 @@ zfcp_fsf_close_port_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_LOG_TRACE("remote port 0x016%Lx on adapter %s closed, "
 		ZFCP_LOG_TRACE("remote port 0x016%Lx on adapter %s closed, "
 			       "port handle 0x%x\n", port->wwpn,
 			       "port handle 0x%x\n", port->wwpn,
 			       zfcp_get_busid_by_port(port), port->handle);
 			       zfcp_get_busid_by_port(port), port->handle);
-		zfcp_erp_modify_port_status(port,
+		zfcp_erp_modify_port_status(port, 33, fsf_req,
 					    ZFCP_STATUS_COMMON_OPEN,
 					    ZFCP_STATUS_COMMON_OPEN,
 					    ZFCP_CLEAR);
 					    ZFCP_CLEAR);
 		retval = 0;
 		retval = 0;
@@ -2814,10 +2690,6 @@ zfcp_fsf_close_port_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
 		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
 				"(debug info 0x%x)\n",
 				"(debug info 0x%x)\n",
 				fsf_req->qtcb->header.fsf_status);
 				fsf_req->qtcb->header.fsf_status);
-		debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf_s_inval:");
-		debug_exception(fsf_req->adapter->erp_dbf, 0,
-				&fsf_req->qtcb->header.fsf_status,
-				sizeof (u32));
 		break;
 		break;
 	}
 	}
 
 
@@ -2930,9 +2802,7 @@ zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
 			      (char *) &header->fsf_status_qual,
 			      (char *) &header->fsf_status_qual,
 			      sizeof (union fsf_status_qual));
 			      sizeof (union fsf_status_qual));
-		debug_text_event(fsf_req->adapter->erp_dbf, 1,
-				 "fsf_s_phand_nv");
-		zfcp_erp_adapter_reopen(port->adapter, 0);
+		zfcp_erp_adapter_reopen(port->adapter, 0, 108, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -2953,8 +2823,7 @@ zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req)
 				break;
 				break;
 			}
 			}
 		}
 		}
-		debug_text_event(fsf_req->adapter->erp_dbf, 1, "fsf_s_access");
-		zfcp_erp_port_access_denied(port);
+		zfcp_erp_port_access_denied(port, 58, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -2964,35 +2833,32 @@ zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req)
 			       "to close it physically.\n",
 			       "to close it physically.\n",
 			       port->wwpn,
 			       port->wwpn,
 			       zfcp_get_busid_by_port(port));
 			       zfcp_get_busid_by_port(port));
-		debug_text_event(fsf_req->adapter->erp_dbf, 1, "fsf_s_pboxed");
-		zfcp_erp_port_boxed(port);
+		zfcp_erp_port_boxed(port, 50, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
 			ZFCP_STATUS_FSFREQ_RETRY;
 			ZFCP_STATUS_FSFREQ_RETRY;
+
+		/* can't use generic zfcp_erp_modify_port_status because
+		 * ZFCP_STATUS_COMMON_OPEN must not be reset for the port */
+		atomic_clear_mask(ZFCP_STATUS_PORT_PHYS_OPEN, &port->status);
+		list_for_each_entry(unit, &port->unit_list_head, list)
+			atomic_clear_mask(ZFCP_STATUS_COMMON_OPEN,
+					  &unit->status);
 		break;
 		break;
 
 
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 	case FSF_ADAPTER_STATUS_AVAILABLE:
 		switch (header->fsf_status_qual.word[0]) {
 		switch (header->fsf_status_qual.word[0]) {
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
-			debug_text_event(fsf_req->adapter->erp_dbf, 1,
-					 "fsf_sq_ltest");
 			/* This will now be escalated by ERP */
 			/* This will now be escalated by ERP */
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 			break;
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 			/* ERP strategy will escalate */
 			/* ERP strategy will escalate */
-			debug_text_event(fsf_req->adapter->erp_dbf, 1,
-					 "fsf_sq_ulp");
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 			break;
 		default:
 		default:
 			ZFCP_LOG_NORMAL
 			ZFCP_LOG_NORMAL
 			    ("bug: Wrong status qualifier 0x%x arrived.\n",
 			    ("bug: Wrong status qualifier 0x%x arrived.\n",
 			     header->fsf_status_qual.word[0]);
 			     header->fsf_status_qual.word[0]);
-			debug_text_event(fsf_req->adapter->erp_dbf, 0,
-					 "fsf_sq_inval:");
-			debug_exception(
-				fsf_req->adapter->erp_dbf, 0,
-				&header->fsf_status_qual.word[0], sizeof (u32));
 			break;
 			break;
 		}
 		}
 		break;
 		break;
@@ -3015,9 +2881,6 @@ zfcp_fsf_close_physical_port_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
 		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
 				"(debug info 0x%x)\n",
 				"(debug info 0x%x)\n",
 				header->fsf_status);
 				header->fsf_status);
-		debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf_s_inval:");
-		debug_exception(fsf_req->adapter->erp_dbf, 0,
-				&header->fsf_status, sizeof (u32));
 		break;
 		break;
 	}
 	}
 
 
@@ -3149,8 +3012,7 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
 			      (char *) &header->fsf_status_qual,
 			      (char *) &header->fsf_status_qual,
 			      sizeof (union fsf_status_qual));
 			      sizeof (union fsf_status_qual));
-		debug_text_event(adapter->erp_dbf, 1, "fsf_s_ph_nv");
-		zfcp_erp_adapter_reopen(unit->port->adapter, 0);
+		zfcp_erp_adapter_reopen(unit->port->adapter, 0, 109, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -3159,8 +3021,6 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
 				"remote port 0x%016Lx on adapter %s twice.\n",
 				"remote port 0x%016Lx on adapter %s twice.\n",
 				unit->fcp_lun,
 				unit->fcp_lun,
 				unit->port->wwpn, zfcp_get_busid_by_unit(unit));
 				unit->port->wwpn, zfcp_get_busid_by_unit(unit));
-		debug_text_exception(adapter->erp_dbf, 0,
-				     "fsf_s_uopen");
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -3182,8 +3042,7 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
 				break;
 				break;
 			}
 			}
 		}
 		}
-		debug_text_event(adapter->erp_dbf, 1, "fsf_s_access");
-		zfcp_erp_unit_access_denied(unit);
+		zfcp_erp_unit_access_denied(unit, 59, fsf_req);
 		atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status);
 		atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status);
                 atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status);
                 atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -3193,8 +3052,7 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter %s "
 		ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter %s "
 			       "needs to be reopened\n",
 			       "needs to be reopened\n",
 			       unit->port->wwpn, zfcp_get_busid_by_unit(unit));
 			       unit->port->wwpn, zfcp_get_busid_by_unit(unit));
-		debug_text_event(adapter->erp_dbf, 2, "fsf_s_pboxed");
-		zfcp_erp_port_boxed(unit->port);
+		zfcp_erp_port_boxed(unit->port, 51, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
 			ZFCP_STATUS_FSFREQ_RETRY;
 			ZFCP_STATUS_FSFREQ_RETRY;
 		break;
 		break;
@@ -3234,9 +3092,7 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
 			      (char *) &header->fsf_status_qual,
 			      (char *) &header->fsf_status_qual,
 			      sizeof (union fsf_status_qual));
 			      sizeof (union fsf_status_qual));
-		debug_text_event(adapter->erp_dbf, 2,
-				 "fsf_s_l_sh_vio");
-		zfcp_erp_unit_access_denied(unit);
+		zfcp_erp_unit_access_denied(unit, 60, fsf_req);
 		atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status);
 		atomic_clear_mask(ZFCP_STATUS_UNIT_SHARED, &unit->status);
 		atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status);
 		atomic_clear_mask(ZFCP_STATUS_UNIT_READONLY, &unit->status);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -3250,9 +3106,7 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
 			      unit->fcp_lun,
 			      unit->fcp_lun,
 			      unit->port->wwpn,
 			      unit->port->wwpn,
 			      zfcp_get_busid_by_unit(unit));
 			      zfcp_get_busid_by_unit(unit));
-		debug_text_event(adapter->erp_dbf, 1,
-				 "fsf_s_max_units");
-		zfcp_erp_unit_failed(unit);
+		zfcp_erp_unit_failed(unit, 34, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -3260,26 +3114,17 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
 		switch (header->fsf_status_qual.word[0]) {
 		switch (header->fsf_status_qual.word[0]) {
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
 			/* Re-establish link to port */
 			/* Re-establish link to port */
-			debug_text_event(adapter->erp_dbf, 1,
-					 "fsf_sq_ltest");
 			zfcp_test_link(unit->port);
 			zfcp_test_link(unit->port);
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 			break;
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 			/* ERP strategy will escalate */
 			/* ERP strategy will escalate */
-			debug_text_event(adapter->erp_dbf, 1,
-					 "fsf_sq_ulp");
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 			break;
 		default:
 		default:
 			ZFCP_LOG_NORMAL
 			ZFCP_LOG_NORMAL
 			    ("bug: Wrong status qualifier 0x%x arrived.\n",
 			    ("bug: Wrong status qualifier 0x%x arrived.\n",
 			     header->fsf_status_qual.word[0]);
 			     header->fsf_status_qual.word[0]);
-			debug_text_event(adapter->erp_dbf, 0,
-					 "fsf_sq_inval:");
-			debug_exception(adapter->erp_dbf, 0,
-					&header->fsf_status_qual.word[0],
-				sizeof (u32));
 		}
 		}
 		break;
 		break;
 
 
@@ -3331,15 +3176,15 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
         		if (exclusive && !readwrite) {
         		if (exclusive && !readwrite) {
                 		ZFCP_LOG_NORMAL("exclusive access of read-only "
                 		ZFCP_LOG_NORMAL("exclusive access of read-only "
 						"unit not supported\n");
 						"unit not supported\n");
-				zfcp_erp_unit_failed(unit);
+				zfcp_erp_unit_failed(unit, 35, fsf_req);
 				fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 				fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
-				zfcp_erp_unit_shutdown(unit, 0);
+				zfcp_erp_unit_shutdown(unit, 0, 80, fsf_req);
         		} else if (!exclusive && readwrite) {
         		} else if (!exclusive && readwrite) {
                 		ZFCP_LOG_NORMAL("shared access of read-write "
                 		ZFCP_LOG_NORMAL("shared access of read-write "
 						"unit not supported\n");
 						"unit not supported\n");
-                		zfcp_erp_unit_failed(unit);
+				zfcp_erp_unit_failed(unit, 36, fsf_req);
 				fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 				fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
-				zfcp_erp_unit_shutdown(unit, 0);
+				zfcp_erp_unit_shutdown(unit, 0, 81, fsf_req);
         		}
         		}
 		}
 		}
 
 
@@ -3350,9 +3195,6 @@ zfcp_fsf_open_unit_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
 		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
 				"(debug info 0x%x)\n",
 				"(debug info 0x%x)\n",
 				header->fsf_status);
 				header->fsf_status);
-		debug_text_event(adapter->erp_dbf, 0, "fsf_s_inval:");
-		debug_exception(adapter->erp_dbf, 0,
-				&header->fsf_status, sizeof (u32));
 		break;
 		break;
 	}
 	}
 
 
@@ -3465,9 +3307,7 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
 			      (char *) &fsf_req->qtcb->header.fsf_status_qual,
 			      (char *) &fsf_req->qtcb->header.fsf_status_qual,
 			      sizeof (union fsf_status_qual));
 			      sizeof (union fsf_status_qual));
-		debug_text_event(fsf_req->adapter->erp_dbf, 1,
-				 "fsf_s_phand_nv");
-		zfcp_erp_adapter_reopen(unit->port->adapter, 0);
+		zfcp_erp_adapter_reopen(unit->port->adapter, 0, 110, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -3483,9 +3323,7 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
 			      (char *) &fsf_req->qtcb->header.fsf_status_qual,
 			      (char *) &fsf_req->qtcb->header.fsf_status_qual,
 			      sizeof (union fsf_status_qual));
 			      sizeof (union fsf_status_qual));
-		debug_text_event(fsf_req->adapter->erp_dbf, 1,
-				 "fsf_s_lhand_nv");
-		zfcp_erp_port_reopen(unit->port, 0);
+		zfcp_erp_port_reopen(unit->port, 0, 111, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -3494,8 +3332,7 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req)
 			       "needs to be reopened\n",
 			       "needs to be reopened\n",
 			       unit->port->wwpn,
 			       unit->port->wwpn,
 			       zfcp_get_busid_by_unit(unit));
 			       zfcp_get_busid_by_unit(unit));
-		debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_s_pboxed");
-		zfcp_erp_port_boxed(unit->port);
+		zfcp_erp_port_boxed(unit->port, 52, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
 			ZFCP_STATUS_FSFREQ_RETRY;
 			ZFCP_STATUS_FSFREQ_RETRY;
 		break;
 		break;
@@ -3504,27 +3341,17 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req)
 		switch (fsf_req->qtcb->header.fsf_status_qual.word[0]) {
 		switch (fsf_req->qtcb->header.fsf_status_qual.word[0]) {
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
 			/* re-establish link to port */
 			/* re-establish link to port */
-			debug_text_event(fsf_req->adapter->erp_dbf, 1,
-					 "fsf_sq_ltest");
 			zfcp_test_link(unit->port);
 			zfcp_test_link(unit->port);
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 			break;
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 			/* ERP strategy will escalate */
 			/* ERP strategy will escalate */
-			debug_text_event(fsf_req->adapter->erp_dbf, 1,
-					 "fsf_sq_ulp");
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 			break;
 			break;
 		default:
 		default:
 			ZFCP_LOG_NORMAL
 			ZFCP_LOG_NORMAL
 			    ("bug: Wrong status qualifier 0x%x arrived.\n",
 			    ("bug: Wrong status qualifier 0x%x arrived.\n",
 			     fsf_req->qtcb->header.fsf_status_qual.word[0]);
 			     fsf_req->qtcb->header.fsf_status_qual.word[0]);
-			debug_text_event(fsf_req->adapter->erp_dbf, 0,
-					 "fsf_sq_inval:");
-			debug_exception(
-				fsf_req->adapter->erp_dbf, 0,
-				&fsf_req->qtcb->header.fsf_status_qual.word[0],
-				sizeof (u32));
 			break;
 			break;
 		}
 		}
 		break;
 		break;
@@ -3545,10 +3372,6 @@ zfcp_fsf_close_unit_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
 		ZFCP_LOG_NORMAL("bug: An unknown FSF Status was presented "
 				"(debug info 0x%x)\n",
 				"(debug info 0x%x)\n",
 				fsf_req->qtcb->header.fsf_status);
 				fsf_req->qtcb->header.fsf_status);
-		debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf_s_inval:");
-		debug_exception(fsf_req->adapter->erp_dbf, 0,
-				&fsf_req->qtcb->header.fsf_status,
-				sizeof (u32));
 		break;
 		break;
 	}
 	}
 
 
@@ -3703,7 +3526,7 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
 					zfcp_get_busid_by_unit(unit),
 					zfcp_get_busid_by_unit(unit),
 					unit->port->wwpn,
 					unit->port->wwpn,
 					unit->fcp_lun);
 					unit->fcp_lun);
-			zfcp_erp_unit_shutdown(unit, 0);
+			zfcp_erp_unit_shutdown(unit, 0, 131, fsf_req);
 			retval = -EINVAL;
 			retval = -EINVAL;
 		}
 		}
 		goto no_fit;
 		goto no_fit;
@@ -3739,8 +3562,8 @@ zfcp_fsf_send_fcp_command_task(struct zfcp_adapter *adapter,
  send_failed:
  send_failed:
  no_fit:
  no_fit:
  failed_scsi_cmnd:
  failed_scsi_cmnd:
- unit_blocked:
 	zfcp_unit_put(unit);
 	zfcp_unit_put(unit);
+ unit_blocked:
 	zfcp_fsf_req_free(fsf_req);
 	zfcp_fsf_req_free(fsf_req);
 	fsf_req = NULL;
 	fsf_req = NULL;
 	scsi_cmnd->host_scribble = NULL;
 	scsi_cmnd->host_scribble = NULL;
@@ -3861,9 +3684,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
 			      (char *) &header->fsf_status_qual,
 			      (char *) &header->fsf_status_qual,
 			      sizeof (union fsf_status_qual));
 			      sizeof (union fsf_status_qual));
-		debug_text_event(fsf_req->adapter->erp_dbf, 1,
-				 "fsf_s_phand_nv");
-		zfcp_erp_adapter_reopen(unit->port->adapter, 0);
+		zfcp_erp_adapter_reopen(unit->port->adapter, 0, 112, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -3879,9 +3700,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
 			      (char *) &header->fsf_status_qual,
 			      (char *) &header->fsf_status_qual,
 			      sizeof (union fsf_status_qual));
 			      sizeof (union fsf_status_qual));
-		debug_text_event(fsf_req->adapter->erp_dbf, 1,
-				 "fsf_s_uhand_nv");
-		zfcp_erp_port_reopen(unit->port, 0);
+		zfcp_erp_port_reopen(unit->port, 0, 113, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -3897,9 +3716,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_NORMAL,
 			      (char *) &header->fsf_status_qual,
 			      (char *) &header->fsf_status_qual,
 			      sizeof (union fsf_status_qual));
 			      sizeof (union fsf_status_qual));
-		debug_text_event(fsf_req->adapter->erp_dbf, 1,
-				 "fsf_s_hand_mis");
-		zfcp_erp_adapter_reopen(unit->port->adapter, 0);
+		zfcp_erp_adapter_reopen(unit->port->adapter, 0, 114, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -3909,9 +3726,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
 			      zfcp_get_busid_by_unit(unit),
 			      zfcp_get_busid_by_unit(unit),
 			      ZFCP_FC_SERVICE_CLASS_DEFAULT);
 			      ZFCP_FC_SERVICE_CLASS_DEFAULT);
 		/* stop operation for this adapter */
 		/* stop operation for this adapter */
-		debug_text_exception(fsf_req->adapter->erp_dbf, 0,
-				     "fsf_s_class_nsup");
-		zfcp_erp_adapter_shutdown(unit->port->adapter, 0);
+		zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 132, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -3927,9 +3742,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
 		ZFCP_HEX_DUMP(ZFCP_LOG_LEVEL_DEBUG,
 			      (char *) &header->fsf_status_qual,
 			      (char *) &header->fsf_status_qual,
 			      sizeof (union fsf_status_qual));
 			      sizeof (union fsf_status_qual));
-		debug_text_event(fsf_req->adapter->erp_dbf, 1,
-				 "fsf_s_fcp_lun_nv");
-		zfcp_erp_port_reopen(unit->port, 0);
+		zfcp_erp_port_reopen(unit->port, 0, 115, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -3951,8 +3764,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
 				break;
 				break;
 			}
 			}
 		}
 		}
-		debug_text_event(fsf_req->adapter->erp_dbf, 1, "fsf_s_access");
-		zfcp_erp_unit_access_denied(unit);
+		zfcp_erp_unit_access_denied(unit, 61, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -3965,9 +3777,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
 			      zfcp_get_busid_by_unit(unit),
 			      zfcp_get_busid_by_unit(unit),
 			      fsf_req->qtcb->bottom.io.data_direction);
 			      fsf_req->qtcb->bottom.io.data_direction);
 		/* stop operation for this adapter */
 		/* stop operation for this adapter */
-		debug_text_event(fsf_req->adapter->erp_dbf, 0,
-				 "fsf_s_dir_ind_nv");
-		zfcp_erp_adapter_shutdown(unit->port->adapter, 0);
+		zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 133, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -3980,9 +3790,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
 		     zfcp_get_busid_by_unit(unit),
 		     zfcp_get_busid_by_unit(unit),
 		     fsf_req->qtcb->bottom.io.fcp_cmnd_length);
 		     fsf_req->qtcb->bottom.io.fcp_cmnd_length);
 		/* stop operation for this adapter */
 		/* stop operation for this adapter */
-		debug_text_event(fsf_req->adapter->erp_dbf, 0,
-				 "fsf_s_cmd_len_nv");
-		zfcp_erp_adapter_shutdown(unit->port->adapter, 0);
+		zfcp_erp_adapter_shutdown(unit->port->adapter, 0, 134, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		break;
 		break;
 
 
@@ -3990,8 +3798,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
 		ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter %s "
 		ZFCP_LOG_DEBUG("The remote port 0x%016Lx on adapter %s "
 			       "needs to be reopened\n",
 			       "needs to be reopened\n",
 			       unit->port->wwpn, zfcp_get_busid_by_unit(unit));
 			       unit->port->wwpn, zfcp_get_busid_by_unit(unit));
-		debug_text_event(fsf_req->adapter->erp_dbf, 2, "fsf_s_pboxed");
-		zfcp_erp_port_boxed(unit->port);
+		zfcp_erp_port_boxed(unit->port, 53, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR |
 			ZFCP_STATUS_FSFREQ_RETRY;
 			ZFCP_STATUS_FSFREQ_RETRY;
 		break;
 		break;
@@ -4001,8 +3808,7 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
 				"wwpn=0x%016Lx, fcp_lun=0x%016Lx)\n",
 				"wwpn=0x%016Lx, fcp_lun=0x%016Lx)\n",
 				zfcp_get_busid_by_unit(unit),
 				zfcp_get_busid_by_unit(unit),
 				unit->port->wwpn, unit->fcp_lun);
 				unit->port->wwpn, unit->fcp_lun);
-		debug_text_event(fsf_req->adapter->erp_dbf, 1, "fsf_s_lboxed");
-		zfcp_erp_unit_boxed(unit);
+		zfcp_erp_unit_boxed(unit, 54, fsf_req);
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR
 			| ZFCP_STATUS_FSFREQ_RETRY;
 			| ZFCP_STATUS_FSFREQ_RETRY;
 		break;
 		break;
@@ -4011,25 +3817,16 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
 		switch (header->fsf_status_qual.word[0]) {
 		switch (header->fsf_status_qual.word[0]) {
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
 		case FSF_SQ_INVOKE_LINK_TEST_PROCEDURE:
 			/* re-establish link to port */
 			/* re-establish link to port */
-			debug_text_event(fsf_req->adapter->erp_dbf, 1,
-					 "fsf_sq_ltest");
  			zfcp_test_link(unit->port);
  			zfcp_test_link(unit->port);
 			break;
 			break;
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 		case FSF_SQ_ULP_DEPENDENT_ERP_REQUIRED:
 			/* FIXME(hw) need proper specs for proper action */
 			/* FIXME(hw) need proper specs for proper action */
 			/* let scsi stack deal with retries and escalation */
 			/* let scsi stack deal with retries and escalation */
-			debug_text_event(fsf_req->adapter->erp_dbf, 1,
-					 "fsf_sq_ulp");
 			break;
 			break;
 		default:
 		default:
 			ZFCP_LOG_NORMAL
 			ZFCP_LOG_NORMAL
  			    ("Unknown status qualifier 0x%x arrived.\n",
  			    ("Unknown status qualifier 0x%x arrived.\n",
 			     header->fsf_status_qual.word[0]);
 			     header->fsf_status_qual.word[0]);
-			debug_text_event(fsf_req->adapter->erp_dbf, 0,
-					 "fsf_sq_inval:");
-			debug_exception(fsf_req->adapter->erp_dbf, 0,
-					&header->fsf_status_qual.word[0],
-					sizeof(u32));
 			break;
 			break;
 		}
 		}
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
@@ -4040,12 +3837,6 @@ zfcp_fsf_send_fcp_command_handler(struct zfcp_fsf_req *fsf_req)
 
 
 	case FSF_FCP_RSP_AVAILABLE:
 	case FSF_FCP_RSP_AVAILABLE:
 		break;
 		break;
-
-	default:
-		debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf_s_inval:");
-		debug_exception(fsf_req->adapter->erp_dbf, 0,
-				&header->fsf_status, sizeof(u32));
-		break;
 	}
 	}
 
 
  skip_fsfstatus:
  skip_fsfstatus:
@@ -4625,9 +4416,6 @@ zfcp_fsf_control_file_handler(struct zfcp_fsf_req *fsf_req)
 			"was presented on the adapter %s\n",
 			"was presented on the adapter %s\n",
 			header->fsf_status,
 			header->fsf_status,
 			zfcp_get_busid_by_adapter(adapter));
 			zfcp_get_busid_by_adapter(adapter));
-		debug_text_event(fsf_req->adapter->erp_dbf, 0, "fsf_sq_inval");
-		debug_exception(fsf_req->adapter->erp_dbf, 0,
-			&header->fsf_status_qual.word[0], sizeof(u32));
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		fsf_req->status |= ZFCP_STATUS_FSFREQ_ERROR;
 		retval = -EINVAL;
 		retval = -EINVAL;
 		break;
 		break;
@@ -4817,7 +4605,6 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req)
 	volatile struct qdio_buffer_element *sbale;
 	volatile struct qdio_buffer_element *sbale;
 	int inc_seq_no;
 	int inc_seq_no;
 	int new_distance_from_int;
 	int new_distance_from_int;
-	u64 dbg_tmp[2];
 	int retval = 0;
 	int retval = 0;
 
 
 	adapter = fsf_req->adapter;
 	adapter = fsf_req->adapter;
@@ -4867,10 +4654,6 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req)
 			 QDIO_FLAG_SYNC_OUTPUT,
 			 QDIO_FLAG_SYNC_OUTPUT,
 			 0, fsf_req->sbal_first, fsf_req->sbal_number, NULL);
 			 0, fsf_req->sbal_first, fsf_req->sbal_number, NULL);
 
 
-	dbg_tmp[0] = (unsigned long) sbale[0].addr;
-	dbg_tmp[1] = (u64) retval;
-	debug_event(adapter->erp_dbf, 4, (void *) dbg_tmp, 16);
-
 	if (unlikely(retval)) {
 	if (unlikely(retval)) {
 		/* Queues are down..... */
 		/* Queues are down..... */
 		retval = -EIO;
 		retval = -EIO;
@@ -4885,7 +4668,7 @@ static int zfcp_fsf_req_send(struct zfcp_fsf_req *fsf_req)
 		req_queue->free_index -= fsf_req->sbal_number;
 		req_queue->free_index -= fsf_req->sbal_number;
 		req_queue->free_index += QDIO_MAX_BUFFERS_PER_Q;
 		req_queue->free_index += QDIO_MAX_BUFFERS_PER_Q;
 		req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; /* wrap */
 		req_queue->free_index %= QDIO_MAX_BUFFERS_PER_Q; /* wrap */
-		zfcp_erp_adapter_reopen(adapter, 0);
+		zfcp_erp_adapter_reopen(adapter, 0, 116, fsf_req);
 	} else {
 	} else {
 		req_queue->distance_from_int = new_distance_from_int;
 		req_queue->distance_from_int = new_distance_from_int;
 		/*
 		/*

+ 3 - 4
drivers/s390/scsi/zfcp_qdio.c

@@ -175,8 +175,9 @@ zfcp_qdio_handler_error_check(struct zfcp_adapter *adapter, unsigned int status,
                 * which is set again in case we have missed by a mile.
                 * which is set again in case we have missed by a mile.
                 */
                 */
 		zfcp_erp_adapter_reopen(adapter,
 		zfcp_erp_adapter_reopen(adapter,
-				       ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
-				       ZFCP_STATUS_COMMON_ERP_FAILED);
+					ZFCP_STATUS_ADAPTER_LINK_UNPLUGGED |
+					ZFCP_STATUS_COMMON_ERP_FAILED, 140,
+					NULL);
 	}
 	}
 	return retval;
 	return retval;
 }
 }
@@ -239,8 +240,6 @@ static void zfcp_qdio_reqid_check(struct zfcp_adapter *adapter,
 	struct zfcp_fsf_req *fsf_req;
 	struct zfcp_fsf_req *fsf_req;
 	unsigned long flags;
 	unsigned long flags;
 
 
-	debug_long_event(adapter->erp_dbf, 4, req_id);
-
 	spin_lock_irqsave(&adapter->req_list_lock, flags);
 	spin_lock_irqsave(&adapter->req_list_lock, flags);
 	fsf_req = zfcp_reqlist_find(adapter, req_id);
 	fsf_req = zfcp_reqlist_find(adapter, req_id);
 
 

+ 22 - 47
drivers/s390/scsi/zfcp_scsi.c

@@ -31,6 +31,7 @@ static int zfcp_scsi_queuecommand(struct scsi_cmnd *,
 				  void (*done) (struct scsi_cmnd *));
 				  void (*done) (struct scsi_cmnd *));
 static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *);
 static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *);
 static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *);
 static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *);
+static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *);
 static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *);
 static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *);
 static int zfcp_task_management_function(struct zfcp_unit *, u8,
 static int zfcp_task_management_function(struct zfcp_unit *, u8,
 					 struct scsi_cmnd *);
 					 struct scsi_cmnd *);
@@ -51,6 +52,7 @@ struct zfcp_data zfcp_data = {
 		.queuecommand		= zfcp_scsi_queuecommand,
 		.queuecommand		= zfcp_scsi_queuecommand,
 		.eh_abort_handler	= zfcp_scsi_eh_abort_handler,
 		.eh_abort_handler	= zfcp_scsi_eh_abort_handler,
 		.eh_device_reset_handler = zfcp_scsi_eh_device_reset_handler,
 		.eh_device_reset_handler = zfcp_scsi_eh_device_reset_handler,
+		.eh_target_reset_handler = zfcp_scsi_eh_target_reset_handler,
 		.eh_host_reset_handler	= zfcp_scsi_eh_host_reset_handler,
 		.eh_host_reset_handler	= zfcp_scsi_eh_host_reset_handler,
 		.can_queue		= 4096,
 		.can_queue		= 4096,
 		.this_id		= -1,
 		.this_id		= -1,
@@ -179,11 +181,10 @@ static void zfcp_scsi_slave_destroy(struct scsi_device *sdpnt)
 	struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata;
 	struct zfcp_unit *unit = (struct zfcp_unit *) sdpnt->hostdata;
 
 
 	if (unit) {
 	if (unit) {
-		zfcp_erp_wait(unit->port->adapter);
 		atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status);
 		atomic_clear_mask(ZFCP_STATUS_UNIT_REGISTERED, &unit->status);
 		sdpnt->hostdata = NULL;
 		sdpnt->hostdata = NULL;
 		unit->device = NULL;
 		unit->device = NULL;
-		zfcp_erp_unit_failed(unit);
+		zfcp_erp_unit_failed(unit, 12, NULL);
 		zfcp_unit_put(unit);
 		zfcp_unit_put(unit);
 	} else
 	} else
 		ZFCP_LOG_NORMAL("bug: no unit associated with SCSI device at "
 		ZFCP_LOG_NORMAL("bug: no unit associated with SCSI device at "
@@ -442,58 +443,32 @@ static int zfcp_scsi_eh_abort_handler(struct scsi_cmnd *scpnt)
 	return retval;
 	return retval;
 }
 }
 
 
-static int
-zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
+static int zfcp_scsi_eh_device_reset_handler(struct scsi_cmnd *scpnt)
 {
 {
 	int retval;
 	int retval;
-	struct zfcp_unit *unit = (struct zfcp_unit *) scpnt->device->hostdata;
+	struct zfcp_unit *unit = scpnt->device->hostdata;
 
 
 	if (!unit) {
 	if (!unit) {
-		ZFCP_LOG_NORMAL("bug: Tried reset for nonexistent unit\n");
-		retval = SUCCESS;
-		goto out;
+		WARN_ON(1);
+		return SUCCESS;
 	}
 	}
-	ZFCP_LOG_NORMAL("resetting unit 0x%016Lx on port 0x%016Lx, adapter %s\n",
-			unit->fcp_lun, unit->port->wwpn,
-			zfcp_get_busid_by_adapter(unit->port->adapter));
+	retval = zfcp_task_management_function(unit,
+					       FCP_LOGICAL_UNIT_RESET,
+					       scpnt);
+	return retval ? FAILED : SUCCESS;
+}
 
 
-	/*
-	 * If we do not know whether the unit supports 'logical unit reset'
-	 * then try 'logical unit reset' and proceed with 'target reset'
-	 * if 'logical unit reset' fails.
-	 * If the unit is known not to support 'logical unit reset' then
-	 * skip 'logical unit reset' and try 'target reset' immediately.
-	 */
-	if (!atomic_test_mask(ZFCP_STATUS_UNIT_NOTSUPPUNITRESET,
-			      &unit->status)) {
-		retval = zfcp_task_management_function(unit,
-						       FCP_LOGICAL_UNIT_RESET,
-						       scpnt);
-		if (retval) {
-			ZFCP_LOG_DEBUG("unit reset failed (unit=%p)\n", unit);
-			if (retval == -ENOTSUPP)
-				atomic_set_mask
-				    (ZFCP_STATUS_UNIT_NOTSUPPUNITRESET,
-				     &unit->status);
-			/* fall through and try 'target reset' next */
-		} else {
-			ZFCP_LOG_DEBUG("unit reset succeeded (unit=%p)\n",
-				       unit);
-			/* avoid 'target reset' */
-			retval = SUCCESS;
-			goto out;
-		}
+static int zfcp_scsi_eh_target_reset_handler(struct scsi_cmnd *scpnt)
+{
+	int retval;
+	struct zfcp_unit *unit = scpnt->device->hostdata;
+
+	if (!unit) {
+		WARN_ON(1);
+		return SUCCESS;
 	}
 	}
 	retval = zfcp_task_management_function(unit, FCP_TARGET_RESET, scpnt);
 	retval = zfcp_task_management_function(unit, FCP_TARGET_RESET, scpnt);
-	if (retval) {
-		ZFCP_LOG_DEBUG("target reset failed (unit=%p)\n", unit);
-		retval = FAILED;
-	} else {
-		ZFCP_LOG_DEBUG("target reset succeeded (unit=%p)\n", unit);
-		retval = SUCCESS;
-	}
- out:
-	return retval;
+	return retval ? FAILED : SUCCESS;
 }
 }
 
 
 static int
 static int
@@ -553,7 +528,7 @@ static int zfcp_scsi_eh_host_reset_handler(struct scsi_cmnd *scpnt)
 		unit->fcp_lun, unit->port->wwpn,
 		unit->fcp_lun, unit->port->wwpn,
 		zfcp_get_busid_by_adapter(unit->port->adapter));
 		zfcp_get_busid_by_adapter(unit->port->adapter));
 
 
-	zfcp_erp_adapter_reopen(adapter, 0);
+	zfcp_erp_adapter_reopen(adapter, 0, 141, scpnt);
 	zfcp_erp_wait(adapter);
 	zfcp_erp_wait(adapter);
 
 
 	return SUCCESS;
 	return SUCCESS;

+ 6 - 5
drivers/s390/scsi/zfcp_sysfs_adapter.c

@@ -89,7 +89,7 @@ zfcp_sysfs_port_add_store(struct device *dev, struct device_attribute *attr, con
 
 
 	retval = 0;
 	retval = 0;
 
 
-	zfcp_erp_port_reopen(port, 0);
+	zfcp_erp_port_reopen(port, 0, 91, NULL);
 	zfcp_erp_wait(port->adapter);
 	zfcp_erp_wait(port->adapter);
 	zfcp_port_put(port);
 	zfcp_port_put(port);
  out:
  out:
@@ -147,7 +147,7 @@ zfcp_sysfs_port_remove_store(struct device *dev, struct device_attribute *attr,
 		goto out;
 		goto out;
 	}
 	}
 
 
-	zfcp_erp_port_shutdown(port, 0);
+	zfcp_erp_port_shutdown(port, 0, 92, NULL);
 	zfcp_erp_wait(adapter);
 	zfcp_erp_wait(adapter);
 	zfcp_port_put(port);
 	zfcp_port_put(port);
 	zfcp_port_dequeue(port);
 	zfcp_port_dequeue(port);
@@ -191,9 +191,10 @@ zfcp_sysfs_adapter_failed_store(struct device *dev, struct device_attribute *att
 		goto out;
 		goto out;
 	}
 	}
 
 
-	zfcp_erp_modify_adapter_status(adapter, ZFCP_STATUS_COMMON_RUNNING,
-				       ZFCP_SET);
-	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED);
+	zfcp_erp_modify_adapter_status(adapter, 44, NULL,
+				       ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
+	zfcp_erp_adapter_reopen(adapter, ZFCP_STATUS_COMMON_ERP_FAILED, 93,
+				NULL);
 	zfcp_erp_wait(adapter);
 	zfcp_erp_wait(adapter);
  out:
  out:
 	up(&zfcp_data.config_sema);
 	up(&zfcp_data.config_sema);

+ 5 - 4
drivers/s390/scsi/zfcp_sysfs_port.c

@@ -94,7 +94,7 @@ zfcp_sysfs_unit_add_store(struct device *dev, struct device_attribute *attr, con
 
 
 	retval = 0;
 	retval = 0;
 
 
-	zfcp_erp_unit_reopen(unit, 0);
+	zfcp_erp_unit_reopen(unit, 0, 94, NULL);
 	zfcp_erp_wait(unit->port->adapter);
 	zfcp_erp_wait(unit->port->adapter);
 	zfcp_unit_put(unit);
 	zfcp_unit_put(unit);
  out:
  out:
@@ -150,7 +150,7 @@ zfcp_sysfs_unit_remove_store(struct device *dev, struct device_attribute *attr,
 		goto out;
 		goto out;
 	}
 	}
 
 
-	zfcp_erp_unit_shutdown(unit, 0);
+	zfcp_erp_unit_shutdown(unit, 0, 95, NULL);
 	zfcp_erp_wait(unit->port->adapter);
 	zfcp_erp_wait(unit->port->adapter);
 	zfcp_unit_put(unit);
 	zfcp_unit_put(unit);
 	zfcp_unit_dequeue(unit);
 	zfcp_unit_dequeue(unit);
@@ -193,8 +193,9 @@ zfcp_sysfs_port_failed_store(struct device *dev, struct device_attribute *attr,
 		goto out;
 		goto out;
 	}
 	}
 
 
-	zfcp_erp_modify_port_status(port, ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
-	zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED);
+	zfcp_erp_modify_port_status(port, 45, NULL,
+				    ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
+	zfcp_erp_port_reopen(port, ZFCP_STATUS_COMMON_ERP_FAILED, 96, NULL);
 	zfcp_erp_wait(port->adapter);
 	zfcp_erp_wait(port->adapter);
  out:
  out:
 	up(&zfcp_data.config_sema);
 	up(&zfcp_data.config_sema);

+ 3 - 2
drivers/s390/scsi/zfcp_sysfs_unit.c

@@ -94,8 +94,9 @@ zfcp_sysfs_unit_failed_store(struct device *dev, struct device_attribute *attr,
 		goto out;
 		goto out;
 	}
 	}
 
 
-	zfcp_erp_modify_unit_status(unit, ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
-	zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED);
+	zfcp_erp_modify_unit_status(unit, 46, NULL,
+				    ZFCP_STATUS_COMMON_RUNNING, ZFCP_SET);
+	zfcp_erp_unit_reopen(unit, ZFCP_STATUS_COMMON_ERP_FAILED, 97, NULL);
 	zfcp_erp_wait(unit->port->adapter);
 	zfcp_erp_wait(unit->port->adapter);
  out:
  out:
 	up(&zfcp_data.config_sema);
 	up(&zfcp_data.config_sema);

+ 9 - 14
drivers/scsi/3w-9xxx.c

@@ -1838,12 +1838,11 @@ static int twa_scsiop_execute_scsi(TW_Device_Extension *tw_dev, int request_id,
 		if (scsi_sg_count(srb)) {
 		if (scsi_sg_count(srb)) {
 			if ((scsi_sg_count(srb) == 1) &&
 			if ((scsi_sg_count(srb) == 1) &&
 			    (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
 			    (scsi_bufflen(srb) < TW_MIN_SGL_LENGTH)) {
-				if (srb->sc_data_direction == DMA_TO_DEVICE || srb->sc_data_direction == DMA_BIDIRECTIONAL) {
-					struct scatterlist *sg = scsi_sglist(srb);
-					char *buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
-					memcpy(tw_dev->generic_buffer_virt[request_id], buf, sg->length);
-					kunmap_atomic(buf - sg->offset, KM_IRQ0);
-				}
+				if (srb->sc_data_direction == DMA_TO_DEVICE ||
+				    srb->sc_data_direction == DMA_BIDIRECTIONAL)
+					scsi_sg_copy_to_buffer(srb,
+							       tw_dev->generic_buffer_virt[request_id],
+							       TW_SECTOR_SIZE);
 				command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
 				command_packet->sg_list[0].address = TW_CPU_TO_SGL(tw_dev->generic_buffer_phys[request_id]);
 				command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH);
 				command_packet->sg_list[0].length = cpu_to_le32(TW_MIN_SGL_LENGTH);
 			} else {
 			} else {
@@ -1915,13 +1914,11 @@ static void twa_scsiop_execute_scsi_complete(TW_Device_Extension *tw_dev, int re
 	    (cmd->sc_data_direction == DMA_FROM_DEVICE ||
 	    (cmd->sc_data_direction == DMA_FROM_DEVICE ||
 	     cmd->sc_data_direction == DMA_BIDIRECTIONAL)) {
 	     cmd->sc_data_direction == DMA_BIDIRECTIONAL)) {
 		if (scsi_sg_count(cmd) == 1) {
 		if (scsi_sg_count(cmd) == 1) {
-			struct scatterlist *sg = scsi_sglist(tw_dev->srb[request_id]);
-			char *buf;
-			unsigned long flags = 0;
+			unsigned long flags;
+			void *buf = tw_dev->generic_buffer_virt[request_id];
+
 			local_irq_save(flags);
 			local_irq_save(flags);
-			buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
-			memcpy(buf, tw_dev->generic_buffer_virt[request_id], sg->length);
-			kunmap_atomic(buf - sg->offset, KM_IRQ0);
+			scsi_sg_copy_from_buffer(cmd, buf, TW_SECTOR_SIZE);
 			local_irq_restore(flags);
 			local_irq_restore(flags);
 		}
 		}
 	}
 	}
@@ -2028,8 +2025,6 @@ static int __devinit twa_probe(struct pci_dev *pdev, const struct pci_device_id
 	}
 	}
 	tw_dev = (TW_Device_Extension *)host->hostdata;
 	tw_dev = (TW_Device_Extension *)host->hostdata;
 
 
-	memset(tw_dev, 0, sizeof(TW_Device_Extension));
-
 	/* Save values to device extension */
 	/* Save values to device extension */
 	tw_dev->host = host;
 	tw_dev->host = host;
 	tw_dev->tw_pci_dev = pdev;
 	tw_dev->tw_pci_dev = pdev;

+ 2 - 12
drivers/scsi/3w-xxxx.c

@@ -1463,18 +1463,10 @@ static void tw_transfer_internal(TW_Device_Extension *tw_dev, int request_id,
 				 void *data, unsigned int len)
 				 void *data, unsigned int len)
 {
 {
 	struct scsi_cmnd *cmd = tw_dev->srb[request_id];
 	struct scsi_cmnd *cmd = tw_dev->srb[request_id];
-	void *buf;
-	unsigned int transfer_len;
-	unsigned long flags = 0;
-	struct scatterlist *sg = scsi_sglist(cmd);
+	unsigned long flags;
 
 
 	local_irq_save(flags);
 	local_irq_save(flags);
-	buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
-	transfer_len = min(sg->length, len);
-
-	memcpy(buf, data, transfer_len);
-
-	kunmap_atomic(buf - sg->offset, KM_IRQ0);
+	scsi_sg_copy_from_buffer(cmd, data, len);
 	local_irq_restore(flags);
 	local_irq_restore(flags);
 }
 }
 
 
@@ -2294,8 +2286,6 @@ static int __devinit tw_probe(struct pci_dev *pdev, const struct pci_device_id *
 	}
 	}
 	tw_dev = (TW_Device_Extension *)host->hostdata;
 	tw_dev = (TW_Device_Extension *)host->hostdata;
 
 
-	memset(tw_dev, 0, sizeof(TW_Device_Extension));
-
 	/* Save values to device extension */
 	/* Save values to device extension */
 	tw_dev->host = host;
 	tw_dev->host = host;
 	tw_dev->tw_pci_dev = pdev;
 	tw_dev->tw_pci_dev = pdev;

+ 4 - 1
drivers/scsi/BusLogic.c

@@ -896,7 +896,7 @@ static int __init BusLogic_InitializeFlashPointProbeInfo(struct BusLogic_HostAda
 		IRQ_Channel = PCI_Device->irq;
 		IRQ_Channel = PCI_Device->irq;
 		IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0);
 		IO_Address = BaseAddress0 = pci_resource_start(PCI_Device, 0);
 		PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
 		PCI_Address = BaseAddress1 = pci_resource_start(PCI_Device, 1);
-#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
+#ifdef CONFIG_SCSI_FLASHPOINT
 		if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) {
 		if (pci_resource_flags(PCI_Device, 0) & IORESOURCE_MEM) {
 			BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, BaseAddress0);
 			BusLogic_Error("BusLogic: Base Address0 0x%X not I/O for " "FlashPoint Host Adapter\n", NULL, BaseAddress0);
 			BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
 			BusLogic_Error("at PCI Bus %d Device %d I/O Address 0x%X\n", NULL, Bus, Device, IO_Address);
@@ -1006,6 +1006,9 @@ static void __init BusLogic_InitializeProbeInfoList(struct BusLogic_HostAdapter
 }
 }
 
 
 
 
+#else
+#define BusLogic_InitializeProbeInfoList(adapter) \
+		BusLogic_InitializeProbeInfoListISA(adapter)
 #endif				/* CONFIG_PCI */
 #endif				/* CONFIG_PCI */
 
 
 
 

+ 2 - 19
drivers/scsi/BusLogic.h

@@ -33,23 +33,6 @@
 #define PACKED __attribute__((packed))
 #define PACKED __attribute__((packed))
 #endif
 #endif
 
 
-/*
-  FlashPoint support is only available for the Intel x86 Architecture with
-  CONFIG_PCI set.
-*/
-
-#ifndef __i386__
-#undef CONFIG_SCSI_OMIT_FLASHPOINT
-#define CONFIG_SCSI_OMIT_FLASHPOINT
-#endif
-
-#ifndef CONFIG_PCI
-#undef CONFIG_SCSI_OMIT_FLASHPOINT
-#define CONFIG_SCSI_OMIT_FLASHPOINT
-#define BusLogic_InitializeProbeInfoListISA BusLogic_InitializeProbeInfoList
-#endif
-
-
 /*
 /*
   Define the maximum number of BusLogic Host Adapters supported by this driver.
   Define the maximum number of BusLogic Host Adapters supported by this driver.
 */
 */
@@ -178,7 +161,7 @@ static int BusLogic_HostAdapterAddressCount[3] = { 0, BusLogic_MultiMasterAddres
   Define macros for testing the Host Adapter Type.
   Define macros for testing the Host Adapter Type.
 */
 */
 
 
-#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
+#ifdef CONFIG_SCSI_FLASHPOINT
 
 
 #define BusLogic_MultiMasterHostAdapterP(HostAdapter) \
 #define BusLogic_MultiMasterHostAdapterP(HostAdapter) \
   (HostAdapter->HostAdapterType == BusLogic_MultiMaster)
   (HostAdapter->HostAdapterType == BusLogic_MultiMaster)
@@ -871,7 +854,7 @@ struct BusLogic_CCB {
 	void (*CallbackFunction) (struct BusLogic_CCB *);	/* Bytes 40-43 */
 	void (*CallbackFunction) (struct BusLogic_CCB *);	/* Bytes 40-43 */
 	u32 BaseAddress;	/* Bytes 44-47 */
 	u32 BaseAddress;	/* Bytes 44-47 */
 	enum BusLogic_CompletionCode CompletionCode;	/* Byte 48 */
 	enum BusLogic_CompletionCode CompletionCode;	/* Byte 48 */
-#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
+#ifdef CONFIG_SCSI_FLASHPOINT
 	unsigned char:8;	/* Byte 49 */
 	unsigned char:8;	/* Byte 49 */
 	unsigned short OS_Flags;	/* Bytes 50-51 */
 	unsigned short OS_Flags;	/* Bytes 50-51 */
 	unsigned char Private[48];	/* Bytes 52-99 */
 	unsigned char Private[48];	/* Bytes 52-99 */

+ 3 - 3
drivers/scsi/FlashPoint.c

@@ -16,7 +16,7 @@
 */
 */
 
 
 
 
-#ifndef CONFIG_SCSI_OMIT_FLASHPOINT
+#ifdef CONFIG_SCSI_FLASHPOINT
 
 
 #define MAX_CARDS	8
 #define MAX_CARDS	8
 #undef BUSTYPE_PCI
 #undef BUSTYPE_PCI
@@ -7626,7 +7626,7 @@ FlashPoint__HandleInterrupt(FlashPoint_CardHandle_T CardHandle)
 #define FlashPoint_InterruptPending	    FlashPoint__InterruptPending
 #define FlashPoint_InterruptPending	    FlashPoint__InterruptPending
 #define FlashPoint_HandleInterrupt	    FlashPoint__HandleInterrupt
 #define FlashPoint_HandleInterrupt	    FlashPoint__HandleInterrupt
 
 
-#else				/* CONFIG_SCSI_OMIT_FLASHPOINT */
+#else				/* !CONFIG_SCSI_FLASHPOINT */
 
 
 /*
 /*
   Define prototypes for the FlashPoint SCCB Manager Functions.
   Define prototypes for the FlashPoint SCCB Manager Functions.
@@ -7641,4 +7641,4 @@ extern bool FlashPoint_InterruptPending(FlashPoint_CardHandle_T);
 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
 extern int FlashPoint_HandleInterrupt(FlashPoint_CardHandle_T);
 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
 extern void FlashPoint_ReleaseHostAdapter(FlashPoint_CardHandle_T);
 
 
-#endif				/* CONFIG_SCSI_OMIT_FLASHPOINT */
+#endif				/* CONFIG_SCSI_FLASHPOINT */

+ 8 - 6
drivers/scsi/Kconfig

@@ -588,18 +588,20 @@ config SCSI_BUSLOGIC
 	  <http://www.tldp.org/docs.html#howto>, and the files
 	  <http://www.tldp.org/docs.html#howto>, and the files
 	  <file:Documentation/scsi/BusLogic.txt> and
 	  <file:Documentation/scsi/BusLogic.txt> and
 	  <file:Documentation/scsi/FlashPoint.txt> for more information.
 	  <file:Documentation/scsi/FlashPoint.txt> for more information.
+	  Note that support for FlashPoint is only available for 32-bit
+	  x86 configurations.
 
 
 	  To compile this driver as a module, choose M here: the
 	  To compile this driver as a module, choose M here: the
 	  module will be called BusLogic.
 	  module will be called BusLogic.
 
 
-config SCSI_OMIT_FLASHPOINT
-	bool "Omit FlashPoint support"
-	depends on SCSI_BUSLOGIC
+config SCSI_FLASHPOINT
+	bool "FlashPoint support"
+	depends on SCSI_BUSLOGIC && PCI && X86_32
 	help
 	help
-	  This option allows you to omit the FlashPoint support from the
+	  This option allows you to add FlashPoint support to the
 	  BusLogic SCSI driver. The FlashPoint SCCB Manager code is
 	  BusLogic SCSI driver. The FlashPoint SCCB Manager code is
-	  substantial, so users of MultiMaster Host Adapters may wish to omit
-	  it.
+	  substantial, so users of MultiMaster Host Adapters may not
+	  wish to include it.
 
 
 config SCSI_DMX3191D
 config SCSI_DMX3191D
 	tristate "DMX3191D SCSI support"
 	tristate "DMX3191D SCSI support"

+ 3 - 0
drivers/scsi/a2091.c

@@ -179,6 +179,9 @@ int __init a2091_detect(struct scsi_host_template *tpnt)
 	DMA(instance)->DAWR = DAWR_A2091;
 	DMA(instance)->DAWR = DAWR_A2091;
 	regs.SASR = &(DMA(instance)->SASR);
 	regs.SASR = &(DMA(instance)->SASR);
 	regs.SCMD = &(DMA(instance)->SCMD);
 	regs.SCMD = &(DMA(instance)->SCMD);
+	HDATA(instance)->no_sync = 0xff;
+	HDATA(instance)->fast = 0;
+	HDATA(instance)->dma_mode = CTRL_DMA;
 	wd33c93_init(instance, regs, dma_setup, dma_stop, WD33C93_FS_8_10);
 	wd33c93_init(instance, regs, dma_setup, dma_stop, WD33C93_FS_8_10);
 	request_irq(IRQ_AMIGA_PORTS, a2091_intr, IRQF_SHARED, "A2091 SCSI",
 	request_irq(IRQ_AMIGA_PORTS, a2091_intr, IRQF_SHARED, "A2091 SCSI",
 		    instance);
 		    instance);

+ 3 - 0
drivers/scsi/a3000.c

@@ -178,6 +178,9 @@ int __init a3000_detect(struct scsi_host_template *tpnt)
     DMA(a3000_host)->DAWR = DAWR_A3000;
     DMA(a3000_host)->DAWR = DAWR_A3000;
     regs.SASR = &(DMA(a3000_host)->SASR);
     regs.SASR = &(DMA(a3000_host)->SASR);
     regs.SCMD = &(DMA(a3000_host)->SCMD);
     regs.SCMD = &(DMA(a3000_host)->SCMD);
+    HDATA(a3000_host)->no_sync = 0xff;
+    HDATA(a3000_host)->fast = 0;
+    HDATA(a3000_host)->dma_mode = CTRL_DMA;
     wd33c93_init(a3000_host, regs, dma_setup, dma_stop, WD33C93_FS_12_15);
     wd33c93_init(a3000_host, regs, dma_setup, dma_stop, WD33C93_FS_12_15);
     if (request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED, "A3000 SCSI",
     if (request_irq(IRQ_AMIGA_PORTS, a3000_intr, IRQF_SHARED, "A3000 SCSI",
 		    a3000_intr))
 		    a3000_intr))

+ 27 - 42
drivers/scsi/aacraid/aachba.c

@@ -205,7 +205,7 @@ MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health"
 
 
 int aac_check_reset = 1;
 int aac_check_reset = 1;
 module_param_named(check_reset, aac_check_reset, int, S_IRUGO|S_IWUSR);
 module_param_named(check_reset, aac_check_reset, int, S_IRUGO|S_IWUSR);
-MODULE_PARM_DESC(aac_check_reset, "If adapter fails health check, reset the"
+MODULE_PARM_DESC(check_reset, "If adapter fails health check, reset the"
 	" adapter. a value of -1 forces the reset to adapters programmed to"
 	" adapter. a value of -1 forces the reset to adapters programmed to"
 	" ignore it.");
 	" ignore it.");
 
 
@@ -379,24 +379,6 @@ int aac_get_containers(struct aac_dev *dev)
 	return status;
 	return status;
 }
 }
 
 
-static void aac_internal_transfer(struct scsi_cmnd *scsicmd, void *data, unsigned int offset, unsigned int len)
-{
-	void *buf;
-	int transfer_len;
-	struct scatterlist *sg = scsi_sglist(scsicmd);
-
-	buf = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
-	transfer_len = min(sg->length, len + offset);
-
-	transfer_len -= offset;
-	if (buf && transfer_len > 0)
-		memcpy(buf + offset, data, transfer_len);
-
-	flush_kernel_dcache_page(kmap_atomic_to_page(buf - sg->offset));
-	kunmap_atomic(buf - sg->offset, KM_IRQ0);
-
-}
-
 static void get_container_name_callback(void *context, struct fib * fibptr)
 static void get_container_name_callback(void *context, struct fib * fibptr)
 {
 {
 	struct aac_get_name_resp * get_name_reply;
 	struct aac_get_name_resp * get_name_reply;
@@ -419,14 +401,17 @@ static void get_container_name_callback(void *context, struct fib * fibptr)
 		while (*sp == ' ')
 		while (*sp == ' ')
 			++sp;
 			++sp;
 		if (*sp) {
 		if (*sp) {
+			struct inquiry_data inq;
 			char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)];
 			char d[sizeof(((struct inquiry_data *)NULL)->inqd_pid)];
 			int count = sizeof(d);
 			int count = sizeof(d);
 			char *dp = d;
 			char *dp = d;
 			do {
 			do {
 				*dp++ = (*sp) ? *sp++ : ' ';
 				*dp++ = (*sp) ? *sp++ : ' ';
 			} while (--count > 0);
 			} while (--count > 0);
-			aac_internal_transfer(scsicmd, d,
-			  offsetof(struct inquiry_data, inqd_pid), sizeof(d));
+
+			scsi_sg_copy_to_buffer(scsicmd, &inq, sizeof(inq));
+			memcpy(inq.inqd_pid, d, sizeof(d));
+			scsi_sg_copy_from_buffer(scsicmd, &inq, sizeof(inq));
 		}
 		}
 	}
 	}
 
 
@@ -811,7 +796,7 @@ static void get_container_serial_callback(void *context, struct fib * fibptr)
 		sp[2] = 0;
 		sp[2] = 0;
 		sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X",
 		sp[3] = snprintf(sp+4, sizeof(sp)-4, "%08X",
 		  le32_to_cpu(get_serial_reply->uid));
 		  le32_to_cpu(get_serial_reply->uid));
-		aac_internal_transfer(scsicmd, sp, 0, sizeof(sp));
+		scsi_sg_copy_from_buffer(scsicmd, sp, sizeof(sp));
 	}
 	}
 
 
 	scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
 	scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
@@ -1986,8 +1971,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 				arr[4] = 0x0;
 				arr[4] = 0x0;
 				arr[5] = 0x80;
 				arr[5] = 0x80;
 				arr[1] = scsicmd->cmnd[2];
 				arr[1] = scsicmd->cmnd[2];
-				aac_internal_transfer(scsicmd, &inq_data, 0,
-				  sizeof(inq_data));
+				scsi_sg_copy_from_buffer(scsicmd, &inq_data,
+							 sizeof(inq_data));
 				scsicmd->result = DID_OK << 16 |
 				scsicmd->result = DID_OK << 16 |
 				  COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
 				  COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
 			} else if (scsicmd->cmnd[2] == 0x80) {
 			} else if (scsicmd->cmnd[2] == 0x80) {
@@ -1995,8 +1980,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 				arr[3] = setinqserial(dev, &arr[4],
 				arr[3] = setinqserial(dev, &arr[4],
 				  scmd_id(scsicmd));
 				  scmd_id(scsicmd));
 				arr[1] = scsicmd->cmnd[2];
 				arr[1] = scsicmd->cmnd[2];
-				aac_internal_transfer(scsicmd, &inq_data, 0,
-				  sizeof(inq_data));
+				scsi_sg_copy_from_buffer(scsicmd, &inq_data,
+							 sizeof(inq_data));
 				return aac_get_container_serial(scsicmd);
 				return aac_get_container_serial(scsicmd);
 			} else {
 			} else {
 				/* vpd page not implemented */
 				/* vpd page not implemented */
@@ -2027,7 +2012,8 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 		if (cid == host->this_id) {
 		if (cid == host->this_id) {
 			setinqstr(dev, (void *) (inq_data.inqd_vid), ARRAY_SIZE(container_types));
 			setinqstr(dev, (void *) (inq_data.inqd_vid), ARRAY_SIZE(container_types));
 			inq_data.inqd_pdt = INQD_PDT_PROC;	/* Processor device */
 			inq_data.inqd_pdt = INQD_PDT_PROC;	/* Processor device */
-			aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
+			scsi_sg_copy_from_buffer(scsicmd, &inq_data,
+						 sizeof(inq_data));
 			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
 			scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
 			scsicmd->scsi_done(scsicmd);
 			scsicmd->scsi_done(scsicmd);
 			return 0;
 			return 0;
@@ -2036,7 +2022,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 			return -1;
 			return -1;
 		setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type);
 		setinqstr(dev, (void *) (inq_data.inqd_vid), fsa_dev_ptr[cid].type);
 		inq_data.inqd_pdt = INQD_PDT_DA;	/* Direct/random access device */
 		inq_data.inqd_pdt = INQD_PDT_DA;	/* Direct/random access device */
-		aac_internal_transfer(scsicmd, &inq_data, 0, sizeof(inq_data));
+		scsi_sg_copy_from_buffer(scsicmd, &inq_data, sizeof(inq_data));
 		return aac_get_container_name(scsicmd);
 		return aac_get_container_name(scsicmd);
 	}
 	}
 	case SERVICE_ACTION_IN:
 	case SERVICE_ACTION_IN:
@@ -2047,6 +2033,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 	{
 	{
 		u64 capacity;
 		u64 capacity;
 		char cp[13];
 		char cp[13];
+		unsigned int alloc_len;
 
 
 		dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n"));
 		dprintk((KERN_DEBUG "READ CAPACITY_16 command.\n"));
 		capacity = fsa_dev_ptr[cid].size - 1;
 		capacity = fsa_dev_ptr[cid].size - 1;
@@ -2063,18 +2050,16 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 		cp[10] = 2;
 		cp[10] = 2;
 		cp[11] = 0;
 		cp[11] = 0;
 		cp[12] = 0;
 		cp[12] = 0;
-		aac_internal_transfer(scsicmd, cp, 0,
-		  min_t(size_t, scsicmd->cmnd[13], sizeof(cp)));
-		if (sizeof(cp) < scsicmd->cmnd[13]) {
-			unsigned int len, offset = sizeof(cp);
 
 
-			memset(cp, 0, offset);
-			do {
-				len = min_t(size_t, scsicmd->cmnd[13] - offset,
-						sizeof(cp));
-				aac_internal_transfer(scsicmd, cp, offset, len);
-			} while ((offset += len) < scsicmd->cmnd[13]);
-		}
+		alloc_len = ((scsicmd->cmnd[10] << 24)
+			     + (scsicmd->cmnd[11] << 16)
+			     + (scsicmd->cmnd[12] << 8) + scsicmd->cmnd[13]);
+
+		alloc_len = min_t(size_t, alloc_len, sizeof(cp));
+		scsi_sg_copy_from_buffer(scsicmd, cp, alloc_len);
+		if (alloc_len < scsi_bufflen(scsicmd))
+			scsi_set_resid(scsicmd,
+				       scsi_bufflen(scsicmd) - alloc_len);
 
 
 		/* Do not cache partition table for arrays */
 		/* Do not cache partition table for arrays */
 		scsicmd->device->removable = 1;
 		scsicmd->device->removable = 1;
@@ -2104,7 +2089,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 		cp[5] = 0;
 		cp[5] = 0;
 		cp[6] = 2;
 		cp[6] = 2;
 		cp[7] = 0;
 		cp[7] = 0;
-		aac_internal_transfer(scsicmd, cp, 0, sizeof(cp));
+		scsi_sg_copy_from_buffer(scsicmd, cp, sizeof(cp));
 		/* Do not cache partition table for arrays */
 		/* Do not cache partition table for arrays */
 		scsicmd->device->removable = 1;
 		scsicmd->device->removable = 1;
 
 
@@ -2139,7 +2124,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 			if (mode_buf_length > scsicmd->cmnd[4])
 			if (mode_buf_length > scsicmd->cmnd[4])
 				mode_buf_length = scsicmd->cmnd[4];
 				mode_buf_length = scsicmd->cmnd[4];
 		}
 		}
-		aac_internal_transfer(scsicmd, mode_buf, 0, mode_buf_length);
+		scsi_sg_copy_from_buffer(scsicmd, mode_buf, mode_buf_length);
 		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
 		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
 		scsicmd->scsi_done(scsicmd);
 		scsicmd->scsi_done(scsicmd);
 
 
@@ -2174,7 +2159,7 @@ int aac_scsi_cmd(struct scsi_cmnd * scsicmd)
 			if (mode_buf_length > scsicmd->cmnd[8])
 			if (mode_buf_length > scsicmd->cmnd[8])
 				mode_buf_length = scsicmd->cmnd[8];
 				mode_buf_length = scsicmd->cmnd[8];
 		}
 		}
-		aac_internal_transfer(scsicmd, mode_buf, 0, mode_buf_length);
+		scsi_sg_copy_from_buffer(scsicmd, mode_buf, mode_buf_length);
 
 
 		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
 		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
 		scsicmd->scsi_done(scsicmd);
 		scsicmd->scsi_done(scsicmd);

+ 6 - 4
drivers/scsi/aacraid/commsup.c

@@ -515,10 +515,12 @@ int aac_fib_send(u16 command, struct fib *fibptr, unsigned long size,
 				}
 				}
 				udelay(5);
 				udelay(5);
 			}
 			}
-		} else
-			(void)down_interruptible(&fibptr->event_wait);
+		} else if (down_interruptible(&fibptr->event_wait) == 0) {
+			fibptr->done = 2;
+			up(&fibptr->event_wait);
+		}
 		spin_lock_irqsave(&fibptr->event_lock, flags);
 		spin_lock_irqsave(&fibptr->event_lock, flags);
-		if (fibptr->done == 0) {
+		if ((fibptr->done == 0) || (fibptr->done == 2)) {
 			fibptr->done = 2; /* Tell interrupt we aborted */
 			fibptr->done = 2; /* Tell interrupt we aborted */
 			spin_unlock_irqrestore(&fibptr->event_lock, flags);
 			spin_unlock_irqrestore(&fibptr->event_lock, flags);
 			return -EINTR;
 			return -EINTR;
@@ -594,7 +596,7 @@ void aac_consumer_free(struct aac_dev * dev, struct aac_queue *q, u32 qid)
 	if (le32_to_cpu(*q->headers.consumer) >= q->entries)
 	if (le32_to_cpu(*q->headers.consumer) >= q->entries)
 		*q->headers.consumer = cpu_to_le32(1);
 		*q->headers.consumer = cpu_to_le32(1);
 	else
 	else
-		*q->headers.consumer = cpu_to_le32(le32_to_cpu(*q->headers.consumer)+1);
+		le32_add_cpu(q->headers.consumer, 1);
 
 
 	if (wasfull) {
 	if (wasfull) {
 		switch (qid) {
 		switch (qid) {

+ 5 - 2
drivers/scsi/aic7xxx/aic79xx_osm.c

@@ -1413,6 +1413,10 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
 	unsigned long flags;
 	unsigned long flags;
 	int nseg;
 	int nseg;
 
 
+	nseg = scsi_dma_map(cmd);
+	if (nseg < 0)
+		return SCSI_MLQUEUE_HOST_BUSY;
+
 	ahd_lock(ahd, &flags);
 	ahd_lock(ahd, &flags);
 
 
 	/*
 	/*
@@ -1430,6 +1434,7 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
 	if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) {
 	if ((scb = ahd_get_scb(ahd, col_idx)) == NULL) {
 		ahd->flags |= AHD_RESOURCE_SHORTAGE;
 		ahd->flags |= AHD_RESOURCE_SHORTAGE;
 		ahd_unlock(ahd, &flags);
 		ahd_unlock(ahd, &flags);
+		scsi_dma_unmap(cmd);
 		return SCSI_MLQUEUE_HOST_BUSY;
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 	}
 
 
@@ -1485,8 +1490,6 @@ ahd_linux_run_command(struct ahd_softc *ahd, struct ahd_linux_device *dev,
 	ahd_set_sense_residual(scb, 0);
 	ahd_set_sense_residual(scb, 0);
 	scb->sg_count = 0;
 	scb->sg_count = 0;
 
 
-	nseg = scsi_dma_map(cmd);
-	BUG_ON(nseg < 0);
 	if (nseg > 0) {
 	if (nseg > 0) {
 		void *sg = scb->sg_list;
 		void *sg = scb->sg_list;
 		struct scatterlist *cur_seg;
 		struct scatterlist *cur_seg;

+ 7 - 3
drivers/scsi/aic7xxx/aic7xxx_osm.c

@@ -1398,12 +1398,18 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
 			return SCSI_MLQUEUE_DEVICE_BUSY;
 			return SCSI_MLQUEUE_DEVICE_BUSY;
 	}
 	}
 
 
+	nseg = scsi_dma_map(cmd);
+	if (nseg < 0)
+		return SCSI_MLQUEUE_HOST_BUSY;
+
 	/*
 	/*
 	 * Get an scb to use.
 	 * Get an scb to use.
 	 */
 	 */
 	scb = ahc_get_scb(ahc);
 	scb = ahc_get_scb(ahc);
-	if (!scb)
+	if (!scb) {
+		scsi_dma_unmap(cmd);
 		return SCSI_MLQUEUE_HOST_BUSY;
 		return SCSI_MLQUEUE_HOST_BUSY;
+	}
 
 
 	scb->io_ctx = cmd;
 	scb->io_ctx = cmd;
 	scb->platform_data->dev = dev;
 	scb->platform_data->dev = dev;
@@ -1464,8 +1470,6 @@ ahc_linux_run_command(struct ahc_softc *ahc, struct ahc_linux_device *dev,
 	ahc_set_sense_residual(scb, 0);
 	ahc_set_sense_residual(scb, 0);
 	scb->sg_count = 0;
 	scb->sg_count = 0;
 
 
-	nseg = scsi_dma_map(cmd);
-	BUG_ON(nseg < 0);
 	if (nseg > 0) {
 	if (nseg > 0) {
 		struct	ahc_dma_seg *sg;
 		struct	ahc_dma_seg *sg;
 		struct	scatterlist *cur_seg;
 		struct	scatterlist *cur_seg;

+ 1 - 1
drivers/scsi/aic7xxx/aicasm/aicasm_gram.y

@@ -1837,7 +1837,7 @@ type_check(symbol_t *symbol, expression_t *expression, int opcode)
 	int and_op;
 	int and_op;
 
 
 	and_op = FALSE;
 	and_op = FALSE;
-	if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || AIC_OP_JZ)
+	if (opcode == AIC_OP_AND || opcode == AIC_OP_JNZ || opcode == AIC_OP_JZ)
 		and_op = TRUE;
 		and_op = TRUE;
 
 
 	/*
 	/*

+ 0 - 16
drivers/scsi/aic94xx/aic94xx.h

@@ -58,7 +58,6 @@
 
 
 extern struct kmem_cache *asd_dma_token_cache;
 extern struct kmem_cache *asd_dma_token_cache;
 extern struct kmem_cache *asd_ascb_cache;
 extern struct kmem_cache *asd_ascb_cache;
-extern char sas_addr_str[2*SAS_ADDR_SIZE + 1];
 
 
 static inline void asd_stringify_sas_addr(char *p, const u8 *sas_addr)
 static inline void asd_stringify_sas_addr(char *p, const u8 *sas_addr)
 {
 {
@@ -68,21 +67,6 @@ static inline void asd_stringify_sas_addr(char *p, const u8 *sas_addr)
 	*p = '\0';
 	*p = '\0';
 }
 }
 
 
-static inline void asd_destringify_sas_addr(u8 *sas_addr, const char *p)
-{
-	int i;
-	for (i = 0; i < SAS_ADDR_SIZE; i++) {
-		u8 h, l;
-		if (!*p)
-			break;
-		h = isdigit(*p) ? *p-'0' : *p-'A'+10;
-		p++;
-		l = isdigit(*p) ? *p-'0' : *p-'A'+10;
-		p++;
-		sas_addr[i] = (h<<4) | l;
-	}
-}
-
 struct asd_ha_struct;
 struct asd_ha_struct;
 struct asd_ascb;
 struct asd_ascb;
 
 

+ 4 - 4
drivers/scsi/aic94xx/aic94xx_dev.c

@@ -35,7 +35,7 @@
 #define SET_DDB(_ddb, _ha) set_bit(_ddb, (_ha)->hw_prof.ddb_bitmap)
 #define SET_DDB(_ddb, _ha) set_bit(_ddb, (_ha)->hw_prof.ddb_bitmap)
 #define CLEAR_DDB(_ddb, _ha) clear_bit(_ddb, (_ha)->hw_prof.ddb_bitmap)
 #define CLEAR_DDB(_ddb, _ha) clear_bit(_ddb, (_ha)->hw_prof.ddb_bitmap)
 
 
-static inline int asd_get_ddb(struct asd_ha_struct *asd_ha)
+static int asd_get_ddb(struct asd_ha_struct *asd_ha)
 {
 {
 	int ddb, i;
 	int ddb, i;
 
 
@@ -71,7 +71,7 @@ out:
 #define NCQ_DATA_SCB_PTR offsetof(struct asd_ddb_stp_sata_target_port, ncq_data_scb_ptr)
 #define NCQ_DATA_SCB_PTR offsetof(struct asd_ddb_stp_sata_target_port, ncq_data_scb_ptr)
 #define ITNL_TIMEOUT    offsetof(struct asd_ddb_ssp_smp_target_port, itnl_timeout)
 #define ITNL_TIMEOUT    offsetof(struct asd_ddb_ssp_smp_target_port, itnl_timeout)
 
 
-static inline void asd_free_ddb(struct asd_ha_struct *asd_ha, int ddb)
+static void asd_free_ddb(struct asd_ha_struct *asd_ha, int ddb)
 {
 {
 	if (!ddb || ddb >= 0xFFFF)
 	if (!ddb || ddb >= 0xFFFF)
 		return;
 		return;
@@ -79,7 +79,7 @@ static inline void asd_free_ddb(struct asd_ha_struct *asd_ha, int ddb)
 	CLEAR_DDB(ddb, asd_ha);
 	CLEAR_DDB(ddb, asd_ha);
 }
 }
 
 
-static inline void asd_set_ddb_type(struct domain_device *dev)
+static void asd_set_ddb_type(struct domain_device *dev)
 {
 {
 	struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
 	struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
 	int ddb = (int) (unsigned long) dev->lldd_dev;
 	int ddb = (int) (unsigned long) dev->lldd_dev;
@@ -109,7 +109,7 @@ static int asd_init_sata_tag_ddb(struct domain_device *dev)
 	return 0;
 	return 0;
 }
 }
 
 
-static inline int asd_init_sata(struct domain_device *dev)
+static int asd_init_sata(struct domain_device *dev)
 {
 {
 	struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
 	struct asd_ha_struct *asd_ha = dev->port->ha->lldd_ha;
 	int ddb = (int) (unsigned long) dev->lldd_dev;
 	int ddb = (int) (unsigned long) dev->lldd_dev;

+ 9 - 1
drivers/scsi/aic94xx/aic94xx_dump.c

@@ -738,6 +738,8 @@ static void asd_dump_lseq_state(struct asd_ha_struct *asd_ha, int lseq)
 	PRINT_LMIP_dword(asd_ha, lseq, DEV_PRES_TIMER_TERM_TS);
 	PRINT_LMIP_dword(asd_ha, lseq, DEV_PRES_TIMER_TERM_TS);
 }
 }
 
 
+#if 0
+
 /**
 /**
  * asd_dump_ddb_site -- dump a CSEQ DDB site
  * asd_dump_ddb_site -- dump a CSEQ DDB site
  * @asd_ha: pointer to host adapter structure
  * @asd_ha: pointer to host adapter structure
@@ -880,6 +882,8 @@ void asd_dump_scb_sites(struct asd_ha_struct *asd_ha)
 	}
 	}
 }
 }
 
 
+#endif  /*  0  */
+
 /**
 /**
  * ads_dump_seq_state -- dump CSEQ and LSEQ states
  * ads_dump_seq_state -- dump CSEQ and LSEQ states
  * @asd_ha: pointer to host adapter structure
  * @asd_ha: pointer to host adapter structure
@@ -922,7 +926,9 @@ void asd_dump_frame_rcvd(struct asd_phy *phy,
 	spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
 	spin_unlock_irqrestore(&phy->sas_phy.frame_rcvd_lock, flags);
 }
 }
 
 
-static inline void asd_dump_scb(struct asd_ascb *ascb, int ind)
+#if 0
+
+static void asd_dump_scb(struct asd_ascb *ascb, int ind)
 {
 {
 	asd_printk("scb%d: vaddr: 0x%p, dma_handle: 0x%llx, next: 0x%llx, "
 	asd_printk("scb%d: vaddr: 0x%p, dma_handle: 0x%llx, next: 0x%llx, "
 		   "index:%d, opcode:0x%02x\n",
 		   "index:%d, opcode:0x%02x\n",
@@ -956,4 +962,6 @@ void asd_dump_scb_list(struct asd_ascb *ascb, int num)
 	}
 	}
 }
 }
 
 
+#endif  /*  0  */
+
 #endif /* ASD_DEBUG */
 #endif /* ASD_DEBUG */

+ 0 - 9
drivers/scsi/aic94xx/aic94xx_dump.h

@@ -29,24 +29,15 @@
 
 
 #ifdef ASD_DEBUG
 #ifdef ASD_DEBUG
 
 
-void asd_dump_ddb_0(struct asd_ha_struct *asd_ha);
-void asd_dump_target_ddb(struct asd_ha_struct *asd_ha, u16 site_no);
-void asd_dump_scb_sites(struct asd_ha_struct *asd_ha);
 void asd_dump_seq_state(struct asd_ha_struct *asd_ha, u8 lseq_mask);
 void asd_dump_seq_state(struct asd_ha_struct *asd_ha, u8 lseq_mask);
 void asd_dump_frame_rcvd(struct asd_phy *phy,
 void asd_dump_frame_rcvd(struct asd_phy *phy,
 			 struct done_list_struct *dl);
 			 struct done_list_struct *dl);
-void asd_dump_scb_list(struct asd_ascb *ascb, int num);
 #else /* ASD_DEBUG */
 #else /* ASD_DEBUG */
 
 
-static inline void asd_dump_ddb_0(struct asd_ha_struct *asd_ha) { }
-static inline void asd_dump_target_ddb(struct asd_ha_struct *asd_ha,
-				     u16 site_no) { }
-static inline void asd_dump_scb_sites(struct asd_ha_struct *asd_ha) { }
 static inline void asd_dump_seq_state(struct asd_ha_struct *asd_ha,
 static inline void asd_dump_seq_state(struct asd_ha_struct *asd_ha,
 				      u8 lseq_mask) { }
 				      u8 lseq_mask) { }
 static inline void asd_dump_frame_rcvd(struct asd_phy *phy,
 static inline void asd_dump_frame_rcvd(struct asd_phy *phy,
 				       struct done_list_struct *dl) { }
 				       struct done_list_struct *dl) { }
-static inline void asd_dump_scb_list(struct asd_ascb *ascb, int num) { }
 #endif /* ASD_DEBUG */
 #endif /* ASD_DEBUG */
 
 
 #endif /* _AIC94XX_DUMP_H_ */
 #endif /* _AIC94XX_DUMP_H_ */

+ 21 - 23
drivers/scsi/aic94xx/aic94xx_hwi.c

@@ -27,6 +27,7 @@
 #include <linux/pci.h>
 #include <linux/pci.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 #include <linux/module.h>
 #include <linux/module.h>
+#include <linux/firmware.h>
 
 
 #include "aic94xx.h"
 #include "aic94xx.h"
 #include "aic94xx_reg.h"
 #include "aic94xx_reg.h"
@@ -38,16 +39,14 @@ u32 MBAR0_SWB_SIZE;
 
 
 /* ---------- Initialization ---------- */
 /* ---------- Initialization ---------- */
 
 
-static void asd_get_user_sas_addr(struct asd_ha_struct *asd_ha)
+static int asd_get_user_sas_addr(struct asd_ha_struct *asd_ha)
 {
 {
-	extern char sas_addr_str[];
-	/* If the user has specified a WWN it overrides other settings
-	 */
-	if (sas_addr_str[0] != '\0')
-		asd_destringify_sas_addr(asd_ha->hw_prof.sas_addr,
-					 sas_addr_str);
-	else if (asd_ha->hw_prof.sas_addr[0] != 0)
-		asd_stringify_sas_addr(sas_addr_str, asd_ha->hw_prof.sas_addr);
+	/* adapter came with a sas address */
+	if (asd_ha->hw_prof.sas_addr[0])
+		return 0;
+
+	return sas_request_addr(asd_ha->sas_ha.core.shost,
+				asd_ha->hw_prof.sas_addr);
 }
 }
 
 
 static void asd_propagate_sas_addr(struct asd_ha_struct *asd_ha)
 static void asd_propagate_sas_addr(struct asd_ha_struct *asd_ha)
@@ -251,7 +250,7 @@ static int asd_init_scbs(struct asd_ha_struct *asd_ha)
 	return 0;
 	return 0;
 }
 }
 
 
-static inline void asd_get_max_scb_ddb(struct asd_ha_struct *asd_ha)
+static void asd_get_max_scb_ddb(struct asd_ha_struct *asd_ha)
 {
 {
 	asd_ha->hw_prof.max_scbs = asd_get_cmdctx_size(asd_ha)/ASD_SCB_SIZE;
 	asd_ha->hw_prof.max_scbs = asd_get_cmdctx_size(asd_ha)/ASD_SCB_SIZE;
 	asd_ha->hw_prof.max_ddbs = asd_get_devctx_size(asd_ha)/ASD_DDB_SIZE;
 	asd_ha->hw_prof.max_ddbs = asd_get_devctx_size(asd_ha)/ASD_DDB_SIZE;
@@ -657,8 +656,7 @@ int asd_init_hw(struct asd_ha_struct *asd_ha)
 
 
 	asd_init_ctxmem(asd_ha);
 	asd_init_ctxmem(asd_ha);
 
 
-	asd_get_user_sas_addr(asd_ha);
-	if (!asd_ha->hw_prof.sas_addr[0]) {
+	if (asd_get_user_sas_addr(asd_ha)) {
 		asd_printk("No SAS Address provided for %s\n",
 		asd_printk("No SAS Address provided for %s\n",
 			   pci_name(asd_ha->pcidev));
 			   pci_name(asd_ha->pcidev));
 		err = -ENODEV;
 		err = -ENODEV;
@@ -773,7 +771,7 @@ static void asd_dl_tasklet_handler(unsigned long data)
  * asd_process_donelist_isr -- schedule processing of done list entries
  * asd_process_donelist_isr -- schedule processing of done list entries
  * @asd_ha: pointer to host adapter structure
  * @asd_ha: pointer to host adapter structure
  */
  */
-static inline void asd_process_donelist_isr(struct asd_ha_struct *asd_ha)
+static void asd_process_donelist_isr(struct asd_ha_struct *asd_ha)
 {
 {
 	tasklet_schedule(&asd_ha->seq.dl_tasklet);
 	tasklet_schedule(&asd_ha->seq.dl_tasklet);
 }
 }
@@ -782,7 +780,7 @@ static inline void asd_process_donelist_isr(struct asd_ha_struct *asd_ha)
  * asd_com_sas_isr -- process device communication interrupt (COMINT)
  * asd_com_sas_isr -- process device communication interrupt (COMINT)
  * @asd_ha: pointer to host adapter structure
  * @asd_ha: pointer to host adapter structure
  */
  */
-static inline void asd_com_sas_isr(struct asd_ha_struct *asd_ha)
+static void asd_com_sas_isr(struct asd_ha_struct *asd_ha)
 {
 {
 	u32 comstat = asd_read_reg_dword(asd_ha, COMSTAT);
 	u32 comstat = asd_read_reg_dword(asd_ha, COMSTAT);
 
 
@@ -821,7 +819,7 @@ static inline void asd_com_sas_isr(struct asd_ha_struct *asd_ha)
 	asd_chip_reset(asd_ha);
 	asd_chip_reset(asd_ha);
 }
 }
 
 
-static inline void asd_arp2_err(struct asd_ha_struct *asd_ha, u32 dchstatus)
+static void asd_arp2_err(struct asd_ha_struct *asd_ha, u32 dchstatus)
 {
 {
 	static const char *halt_code[256] = {
 	static const char *halt_code[256] = {
 		"UNEXPECTED_INTERRUPT0",
 		"UNEXPECTED_INTERRUPT0",
@@ -908,7 +906,7 @@ static inline void asd_arp2_err(struct asd_ha_struct *asd_ha, u32 dchstatus)
  * asd_dch_sas_isr -- process device channel interrupt (DEVINT)
  * asd_dch_sas_isr -- process device channel interrupt (DEVINT)
  * @asd_ha: pointer to host adapter structure
  * @asd_ha: pointer to host adapter structure
  */
  */
-static inline void asd_dch_sas_isr(struct asd_ha_struct *asd_ha)
+static void asd_dch_sas_isr(struct asd_ha_struct *asd_ha)
 {
 {
 	u32 dchstatus = asd_read_reg_dword(asd_ha, DCHSTATUS);
 	u32 dchstatus = asd_read_reg_dword(asd_ha, DCHSTATUS);
 
 
@@ -923,7 +921,7 @@ static inline void asd_dch_sas_isr(struct asd_ha_struct *asd_ha)
  * ads_rbi_exsi_isr -- process external system interface interrupt (INITERR)
  * ads_rbi_exsi_isr -- process external system interface interrupt (INITERR)
  * @asd_ha: pointer to host adapter structure
  * @asd_ha: pointer to host adapter structure
  */
  */
-static inline void asd_rbi_exsi_isr(struct asd_ha_struct *asd_ha)
+static void asd_rbi_exsi_isr(struct asd_ha_struct *asd_ha)
 {
 {
 	u32 stat0r = asd_read_reg_dword(asd_ha, ASISTAT0R);
 	u32 stat0r = asd_read_reg_dword(asd_ha, ASISTAT0R);
 
 
@@ -971,7 +969,7 @@ static inline void asd_rbi_exsi_isr(struct asd_ha_struct *asd_ha)
  *
  *
  * Asserted on PCIX errors: target abort, etc.
  * Asserted on PCIX errors: target abort, etc.
  */
  */
-static inline void asd_hst_pcix_isr(struct asd_ha_struct *asd_ha)
+static void asd_hst_pcix_isr(struct asd_ha_struct *asd_ha)
 {
 {
 	u16 status;
 	u16 status;
 	u32 pcix_status;
 	u32 pcix_status;
@@ -1044,8 +1042,8 @@ irqreturn_t asd_hw_isr(int irq, void *dev_id)
 
 
 /* ---------- SCB handling ---------- */
 /* ---------- SCB handling ---------- */
 
 
-static inline struct asd_ascb *asd_ascb_alloc(struct asd_ha_struct *asd_ha,
-					      gfp_t gfp_flags)
+static struct asd_ascb *asd_ascb_alloc(struct asd_ha_struct *asd_ha,
+				       gfp_t gfp_flags)
 {
 {
 	extern struct kmem_cache *asd_ascb_cache;
 	extern struct kmem_cache *asd_ascb_cache;
 	struct asd_seq_data *seq = &asd_ha->seq;
 	struct asd_seq_data *seq = &asd_ha->seq;
@@ -1144,8 +1142,8 @@ struct asd_ascb *asd_ascb_alloc_list(struct asd_ha_struct
  *
  *
  * LOCKING: called with the pending list lock held.
  * LOCKING: called with the pending list lock held.
  */
  */
-static inline void asd_swap_head_scb(struct asd_ha_struct *asd_ha,
-				     struct asd_ascb *ascb)
+static void asd_swap_head_scb(struct asd_ha_struct *asd_ha,
+			      struct asd_ascb *ascb)
 {
 {
 	struct asd_seq_data *seq = &asd_ha->seq;
 	struct asd_seq_data *seq = &asd_ha->seq;
 	struct asd_ascb *last = list_entry(ascb->list.prev,
 	struct asd_ascb *last = list_entry(ascb->list.prev,
@@ -1171,7 +1169,7 @@ static inline void asd_swap_head_scb(struct asd_ha_struct *asd_ha,
  * intended to be called from asd_post_ascb_list(), just prior to
  * intended to be called from asd_post_ascb_list(), just prior to
  * posting the SCBs to the sequencer.
  * posting the SCBs to the sequencer.
  */
  */
-static inline void asd_start_scb_timers(struct list_head *list)
+static void asd_start_scb_timers(struct list_head *list)
 {
 {
 	struct asd_ascb *ascb;
 	struct asd_ascb *ascb;
 	list_for_each_entry(ascb, list, list) {
 	list_for_each_entry(ascb, list, list) {

+ 0 - 2
drivers/scsi/aic94xx/aic94xx_hwi.h

@@ -391,8 +391,6 @@ void asd_build_control_phy(struct asd_ascb *ascb, int phy_id, u8 subfunc);
 void asd_control_led(struct asd_ha_struct *asd_ha, int phy_id, int op);
 void asd_control_led(struct asd_ha_struct *asd_ha, int phy_id, int op);
 void asd_turn_led(struct asd_ha_struct *asd_ha, int phy_id, int op);
 void asd_turn_led(struct asd_ha_struct *asd_ha, int phy_id, int op);
 int  asd_enable_phys(struct asd_ha_struct *asd_ha, const u8 phy_mask);
 int  asd_enable_phys(struct asd_ha_struct *asd_ha, const u8 phy_mask);
-void asd_build_initiate_link_adm_task(struct asd_ascb *ascb, int phy_id,
-				      u8 subfunc);
 
 
 void asd_ascb_timedout(unsigned long data);
 void asd_ascb_timedout(unsigned long data);
 int  asd_chip_hardrst(struct asd_ha_struct *asd_ha);
 int  asd_chip_hardrst(struct asd_ha_struct *asd_ha);

+ 4 - 6
drivers/scsi/aic94xx/aic94xx_init.c

@@ -56,8 +56,6 @@ MODULE_PARM_DESC(collector, "\n"
 	"\tThe aic94xx SAS LLDD supports both modes.\n"
 	"\tThe aic94xx SAS LLDD supports both modes.\n"
 	"\tDefault: 0 (Direct Mode).\n");
 	"\tDefault: 0 (Direct Mode).\n");
 
 
-char sas_addr_str[2*SAS_ADDR_SIZE + 1] = "";
-
 static struct scsi_transport_template *aic94xx_transport_template;
 static struct scsi_transport_template *aic94xx_transport_template;
 static int asd_scan_finished(struct Scsi_Host *, unsigned long);
 static int asd_scan_finished(struct Scsi_Host *, unsigned long);
 static void asd_scan_start(struct Scsi_Host *);
 static void asd_scan_start(struct Scsi_Host *);
@@ -547,7 +545,7 @@ static struct asd_pcidev_struct {
 	},
 	},
 };
 };
 
 
-static inline int asd_create_ha_caches(struct asd_ha_struct *asd_ha)
+static int asd_create_ha_caches(struct asd_ha_struct *asd_ha)
 {
 {
 	asd_ha->scb_pool = dma_pool_create(ASD_DRIVER_NAME "_scb_pool",
 	asd_ha->scb_pool = dma_pool_create(ASD_DRIVER_NAME "_scb_pool",
 					   &asd_ha->pcidev->dev,
 					   &asd_ha->pcidev->dev,
@@ -565,7 +563,7 @@ static inline int asd_create_ha_caches(struct asd_ha_struct *asd_ha)
  * asd_free_edbs -- free empty data buffers
  * asd_free_edbs -- free empty data buffers
  * asd_ha: pointer to host adapter structure
  * asd_ha: pointer to host adapter structure
  */
  */
-static inline void asd_free_edbs(struct asd_ha_struct *asd_ha)
+static void asd_free_edbs(struct asd_ha_struct *asd_ha)
 {
 {
 	struct asd_seq_data *seq = &asd_ha->seq;
 	struct asd_seq_data *seq = &asd_ha->seq;
 	int i;
 	int i;
@@ -576,7 +574,7 @@ static inline void asd_free_edbs(struct asd_ha_struct *asd_ha)
 	seq->edb_arr = NULL;
 	seq->edb_arr = NULL;
 }
 }
 
 
-static inline void asd_free_escbs(struct asd_ha_struct *asd_ha)
+static void asd_free_escbs(struct asd_ha_struct *asd_ha)
 {
 {
 	struct asd_seq_data *seq = &asd_ha->seq;
 	struct asd_seq_data *seq = &asd_ha->seq;
 	int i;
 	int i;
@@ -591,7 +589,7 @@ static inline void asd_free_escbs(struct asd_ha_struct *asd_ha)
 	seq->escb_arr = NULL;
 	seq->escb_arr = NULL;
 }
 }
 
 
-static inline void asd_destroy_ha_caches(struct asd_ha_struct *asd_ha)
+static void asd_destroy_ha_caches(struct asd_ha_struct *asd_ha)
 {
 {
 	int i;
 	int i;
 
 

+ 26 - 27
drivers/scsi/aic94xx/aic94xx_reg.c

@@ -32,8 +32,8 @@
  * Offset comes before value to remind that the operation of
  * Offset comes before value to remind that the operation of
  * this function is *offs = val.
  * this function is *offs = val.
  */
  */
-static inline void asd_write_byte(struct asd_ha_struct *asd_ha,
-				  unsigned long offs, u8 val)
+static void asd_write_byte(struct asd_ha_struct *asd_ha,
+			   unsigned long offs, u8 val)
 {
 {
 	if (unlikely(asd_ha->iospace))
 	if (unlikely(asd_ha->iospace))
 		outb(val,
 		outb(val,
@@ -43,8 +43,8 @@ static inline void asd_write_byte(struct asd_ha_struct *asd_ha,
 	wmb();
 	wmb();
 }
 }
 
 
-static inline void asd_write_word(struct asd_ha_struct *asd_ha,
-				  unsigned long offs, u16 val)
+static void asd_write_word(struct asd_ha_struct *asd_ha,
+			   unsigned long offs, u16 val)
 {
 {
 	if (unlikely(asd_ha->iospace))
 	if (unlikely(asd_ha->iospace))
 		outw(val,
 		outw(val,
@@ -54,8 +54,8 @@ static inline void asd_write_word(struct asd_ha_struct *asd_ha,
 	wmb();
 	wmb();
 }
 }
 
 
-static inline void asd_write_dword(struct asd_ha_struct *asd_ha,
-				   unsigned long offs, u32 val)
+static void asd_write_dword(struct asd_ha_struct *asd_ha,
+			    unsigned long offs, u32 val)
 {
 {
 	if (unlikely(asd_ha->iospace))
 	if (unlikely(asd_ha->iospace))
 		outl(val,
 		outl(val,
@@ -67,8 +67,7 @@ static inline void asd_write_dword(struct asd_ha_struct *asd_ha,
 
 
 /* Reading from device address space.
 /* Reading from device address space.
  */
  */
-static inline u8 asd_read_byte(struct asd_ha_struct *asd_ha,
-			       unsigned long offs)
+static u8 asd_read_byte(struct asd_ha_struct *asd_ha, unsigned long offs)
 {
 {
 	u8 val;
 	u8 val;
 	if (unlikely(asd_ha->iospace))
 	if (unlikely(asd_ha->iospace))
@@ -80,8 +79,8 @@ static inline u8 asd_read_byte(struct asd_ha_struct *asd_ha,
 	return val;
 	return val;
 }
 }
 
 
-static inline u16 asd_read_word(struct asd_ha_struct *asd_ha,
-				unsigned long offs)
+static u16 asd_read_word(struct asd_ha_struct *asd_ha,
+			 unsigned long offs)
 {
 {
 	u16 val;
 	u16 val;
 	if (unlikely(asd_ha->iospace))
 	if (unlikely(asd_ha->iospace))
@@ -93,8 +92,8 @@ static inline u16 asd_read_word(struct asd_ha_struct *asd_ha,
 	return val;
 	return val;
 }
 }
 
 
-static inline u32 asd_read_dword(struct asd_ha_struct *asd_ha,
-				 unsigned long offs)
+static u32 asd_read_dword(struct asd_ha_struct *asd_ha,
+			  unsigned long offs)
 {
 {
 	u32 val;
 	u32 val;
 	if (unlikely(asd_ha->iospace))
 	if (unlikely(asd_ha->iospace))
@@ -124,22 +123,22 @@ static inline u32 asd_mem_offs_swb(void)
 /* We know that the register wanted is in the range
 /* We know that the register wanted is in the range
  * of the sliding window.
  * of the sliding window.
  */
  */
-#define ASD_READ_SW(ww, type, ord)                                     \
-static inline type asd_read_##ww##_##ord (struct asd_ha_struct *asd_ha,\
-					  u32 reg)                     \
-{                                                                      \
-	struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0];    \
-	u32 map_offs=(reg - io_handle-> ww##_base )+asd_mem_offs_##ww ();\
-	return asd_read_##ord (asd_ha, (unsigned long) map_offs);      \
+#define ASD_READ_SW(ww, type, ord)					\
+static type asd_read_##ww##_##ord(struct asd_ha_struct *asd_ha,		\
+				   u32 reg)				\
+{									\
+	struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0];	\
+	u32 map_offs = (reg - io_handle->ww##_base) + asd_mem_offs_##ww();\
+	return asd_read_##ord(asd_ha, (unsigned long)map_offs);	\
 }
 }
 
 
-#define ASD_WRITE_SW(ww, type, ord)                                    \
-static inline void asd_write_##ww##_##ord (struct asd_ha_struct *asd_ha,\
-				  u32 reg, type val)                   \
-{                                                                      \
-	struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0];    \
-	u32 map_offs=(reg - io_handle-> ww##_base )+asd_mem_offs_##ww ();\
-	asd_write_##ord (asd_ha, (unsigned long) map_offs, val);       \
+#define ASD_WRITE_SW(ww, type, ord)					\
+static void asd_write_##ww##_##ord(struct asd_ha_struct *asd_ha,	\
+				    u32 reg, type val)			\
+{									\
+	struct asd_ha_addrspace *io_handle = &asd_ha->io_handle[0];	\
+	u32 map_offs = (reg - io_handle->ww##_base) + asd_mem_offs_##ww();\
+	asd_write_##ord(asd_ha, (unsigned long)map_offs, val);		\
 }
 }
 
 
 ASD_READ_SW(swa, u8,  byte);
 ASD_READ_SW(swa, u8,  byte);
@@ -186,7 +185,7 @@ ASD_WRITE_SW(swc, u32, dword);
  * @asd_ha: pointer to host adapter structure
  * @asd_ha: pointer to host adapter structure
  * @reg: register desired to be within range of the new window
  * @reg: register desired to be within range of the new window
  */
  */
-static inline void asd_move_swb(struct asd_ha_struct *asd_ha, u32 reg)
+static void asd_move_swb(struct asd_ha_struct *asd_ha, u32 reg)
 {
 {
 	u32 base = reg & ~(MBAR0_SWB_SIZE-1);
 	u32 base = reg & ~(MBAR0_SWB_SIZE-1);
 	pci_write_config_dword(asd_ha->pcidev, PCI_CONF_MBAR0_SWB, base);
 	pci_write_config_dword(asd_ha->pcidev, PCI_CONF_MBAR0_SWB, base);

+ 18 - 15
drivers/scsi/aic94xx/aic94xx_scb.c

@@ -50,7 +50,7 @@
 			   | CURRENT_SPINUP_HOLD | CURRENT_GTO_TIMEOUT \
 			   | CURRENT_SPINUP_HOLD | CURRENT_GTO_TIMEOUT \
 			   | CURRENT_OOB_ERROR)
 			   | CURRENT_OOB_ERROR)
 
 
-static inline void get_lrate_mode(struct asd_phy *phy, u8 oob_mode)
+static void get_lrate_mode(struct asd_phy *phy, u8 oob_mode)
 {
 {
 	struct sas_phy *sas_phy = phy->sas_phy.phy;
 	struct sas_phy *sas_phy = phy->sas_phy.phy;
 
 
@@ -81,7 +81,7 @@ static inline void get_lrate_mode(struct asd_phy *phy, u8 oob_mode)
 		phy->sas_phy.oob_mode = SATA_OOB_MODE;
 		phy->sas_phy.oob_mode = SATA_OOB_MODE;
 }
 }
 
 
-static inline void asd_phy_event_tasklet(struct asd_ascb *ascb,
+static void asd_phy_event_tasklet(struct asd_ascb *ascb,
 					 struct done_list_struct *dl)
 					 struct done_list_struct *dl)
 {
 {
 	struct asd_ha_struct *asd_ha = ascb->ha;
 	struct asd_ha_struct *asd_ha = ascb->ha;
@@ -125,8 +125,7 @@ static inline void asd_phy_event_tasklet(struct asd_ascb *ascb,
 }
 }
 
 
 /* If phys are enabled sparsely, this will do the right thing. */
 /* If phys are enabled sparsely, this will do the right thing. */
-static inline unsigned ord_phy(struct asd_ha_struct *asd_ha,
-			       struct asd_phy *phy)
+static unsigned ord_phy(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
 {
 {
 	u8 enabled_mask = asd_ha->hw_prof.enabled_phys;
 	u8 enabled_mask = asd_ha->hw_prof.enabled_phys;
 	int i, k = 0;
 	int i, k = 0;
@@ -151,7 +150,7 @@ static inline unsigned ord_phy(struct asd_ha_struct *asd_ha,
  * LOCKING: the frame_rcvd_lock needs to be held since this parses the frame
  * LOCKING: the frame_rcvd_lock needs to be held since this parses the frame
  * buffer.
  * buffer.
  */
  */
-static inline void asd_get_attached_sas_addr(struct asd_phy *phy, u8 *sas_addr)
+static void asd_get_attached_sas_addr(struct asd_phy *phy, u8 *sas_addr)
 {
 {
 	if (phy->sas_phy.frame_rcvd[0] == 0x34
 	if (phy->sas_phy.frame_rcvd[0] == 0x34
 	    && phy->sas_phy.oob_mode == SATA_OOB_MODE) {
 	    && phy->sas_phy.oob_mode == SATA_OOB_MODE) {
@@ -232,9 +231,9 @@ static void asd_deform_port(struct asd_ha_struct *asd_ha, struct asd_phy *phy)
 	spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags);
 	spin_unlock_irqrestore(&asd_ha->asd_ports_lock, flags);
 }
 }
 
 
-static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
-					   struct done_list_struct *dl,
-					   int edb_id, int phy_id)
+static void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
+				    struct done_list_struct *dl,
+				    int edb_id, int phy_id)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
 	int edb_el = edb_id + ascb->edb_index;
 	int edb_el = edb_id + ascb->edb_index;
@@ -255,9 +254,9 @@ static inline void asd_bytes_dmaed_tasklet(struct asd_ascb *ascb,
 	sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED);
 	sas_ha->notify_port_event(&phy->sas_phy, PORTE_BYTES_DMAED);
 }
 }
 
 
-static inline void asd_link_reset_err_tasklet(struct asd_ascb *ascb,
-					      struct done_list_struct *dl,
-					      int phy_id)
+static void asd_link_reset_err_tasklet(struct asd_ascb *ascb,
+				       struct done_list_struct *dl,
+				       int phy_id)
 {
 {
 	struct asd_ha_struct *asd_ha = ascb->ha;
 	struct asd_ha_struct *asd_ha = ascb->ha;
 	struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
 	struct sas_ha_struct *sas_ha = &asd_ha->sas_ha;
@@ -308,9 +307,9 @@ out:
 	;
 	;
 }
 }
 
 
-static inline void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb,
-					      struct done_list_struct *dl,
-					      int phy_id)
+static void asd_primitive_rcvd_tasklet(struct asd_ascb *ascb,
+				       struct done_list_struct *dl,
+				       int phy_id)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
 	struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha;
 	struct sas_ha_struct *sas_ha = &ascb->ha->sas_ha;
@@ -715,7 +714,7 @@ out:
 	asd_ascb_free(ascb);
 	asd_ascb_free(ascb);
 }
 }
 
 
-static inline void set_speed_mask(u8 *speed_mask, struct asd_phy_desc *pd)
+static void set_speed_mask(u8 *speed_mask, struct asd_phy_desc *pd)
 {
 {
 	/* disable all speeds, then enable defaults */
 	/* disable all speeds, then enable defaults */
 	*speed_mask = SAS_SPEED_60_DIS | SAS_SPEED_30_DIS | SAS_SPEED_15_DIS
 	*speed_mask = SAS_SPEED_60_DIS | SAS_SPEED_30_DIS | SAS_SPEED_15_DIS
@@ -820,6 +819,8 @@ void asd_build_control_phy(struct asd_ascb *ascb, int phy_id, u8 subfunc)
 
 
 /* ---------- INITIATE LINK ADM TASK ---------- */
 /* ---------- INITIATE LINK ADM TASK ---------- */
 
 
+#if 0
+
 static void link_adm_tasklet_complete(struct asd_ascb *ascb,
 static void link_adm_tasklet_complete(struct asd_ascb *ascb,
 				      struct done_list_struct *dl)
 				      struct done_list_struct *dl)
 {
 {
@@ -852,6 +853,8 @@ void asd_build_initiate_link_adm_task(struct asd_ascb *ascb, int phy_id,
 	ascb->tasklet_complete = link_adm_tasklet_complete;
 	ascb->tasklet_complete = link_adm_tasklet_complete;
 }
 }
 
 
+#endif  /*  0  */
+
 /* ---------- SCB timer ---------- */
 /* ---------- SCB timer ---------- */
 
 
 /**
 /**

+ 2 - 2
drivers/scsi/aic94xx/aic94xx_sds.c

@@ -590,8 +590,8 @@ static int asd_reset_flash(struct asd_ha_struct *asd_ha)
 	return err;
 	return err;
 }
 }
 
 
-static inline int asd_read_flash_seg(struct asd_ha_struct *asd_ha,
-				     void *buffer, u32 offs, int size)
+static int asd_read_flash_seg(struct asd_ha_struct *asd_ha,
+			      void *buffer, u32 offs, int size)
 {
 {
 	asd_read_reg_string(asd_ha, buffer, asd_ha->hw_prof.flash.bar+offs,
 	asd_read_reg_string(asd_ha, buffer, asd_ha->hw_prof.flash.bar+offs,
 			    size);
 			    size);

+ 5 - 26
drivers/scsi/aic94xx/aic94xx_seq.c

@@ -60,7 +60,7 @@ static u16 last_scb_site_no;
  *
  *
  * Return 0 on success, negative on failure.
  * Return 0 on success, negative on failure.
  */
  */
-int asd_pause_cseq(struct asd_ha_struct *asd_ha)
+static int asd_pause_cseq(struct asd_ha_struct *asd_ha)
 {
 {
 	int	count = PAUSE_TRIES;
 	int	count = PAUSE_TRIES;
 	u32	arp2ctl;
 	u32	arp2ctl;
@@ -87,7 +87,7 @@ int asd_pause_cseq(struct asd_ha_struct *asd_ha)
  *
  *
  * Return 0 on success, negative on error.
  * Return 0 on success, negative on error.
  */
  */
-int asd_unpause_cseq(struct asd_ha_struct *asd_ha)
+static int asd_unpause_cseq(struct asd_ha_struct *asd_ha)
 {
 {
 	u32	arp2ctl;
 	u32	arp2ctl;
 	int	count = PAUSE_TRIES;
 	int	count = PAUSE_TRIES;
@@ -115,7 +115,7 @@ int asd_unpause_cseq(struct asd_ha_struct *asd_ha)
  *
  *
  * Return 0 on success, negative on error.
  * Return 0 on success, negative on error.
  */
  */
-static inline int asd_seq_pause_lseq(struct asd_ha_struct *asd_ha, int lseq)
+static int asd_seq_pause_lseq(struct asd_ha_struct *asd_ha, int lseq)
 {
 {
 	u32    arp2ctl;
 	u32    arp2ctl;
 	int    count = PAUSE_TRIES;
 	int    count = PAUSE_TRIES;
@@ -143,7 +143,7 @@ static inline int asd_seq_pause_lseq(struct asd_ha_struct *asd_ha, int lseq)
  *
  *
  * Return 0 on success, negative on failure.
  * Return 0 on success, negative on failure.
  */
  */
-int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask)
+static int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask)
 {
 {
 	int lseq;
 	int lseq;
 	int err = 0;
 	int err = 0;
@@ -164,7 +164,7 @@ int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask)
  *
  *
  * Return 0 on success, negative on error.
  * Return 0 on success, negative on error.
  */
  */
-static inline int asd_seq_unpause_lseq(struct asd_ha_struct *asd_ha, int lseq)
+static int asd_seq_unpause_lseq(struct asd_ha_struct *asd_ha, int lseq)
 {
 {
 	u32 arp2ctl;
 	u32 arp2ctl;
 	int count = PAUSE_TRIES;
 	int count = PAUSE_TRIES;
@@ -186,27 +186,6 @@ static inline int asd_seq_unpause_lseq(struct asd_ha_struct *asd_ha, int lseq)
 }
 }
 
 
 
 
-/**
- * asd_unpause_lseq - unpause the link sequencer(s)
- * @asd_ha: pointer to host adapter structure
- * @lseq_mask: mask of link sequencers of interest
- *
- * Return 0 on success, negative on failure.
- */
-int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask)
-{
-	int lseq;
-	int err = 0;
-
-	for_each_sequencer(lseq_mask, lseq_mask, lseq) {
-		err = asd_seq_unpause_lseq(asd_ha, lseq);
-		if (err)
-			return err;
-	}
-
-	return err;
-}
-
 /* ---------- Downloading CSEQ/LSEQ microcode ---------- */
 /* ---------- Downloading CSEQ/LSEQ microcode ---------- */
 
 
 static int asd_verify_cseq(struct asd_ha_struct *asd_ha, const u8 *_prog,
 static int asd_verify_cseq(struct asd_ha_struct *asd_ha, const u8 *_prog,

+ 0 - 4
drivers/scsi/aic94xx/aic94xx_seq.h

@@ -58,10 +58,6 @@ struct sequencer_file_header {
 } __attribute__((packed));
 } __attribute__((packed));
 
 
 #ifdef __KERNEL__
 #ifdef __KERNEL__
-int asd_pause_cseq(struct asd_ha_struct *asd_ha);
-int asd_unpause_cseq(struct asd_ha_struct *asd_ha);
-int asd_pause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask);
-int asd_unpause_lseq(struct asd_ha_struct *asd_ha, u8 lseq_mask);
 int asd_init_seqs(struct asd_ha_struct *asd_ha);
 int asd_init_seqs(struct asd_ha_struct *asd_ha);
 int asd_start_seqs(struct asd_ha_struct *asd_ha);
 int asd_start_seqs(struct asd_ha_struct *asd_ha);
 int asd_release_firmware(void);
 int asd_release_firmware(void);

+ 6 - 6
drivers/scsi/aic94xx/aic94xx_task.c

@@ -33,7 +33,7 @@ static void asd_unbuild_ata_ascb(struct asd_ascb *a);
 static void asd_unbuild_smp_ascb(struct asd_ascb *a);
 static void asd_unbuild_smp_ascb(struct asd_ascb *a);
 static void asd_unbuild_ssp_ascb(struct asd_ascb *a);
 static void asd_unbuild_ssp_ascb(struct asd_ascb *a);
 
 
-static inline void asd_can_dequeue(struct asd_ha_struct *asd_ha, int num)
+static void asd_can_dequeue(struct asd_ha_struct *asd_ha, int num)
 {
 {
 	unsigned long flags;
 	unsigned long flags;
 
 
@@ -51,9 +51,9 @@ static const u8 data_dir_flags[] = {
 	[PCI_DMA_NONE]          = DATA_DIR_NONE, /* NO TRANSFER */
 	[PCI_DMA_NONE]          = DATA_DIR_NONE, /* NO TRANSFER */
 };
 };
 
 
-static inline int asd_map_scatterlist(struct sas_task *task,
-				      struct sg_el *sg_arr,
-				      gfp_t gfp_flags)
+static int asd_map_scatterlist(struct sas_task *task,
+			       struct sg_el *sg_arr,
+			       gfp_t gfp_flags)
 {
 {
 	struct asd_ascb *ascb = task->lldd_task;
 	struct asd_ascb *ascb = task->lldd_task;
 	struct asd_ha_struct *asd_ha = ascb->ha;
 	struct asd_ha_struct *asd_ha = ascb->ha;
@@ -131,7 +131,7 @@ err_unmap:
 	return res;
 	return res;
 }
 }
 
 
-static inline void asd_unmap_scatterlist(struct asd_ascb *ascb)
+static void asd_unmap_scatterlist(struct asd_ascb *ascb)
 {
 {
 	struct asd_ha_struct *asd_ha = ascb->ha;
 	struct asd_ha_struct *asd_ha = ascb->ha;
 	struct sas_task *task = ascb->uldd_task;
 	struct sas_task *task = ascb->uldd_task;
@@ -527,7 +527,7 @@ static void asd_unbuild_ssp_ascb(struct asd_ascb *a)
 
 
 /* ---------- Execute Task ---------- */
 /* ---------- Execute Task ---------- */
 
 
-static inline int asd_can_queue(struct asd_ha_struct *asd_ha, int num)
+static int asd_can_queue(struct asd_ha_struct *asd_ha, int num)
 {
 {
 	int res = 0;
 	int res = 0;
 	unsigned long flags;
 	unsigned long flags;

+ 1 - 1
drivers/scsi/aic94xx/aic94xx_tmf.c

@@ -336,7 +336,7 @@ static void asd_tmf_tasklet_complete(struct asd_ascb *ascb,
 	asd_ascb_free(ascb);
 	asd_ascb_free(ascb);
 }
 }
 
 
-static inline int asd_clear_nexus(struct sas_task *task)
+static int asd_clear_nexus(struct sas_task *task)
 {
 {
 	int res = TMF_RESP_FUNC_FAILED;
 	int res = TMF_RESP_FUNC_FAILED;
 	int leftover;
 	int leftover;

+ 0 - 1
drivers/scsi/arm/acornscsi.c

@@ -2983,7 +2983,6 @@ static struct scsi_host_template acornscsi_template = {
 	.this_id		= 7,
 	.this_id		= 7,
 	.sg_tablesize		= SG_ALL,
 	.sg_tablesize		= SG_ALL,
 	.cmd_per_lun		= 2,
 	.cmd_per_lun		= 2,
-	.unchecked_isa_dma	= 0,
 	.use_clustering		= DISABLE_CLUSTERING,
 	.use_clustering		= DISABLE_CLUSTERING,
 	.proc_name		= "acornscsi",
 	.proc_name		= "acornscsi",
 };
 };

+ 0 - 1
drivers/scsi/arm/cumana_1.c

@@ -222,7 +222,6 @@ static struct scsi_host_template cumanascsi_template = {
 	.this_id		= 7,
 	.this_id		= 7,
 	.sg_tablesize		= SG_ALL,
 	.sg_tablesize		= SG_ALL,
 	.cmd_per_lun		= 2,
 	.cmd_per_lun		= 2,
-	.unchecked_isa_dma	= 0,
 	.use_clustering		= DISABLE_CLUSTERING,
 	.use_clustering		= DISABLE_CLUSTERING,
 	.proc_name		= "CumanaSCSI-1",
 	.proc_name		= "CumanaSCSI-1",
 };
 };

+ 17 - 16
drivers/scsi/ch.c

@@ -113,7 +113,7 @@ static const struct {
 	unsigned char  asc;
 	unsigned char  asc;
 	unsigned char  ascq;
 	unsigned char  ascq;
 	int	       errno;
 	int	       errno;
-} err[] = {
+} ch_err[] = {
 /* Just filled in what looks right. Hav'nt checked any standard paper for
 /* Just filled in what looks right. Hav'nt checked any standard paper for
    these errno assignments, so they may be wrong... */
    these errno assignments, so they may be wrong... */
 	{
 	{
@@ -155,11 +155,11 @@ static int ch_find_errno(struct scsi_sense_hdr *sshdr)
 	/* Check to see if additional sense information is available */
 	/* Check to see if additional sense information is available */
 	if (scsi_sense_valid(sshdr) &&
 	if (scsi_sense_valid(sshdr) &&
 	    sshdr->asc != 0) {
 	    sshdr->asc != 0) {
-		for (i = 0; err[i].errno != 0; i++) {
-			if (err[i].sense == sshdr->sense_key &&
-			    err[i].asc   == sshdr->asc &&
-			    err[i].ascq  == sshdr->ascq) {
-				errno = -err[i].errno;
+		for (i = 0; ch_err[i].errno != 0; i++) {
+			if (ch_err[i].sense == sshdr->sense_key &&
+			    ch_err[i].asc   == sshdr->asc &&
+			    ch_err[i].ascq  == sshdr->ascq) {
+				errno = -ch_err[i].errno;
 				break;
 				break;
 			}
 			}
 		}
 		}
@@ -721,8 +721,8 @@ static long ch_ioctl(struct file *file,
 	case CHIOGELEM:
 	case CHIOGELEM:
 	{
 	{
 		struct changer_get_element cge;
 		struct changer_get_element cge;
-		u_char  cmd[12];
-		u_char  *buffer;
+		u_char ch_cmd[12];
+		u_char *buffer;
 		unsigned int elem;
 		unsigned int elem;
 		int     result,i;
 		int     result,i;
 
 
@@ -739,17 +739,18 @@ static long ch_ioctl(struct file *file,
 		mutex_lock(&ch->lock);
 		mutex_lock(&ch->lock);
 
 
 	voltag_retry:
 	voltag_retry:
-		memset(cmd,0,sizeof(cmd));
-		cmd[0] = READ_ELEMENT_STATUS;
-		cmd[1] = (ch->device->lun << 5) |
+		memset(ch_cmd, 0, sizeof(ch_cmd));
+		ch_cmd[0] = READ_ELEMENT_STATUS;
+		ch_cmd[1] = (ch->device->lun << 5) |
 			(ch->voltags ? 0x10 : 0) |
 			(ch->voltags ? 0x10 : 0) |
 			ch_elem_to_typecode(ch,elem);
 			ch_elem_to_typecode(ch,elem);
-		cmd[2] = (elem >> 8) & 0xff;
-		cmd[3] = elem        & 0xff;
-		cmd[5] = 1;
-		cmd[9] = 255;
+		ch_cmd[2] = (elem >> 8) & 0xff;
+		ch_cmd[3] = elem        & 0xff;
+		ch_cmd[5] = 1;
+		ch_cmd[9] = 255;
 
 
-		if (0 == (result = ch_do_scsi(ch, cmd, buffer, 256, DMA_FROM_DEVICE))) {
+		result = ch_do_scsi(ch, ch_cmd, buffer, 256, DMA_FROM_DEVICE);
+		if (!result) {
 			cge.cge_status = buffer[18];
 			cge.cge_status = buffer[18];
 			cge.cge_flags = 0;
 			cge.cge_flags = 0;
 			if (buffer[18] & CESTATUS_EXCEPT) {
 			if (buffer[18] & CESTATUS_EXCEPT) {

+ 0 - 1
drivers/scsi/dc395x.c

@@ -4761,7 +4761,6 @@ static struct scsi_host_template dc395x_driver_template = {
 	.cmd_per_lun            = DC395x_MAX_CMD_PER_LUN,
 	.cmd_per_lun            = DC395x_MAX_CMD_PER_LUN,
 	.eh_abort_handler       = dc395x_eh_abort,
 	.eh_abort_handler       = dc395x_eh_abort,
 	.eh_bus_reset_handler   = dc395x_eh_bus_reset,
 	.eh_bus_reset_handler   = dc395x_eh_bus_reset,
-	.unchecked_isa_dma      = 0,
 	.use_clustering         = DISABLE_CLUSTERING,
 	.use_clustering         = DISABLE_CLUSTERING,
 };
 };
 
 

+ 0 - 2
drivers/scsi/eata_pio.c

@@ -815,8 +815,6 @@ static int register_pio_HBA(long base, struct get_conf *gc, struct pci_dev *pdev
 	else
 	else
 		hd->primary = 1;
 		hd->primary = 1;
 
 
-	sh->unchecked_isa_dma = 0;	/* We can only do PIO */
-
 	hd->next = NULL;	/* build a linked list of all HBAs */
 	hd->next = NULL;	/* build a linked list of all HBAs */
 	hd->prev = last_HBA;
 	hd->prev = last_HBA;
 	if (hd->prev != NULL)
 	if (hd->prev != NULL)

+ 132 - 188
drivers/scsi/gdth.c

@@ -85,10 +85,10 @@
 
 
 /* The meaning of the Scsi_Pointer members in this driver is as follows:
 /* The meaning of the Scsi_Pointer members in this driver is as follows:
  * ptr:                     Chaining
  * ptr:                     Chaining
- * this_residual:           gdth_bufflen
- * buffer:                  gdth_sglist
+ * this_residual:           unused
+ * buffer:                  unused
  * dma_handle:              unused
  * dma_handle:              unused
- * buffers_residual:        gdth_sg_count
+ * buffers_residual:        unused
  * Status:                  unused
  * Status:                  unused
  * Message:                 unused
  * Message:                 unused
  * have_data_in:            unused
  * have_data_in:            unused
@@ -372,47 +372,6 @@ static const struct file_operations gdth_fops = {
     .release = gdth_close,
     .release = gdth_close,
 };
 };
 
 
-/*
- * gdth scsi_command access wrappers.
- *   below 6 functions are used throughout the driver to access scsi_command's
- *   io parameters. The reason we do not use the regular accessors from
- *   scsi_cmnd.h is because of gdth_execute(). Since it is unrecommended for
- *   llds to directly set scsi_cmnd's IO members. This driver will use SCp
- *   members for IO parameters, and will copy scsi_cmnd's members to Scp
- *   members in queuecommand. For internal commands through gdth_execute()
- *   SCp's members will be set directly.
- */
-static inline unsigned gdth_bufflen(struct scsi_cmnd *cmd)
-{
-	return (unsigned)cmd->SCp.this_residual;
-}
-
-static inline void gdth_set_bufflen(struct scsi_cmnd *cmd, unsigned bufflen)
-{
-	cmd->SCp.this_residual = bufflen;
-}
-
-static inline unsigned gdth_sg_count(struct scsi_cmnd *cmd)
-{
-	return (unsigned)cmd->SCp.buffers_residual;
-}
-
-static inline void gdth_set_sg_count(struct scsi_cmnd *cmd, unsigned sg_count)
-{
-	cmd->SCp.buffers_residual = sg_count;
-}
-
-static inline struct scatterlist *gdth_sglist(struct scsi_cmnd *cmd)
-{
-	return cmd->SCp.buffer;
-}
-
-static inline void gdth_set_sglist(struct scsi_cmnd *cmd,
-                                   struct scatterlist *sglist)
-{
-	cmd->SCp.buffer = sglist;
-}
-
 #include "gdth_proc.h"
 #include "gdth_proc.h"
 #include "gdth_proc.c"
 #include "gdth_proc.c"
 
 
@@ -591,125 +550,111 @@ static int __init gdth_search_isa(ulong32 bios_adr)
 #endif /* CONFIG_ISA */
 #endif /* CONFIG_ISA */
 
 
 #ifdef CONFIG_PCI
 #ifdef CONFIG_PCI
-static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt,
-                            ushort vendor, ushort dev);
+static bool gdth_pci_registered;
 
 
-static int __init gdth_search_pci(gdth_pci_str *pcistr)
+static bool gdth_search_vortex(ushort device)
 {
 {
-    ushort device, cnt;
-    
-    TRACE(("gdth_search_pci()\n"));
-
-    cnt = 0;
-    for (device = 0; device <= PCI_DEVICE_ID_VORTEX_GDT6555; ++device)
-        gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device);
-    for (device = PCI_DEVICE_ID_VORTEX_GDT6x17RP; 
-         device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP; ++device)
-        gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, device);
-    gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, 
-                    PCI_DEVICE_ID_VORTEX_GDTNEWRX);
-    gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_VORTEX, 
-                    PCI_DEVICE_ID_VORTEX_GDTNEWRX2);
-    gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL,
-                    PCI_DEVICE_ID_INTEL_SRC);
-    gdth_search_dev(pcistr, &cnt, PCI_VENDOR_ID_INTEL,
-                    PCI_DEVICE_ID_INTEL_SRC_XSCALE);
-    return cnt;
+	if (device <= PCI_DEVICE_ID_VORTEX_GDT6555)
+		return true;
+	if (device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP &&
+	    device <= PCI_DEVICE_ID_VORTEX_GDTMAXRP)
+		return true;
+	if (device == PCI_DEVICE_ID_VORTEX_GDTNEWRX ||
+	    device == PCI_DEVICE_ID_VORTEX_GDTNEWRX2)
+		return true;
+	return false;
 }
 }
 
 
+static int gdth_pci_probe_one(gdth_pci_str *pcistr, gdth_ha_str **ha_out);
+static int gdth_pci_init_one(struct pci_dev *pdev,
+			     const struct pci_device_id *ent);
+static void gdth_pci_remove_one(struct pci_dev *pdev);
+static void gdth_remove_one(gdth_ha_str *ha);
+
 /* Vortex only makes RAID controllers.
 /* Vortex only makes RAID controllers.
  * We do not really want to specify all 550 ids here, so wildcard match.
  * We do not really want to specify all 550 ids here, so wildcard match.
  */
  */
-static struct pci_device_id gdthtable[] __maybe_unused = {
-    {PCI_VENDOR_ID_VORTEX,PCI_ANY_ID,PCI_ANY_ID, PCI_ANY_ID},
-    {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC,PCI_ANY_ID,PCI_ANY_ID}, 
-    {PCI_VENDOR_ID_INTEL,PCI_DEVICE_ID_INTEL_SRC_XSCALE,PCI_ANY_ID,PCI_ANY_ID}, 
-    {0}
+static const struct pci_device_id gdthtable[] = {
+	{ PCI_VDEVICE(VORTEX, PCI_ANY_ID) },
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SRC) },
+	{ PCI_VDEVICE(INTEL, PCI_DEVICE_ID_INTEL_SRC_XSCALE) },
+	{ }	/* terminate list */
+};
+MODULE_DEVICE_TABLE(pci, gdthtable);
+
+static struct pci_driver gdth_pci_driver = {
+	.name		= "gdth",
+	.id_table	= gdthtable,
+	.probe		= gdth_pci_init_one,
+	.remove		= gdth_pci_remove_one,
 };
 };
-MODULE_DEVICE_TABLE(pci,gdthtable);
 
 
-static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt,
-                                   ushort vendor, ushort device)
+static void gdth_pci_remove_one(struct pci_dev *pdev)
 {
 {
-    ulong base0, base1, base2;
-    struct pci_dev *pdev;
+	gdth_ha_str *ha = pci_get_drvdata(pdev);
+
+	pci_set_drvdata(pdev, NULL);
+
+	list_del(&ha->list);
+	gdth_remove_one(ha);
+
+	pci_disable_device(pdev);
+}
+
+static int gdth_pci_init_one(struct pci_dev *pdev,
+				       const struct pci_device_id *ent)
+{
+	ushort vendor = pdev->vendor;
+	ushort device = pdev->device;
+	ulong base0, base1, base2;
+	int rc;
+	gdth_pci_str gdth_pcistr;
+	gdth_ha_str *ha = NULL;
     
     
-    TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n",
-          *cnt, vendor, device));
+	TRACE(("gdth_search_dev() cnt %d vendor %x device %x\n",
+	       gdth_ctr_count, vendor, device));
 
 
-    pdev = NULL;
-    while ((pdev = pci_get_device(vendor, device, pdev))
-           != NULL) {
-        if (pci_enable_device(pdev))
-            continue;
-        if (*cnt >= MAXHA) {
-            pci_dev_put(pdev);
-            return;
-        }
+	memset(&gdth_pcistr, 0, sizeof(gdth_pcistr));
+
+	if (vendor == PCI_VENDOR_ID_VORTEX && !gdth_search_vortex(device))
+		return -ENODEV;
+
+	rc = pci_enable_device(pdev);
+	if (rc)
+		return rc;
+
+	if (gdth_ctr_count >= MAXHA)
+		return -EBUSY;
 
 
         /* GDT PCI controller found, resources are already in pdev */
         /* GDT PCI controller found, resources are already in pdev */
-        pcistr[*cnt].pdev = pdev;
-        pcistr[*cnt].irq = pdev->irq;
+	gdth_pcistr.pdev = pdev;
         base0 = pci_resource_flags(pdev, 0);
         base0 = pci_resource_flags(pdev, 0);
         base1 = pci_resource_flags(pdev, 1);
         base1 = pci_resource_flags(pdev, 1);
         base2 = pci_resource_flags(pdev, 2);
         base2 = pci_resource_flags(pdev, 2);
         if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
         if (device <= PCI_DEVICE_ID_VORTEX_GDT6000B ||   /* GDT6000/B */
             device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
             device >= PCI_DEVICE_ID_VORTEX_GDT6x17RP) {  /* MPR */
             if (!(base0 & IORESOURCE_MEM)) 
             if (!(base0 & IORESOURCE_MEM)) 
-                continue;
-            pcistr[*cnt].dpmem = pci_resource_start(pdev, 0);
+		return -ENODEV;
+	    gdth_pcistr.dpmem = pci_resource_start(pdev, 0);
         } else {                                  /* GDT6110, GDT6120, .. */
         } else {                                  /* GDT6110, GDT6120, .. */
             if (!(base0 & IORESOURCE_MEM) ||
             if (!(base0 & IORESOURCE_MEM) ||
                 !(base2 & IORESOURCE_MEM) ||
                 !(base2 & IORESOURCE_MEM) ||
                 !(base1 & IORESOURCE_IO)) 
                 !(base1 & IORESOURCE_IO)) 
-                continue;
-            pcistr[*cnt].dpmem = pci_resource_start(pdev, 2);
-            pcistr[*cnt].io_mm = pci_resource_start(pdev, 0);
-            pcistr[*cnt].io    = pci_resource_start(pdev, 1);
+		return -ENODEV;
+	    gdth_pcistr.dpmem = pci_resource_start(pdev, 2);
+	    gdth_pcistr.io    = pci_resource_start(pdev, 1);
         }
         }
         TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
         TRACE2(("Controller found at %d/%d, irq %d, dpmem 0x%lx\n",
-                pcistr[*cnt].pdev->bus->number,
-		PCI_SLOT(pcistr[*cnt].pdev->devfn),
-                pcistr[*cnt].irq, pcistr[*cnt].dpmem));
-        (*cnt)++;
-    }       
-}   
+		gdth_pcistr.pdev->bus->number,
+		PCI_SLOT(gdth_pcistr.pdev->devfn),
+		gdth_pcistr.irq,
+		gdth_pcistr.dpmem));
 
 
-static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt)
-{    
-    gdth_pci_str temp;
-    int i, changed;
-    
-    TRACE(("gdth_sort_pci() cnt %d\n",cnt));
-    if (cnt == 0)
-        return;
+	rc = gdth_pci_probe_one(&gdth_pcistr, &ha);
+	if (rc)
+		return rc;
 
 
-    do {
-        changed = FALSE;
-        for (i = 0; i < cnt-1; ++i) {
-            if (!reverse_scan) {
-                if ((pcistr[i].pdev->bus->number > pcistr[i+1].pdev->bus->number) ||
-                    (pcistr[i].pdev->bus->number == pcistr[i+1].pdev->bus->number &&
-                     PCI_SLOT(pcistr[i].pdev->devfn) >
-                     PCI_SLOT(pcistr[i+1].pdev->devfn))) {
-                    temp = pcistr[i];
-                    pcistr[i] = pcistr[i+1];
-                    pcistr[i+1] = temp;
-                    changed = TRUE;
-                }
-            } else {
-                if ((pcistr[i].pdev->bus->number < pcistr[i+1].pdev->bus->number) ||
-                    (pcistr[i].pdev->bus->number == pcistr[i+1].pdev->bus->number &&
-                     PCI_SLOT(pcistr[i].pdev->devfn) <
-                     PCI_SLOT(pcistr[i+1].pdev->devfn))) {
-                    temp = pcistr[i];
-                    pcistr[i] = pcistr[i+1];
-                    pcistr[i+1] = temp;
-                    changed = TRUE;
-                }
-            }
-        }
-    } while (changed);
+	return 0;
 }
 }
 #endif /* CONFIG_PCI */
 #endif /* CONFIG_PCI */
 
 
@@ -909,7 +854,8 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha)
 #endif /* CONFIG_ISA */
 #endif /* CONFIG_ISA */
 
 
 #ifdef CONFIG_PCI
 #ifdef CONFIG_PCI
-static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
+static int gdth_init_pci(struct pci_dev *pdev, gdth_pci_str *pcistr,
+				   gdth_ha_str *ha)
 {
 {
     register gdt6_dpram_str __iomem *dp6_ptr;
     register gdt6_dpram_str __iomem *dp6_ptr;
     register gdt6c_dpram_str __iomem *dp6c_ptr;
     register gdt6c_dpram_str __iomem *dp6c_ptr;
@@ -921,14 +867,14 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
 
 
     TRACE(("gdth_init_pci()\n"));
     TRACE(("gdth_init_pci()\n"));
 
 
-    if (pcistr->pdev->vendor == PCI_VENDOR_ID_INTEL)
+    if (pdev->vendor == PCI_VENDOR_ID_INTEL)
         ha->oem_id = OEM_ID_INTEL;
         ha->oem_id = OEM_ID_INTEL;
     else
     else
         ha->oem_id = OEM_ID_ICP;
         ha->oem_id = OEM_ID_ICP;
-    ha->brd_phys = (pcistr->pdev->bus->number << 8) | (pcistr->pdev->devfn & 0xf8);
-    ha->stype = (ulong32)pcistr->pdev->device;
-    ha->irq = pcistr->irq;
-    ha->pdev = pcistr->pdev;
+    ha->brd_phys = (pdev->bus->number << 8) | (pdev->devfn & 0xf8);
+    ha->stype = (ulong32)pdev->device;
+    ha->irq = pdev->irq;
+    ha->pdev = pdev;
     
     
     if (ha->pdev->device <= PCI_DEVICE_ID_VORTEX_GDT6000B) {  /* GDT6000/B */
     if (ha->pdev->device <= PCI_DEVICE_ID_VORTEX_GDT6000B) {  /* GDT6000/B */
         TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq));
         TRACE2(("init_pci() dpmem %lx irq %d\n",pcistr->dpmem,ha->irq));
@@ -956,8 +902,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
                     continue;
                     continue;
                 }
                 }
                 iounmap(ha->brd);
                 iounmap(ha->brd);
-                pci_write_config_dword(pcistr->pdev, 
-                                       PCI_BASE_ADDRESS_0, i);
+		pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, i);
                 ha->brd = ioremap(i, sizeof(gdt6_dpram_str)); 
                 ha->brd = ioremap(i, sizeof(gdt6_dpram_str)); 
                 if (ha->brd == NULL) {
                 if (ha->brd == NULL) {
                     printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
                     printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
@@ -1066,8 +1011,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
                     continue;
                     continue;
                 }
                 }
                 iounmap(ha->brd);
                 iounmap(ha->brd);
-                pci_write_config_dword(pcistr->pdev, 
-                                       PCI_BASE_ADDRESS_2, i);
+		pci_write_config_dword(pdev, PCI_BASE_ADDRESS_2, i);
                 ha->brd = ioremap(i, sizeof(gdt6c_dpram_str)); 
                 ha->brd = ioremap(i, sizeof(gdt6c_dpram_str)); 
                 if (ha->brd == NULL) {
                 if (ha->brd == NULL) {
                     printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
                     printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
@@ -1159,16 +1103,16 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
         }
         }
 
 
         /* manipulate config. space to enable DPMEM, start RP controller */
         /* manipulate config. space to enable DPMEM, start RP controller */
-        pci_read_config_word(pcistr->pdev, PCI_COMMAND, &command);
+	pci_read_config_word(pdev, PCI_COMMAND, &command);
         command |= 6;
         command |= 6;
-        pci_write_config_word(pcistr->pdev, PCI_COMMAND, command);
-        if (pci_resource_start(pcistr->pdev, 8) == 1UL)
-            pci_resource_start(pcistr->pdev, 8) = 0UL;
+	pci_write_config_word(pdev, PCI_COMMAND, command);
+	if (pci_resource_start(pdev, 8) == 1UL)
+	    pci_resource_start(pdev, 8) = 0UL;
         i = 0xFEFF0001UL;
         i = 0xFEFF0001UL;
-        pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS, i);
+	pci_write_config_dword(pdev, PCI_ROM_ADDRESS, i);
         gdth_delay(1);
         gdth_delay(1);
-        pci_write_config_dword(pcistr->pdev, PCI_ROM_ADDRESS,
-                               pci_resource_start(pcistr->pdev, 8));
+	pci_write_config_dword(pdev, PCI_ROM_ADDRESS,
+			       pci_resource_start(pdev, 8));
         
         
         dp6m_ptr = ha->brd;
         dp6m_ptr = ha->brd;
 
 
@@ -1195,8 +1139,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha)
                     continue;
                     continue;
                 }
                 }
                 iounmap(ha->brd);
                 iounmap(ha->brd);
-                pci_write_config_dword(pcistr->pdev, 
-                                       PCI_BASE_ADDRESS_0, i);
+		pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, i);
                 ha->brd = ioremap(i, sizeof(gdt6m_dpram_str)); 
                 ha->brd = ioremap(i, sizeof(gdt6m_dpram_str)); 
                 if (ha->brd == NULL) {
                 if (ha->brd == NULL) {
                     printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
                     printk("GDT-PCI: Initialization error (DPMEM remap error)\n");
@@ -2353,12 +2296,12 @@ static void gdth_next(gdth_ha_str *ha)
 static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
 static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
                                     char *buffer, ushort count)
                                     char *buffer, ushort count)
 {
 {
-    ushort cpcount,i, max_sg = gdth_sg_count(scp);
+    ushort cpcount,i, max_sg = scsi_sg_count(scp);
     ushort cpsum,cpnow;
     ushort cpsum,cpnow;
     struct scatterlist *sl;
     struct scatterlist *sl;
     char *address;
     char *address;
 
 
-    cpcount = min_t(ushort, count, gdth_bufflen(scp));
+    cpcount = min_t(ushort, count, scsi_bufflen(scp));
 
 
     if (cpcount) {
     if (cpcount) {
         cpsum=0;
         cpsum=0;
@@ -2366,7 +2309,7 @@ static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp,
             unsigned long flags;
             unsigned long flags;
             cpnow = (ushort)sl->length;
             cpnow = (ushort)sl->length;
             TRACE(("copy_internal() now %d sum %d count %d %d\n",
             TRACE(("copy_internal() now %d sum %d count %d %d\n",
-                          cpnow, cpsum, cpcount, gdth_bufflen(scp)));
+                          cpnow, cpsum, cpcount, scsi_bufflen(scp)));
             if (cpsum+cpnow > cpcount) 
             if (cpsum+cpnow > cpcount) 
                 cpnow = cpcount - cpsum;
                 cpnow = cpcount - cpsum;
             cpsum += cpnow;
             cpsum += cpnow;
@@ -2589,10 +2532,10 @@ static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive)
             cmdp->u.cache.BlockCnt = blockcnt;
             cmdp->u.cache.BlockCnt = blockcnt;
         }
         }
 
 
-        if (gdth_bufflen(scp)) {
+        if (scsi_bufflen(scp)) {
             cmndinfo->dma_dir = (read_write == 1 ?
             cmndinfo->dma_dir = (read_write == 1 ?
                 PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);   
                 PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);   
-            sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp),
+            sgcnt = pci_map_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp),
                                cmndinfo->dma_dir);
                                cmndinfo->dma_dir);
             if (mode64) {
             if (mode64) {
                 struct scatterlist *sl;
                 struct scatterlist *sl;
@@ -2739,7 +2682,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b)
             cmdp->u.raw64.lun        = l;
             cmdp->u.raw64.lun        = l;
             cmdp->u.raw64.bus        = b;
             cmdp->u.raw64.bus        = b;
             cmdp->u.raw64.priority   = 0;
             cmdp->u.raw64.priority   = 0;
-            cmdp->u.raw64.sdlen      = gdth_bufflen(scp);
+            cmdp->u.raw64.sdlen      = scsi_bufflen(scp);
             cmdp->u.raw64.sense_len  = 16;
             cmdp->u.raw64.sense_len  = 16;
             cmdp->u.raw64.sense_data = sense_paddr;
             cmdp->u.raw64.sense_data = sense_paddr;
             cmdp->u.raw64.direction  = 
             cmdp->u.raw64.direction  = 
@@ -2756,7 +2699,7 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b)
             cmdp->u.raw.bus        = b;
             cmdp->u.raw.bus        = b;
             cmdp->u.raw.priority   = 0;
             cmdp->u.raw.priority   = 0;
             cmdp->u.raw.link_p     = 0;
             cmdp->u.raw.link_p     = 0;
-            cmdp->u.raw.sdlen      = gdth_bufflen(scp);
+            cmdp->u.raw.sdlen      = scsi_bufflen(scp);
             cmdp->u.raw.sense_len  = 16;
             cmdp->u.raw.sense_len  = 16;
             cmdp->u.raw.sense_data = sense_paddr;
             cmdp->u.raw.sense_data = sense_paddr;
             cmdp->u.raw.direction  = 
             cmdp->u.raw.direction  = 
@@ -2765,9 +2708,9 @@ static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b)
             cmdp->u.raw.sg_ranz    = 0;
             cmdp->u.raw.sg_ranz    = 0;
         }
         }
 
 
-        if (gdth_bufflen(scp)) {
+        if (scsi_bufflen(scp)) {
             cmndinfo->dma_dir = PCI_DMA_BIDIRECTIONAL;
             cmndinfo->dma_dir = PCI_DMA_BIDIRECTIONAL;
-            sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp),
+            sgcnt = pci_map_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp),
                                cmndinfo->dma_dir);
                                cmndinfo->dma_dir);
             if (mode64) {
             if (mode64) {
                 struct scatterlist *sl;
                 struct scatterlist *sl;
@@ -3388,8 +3331,8 @@ static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index,
             /* retry */
             /* retry */
             return 2;
             return 2;
         }
         }
-        if (gdth_bufflen(scp))
-            pci_unmap_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp),
+        if (scsi_bufflen(scp))
+            pci_unmap_sg(ha->pdev, scsi_sglist(scp), scsi_sg_count(scp),
                          cmndinfo->dma_dir);
                          cmndinfo->dma_dir);
 
 
         if (cmndinfo->sense_paddr)
         if (cmndinfo->sense_paddr)
@@ -4031,10 +3974,6 @@ static int gdth_queuecommand(struct scsi_cmnd *scp,
     gdth_update_timeout(scp, scp->timeout_per_command * 6);
     gdth_update_timeout(scp, scp->timeout_per_command * 6);
     cmndinfo->priority = DEFAULT_PRI;
     cmndinfo->priority = DEFAULT_PRI;
 
 
-    gdth_set_bufflen(scp, scsi_bufflen(scp));
-    gdth_set_sg_count(scp, scsi_sg_count(scp));
-    gdth_set_sglist(scp, scsi_sglist(scp));
-
     return __gdth_queuecommand(ha, scp, cmndinfo);
     return __gdth_queuecommand(ha, scp, cmndinfo);
 }
 }
 
 
@@ -4955,12 +4894,16 @@ static int __init gdth_eisa_probe_one(ushort eisa_slot)
 #endif /* CONFIG_EISA */
 #endif /* CONFIG_EISA */
 
 
 #ifdef CONFIG_PCI
 #ifdef CONFIG_PCI
-static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr)
+static int gdth_pci_probe_one(gdth_pci_str *pcistr,
+			     gdth_ha_str **ha_out)
 {
 {
 	struct Scsi_Host *shp;
 	struct Scsi_Host *shp;
 	gdth_ha_str *ha;
 	gdth_ha_str *ha;
 	dma_addr_t scratch_dma_handle = 0;
 	dma_addr_t scratch_dma_handle = 0;
 	int error, i;
 	int error, i;
+	struct pci_dev *pdev = pcistr->pdev;
+
+	*ha_out = NULL;
 
 
 	shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str));
 	shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str));
 	if (!shp)
 	if (!shp)
@@ -4968,13 +4911,13 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr)
 	ha = shost_priv(shp);
 	ha = shost_priv(shp);
 
 
 	error = -ENODEV;
 	error = -ENODEV;
-	if (!gdth_init_pci(&pcistr[ctr],ha))
+	if (!gdth_init_pci(pdev, pcistr, ha))
 		goto out_host_put;
 		goto out_host_put;
 
 
 	/* controller found and initialized */
 	/* controller found and initialized */
 	printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n",
 	printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n",
-		pcistr[ctr].pdev->bus->number,
-		PCI_SLOT(pcistr[ctr].pdev->devfn),
+		pdev->bus->number,
+		PCI_SLOT(pdev->devfn),
 		ha->irq);
 		ha->irq);
 
 
 	error = request_irq(ha->irq, gdth_interrupt,
 	error = request_irq(ha->irq, gdth_interrupt,
@@ -5019,7 +4962,7 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr)
 
 
 	ha->scratch_busy = FALSE;
 	ha->scratch_busy = FALSE;
 	ha->req_first = NULL;
 	ha->req_first = NULL;
-	ha->tid_cnt = pcistr[ctr].pdev->device >= 0x200 ? MAXID : MAX_HDRIVES;
+	ha->tid_cnt = pdev->device >= 0x200 ? MAXID : MAX_HDRIVES;
 	if (max_ids > 0 && max_ids < ha->tid_cnt)
 	if (max_ids > 0 && max_ids < ha->tid_cnt)
 		ha->tid_cnt = max_ids;
 		ha->tid_cnt = max_ids;
 	for (i = 0; i < GDTH_MAXCMDS; ++i)
 	for (i = 0; i < GDTH_MAXCMDS; ++i)
@@ -5039,16 +4982,16 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr)
 	/* 64-bit DMA only supported from FW >= x.43 */
 	/* 64-bit DMA only supported from FW >= x.43 */
 	if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) ||
 	if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) ||
 	    !ha->dma64_support) {
 	    !ha->dma64_support) {
-		if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) {
+		if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
 			printk(KERN_WARNING "GDT-PCI %d: "
 			printk(KERN_WARNING "GDT-PCI %d: "
 				"Unable to set 32-bit DMA\n", ha->hanum);
 				"Unable to set 32-bit DMA\n", ha->hanum);
 				goto out_free_coal_stat;
 				goto out_free_coal_stat;
 		}
 		}
 	} else {
 	} else {
 		shp->max_cmd_len = 16;
 		shp->max_cmd_len = 16;
-		if (!pci_set_dma_mask(pcistr[ctr].pdev, DMA_64BIT_MASK)) {
+		if (!pci_set_dma_mask(pdev, DMA_64BIT_MASK)) {
 			printk("GDT-PCI %d: 64-bit DMA enabled\n", ha->hanum);
 			printk("GDT-PCI %d: 64-bit DMA enabled\n", ha->hanum);
-		} else if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) {
+		} else if (pci_set_dma_mask(pdev, DMA_32BIT_MASK)) {
 			printk(KERN_WARNING "GDT-PCI %d: "
 			printk(KERN_WARNING "GDT-PCI %d: "
 				"Unable to set 64/32-bit DMA\n", ha->hanum);
 				"Unable to set 64/32-bit DMA\n", ha->hanum);
 			goto out_free_coal_stat;
 			goto out_free_coal_stat;
@@ -5062,13 +5005,17 @@ static int __init gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr)
 	spin_lock_init(&ha->smp_lock);
 	spin_lock_init(&ha->smp_lock);
 	gdth_enable_int(ha);
 	gdth_enable_int(ha);
 
 
-	error = scsi_add_host(shp, &pcistr[ctr].pdev->dev);
+	error = scsi_add_host(shp, &pdev->dev);
 	if (error)
 	if (error)
 		goto out_free_coal_stat;
 		goto out_free_coal_stat;
 	list_add_tail(&ha->list, &gdth_instances);
 	list_add_tail(&ha->list, &gdth_instances);
 
 
+	pci_set_drvdata(ha->pdev, ha);
+
 	scsi_scan_host(shp);
 	scsi_scan_host(shp);
 
 
+	*ha_out = ha;
+
 	return 0;
 	return 0;
 
 
  out_free_coal_stat:
  out_free_coal_stat:
@@ -5185,16 +5132,8 @@ static int __init gdth_init(void)
 
 
 #ifdef CONFIG_PCI
 #ifdef CONFIG_PCI
 	/* scanning for PCI controllers */
 	/* scanning for PCI controllers */
-	{
-		gdth_pci_str pcistr[MAXHA];
-		int cnt,ctr;
-
-		cnt = gdth_search_pci(pcistr);
-		printk("GDT-HA: Found %d PCI Storage RAID Controllers\n", cnt);
-		gdth_sort_pci(pcistr,cnt);
-		for (ctr = 0; ctr < cnt; ++ctr)
-			gdth_pci_probe_one(pcistr, ctr);
-	}
+	if (pci_register_driver(&gdth_pci_driver) == 0)
+		gdth_pci_registered = true;
 #endif /* CONFIG_PCI */
 #endif /* CONFIG_PCI */
 
 
 	TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count));
 	TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count));
@@ -5227,6 +5166,11 @@ static void __exit gdth_exit(void)
 	del_timer_sync(&gdth_timer);
 	del_timer_sync(&gdth_timer);
 #endif
 #endif
 
 
+#ifdef CONFIG_PCI
+	if (gdth_pci_registered)
+		pci_unregister_driver(&gdth_pci_driver);
+#endif
+
 	list_for_each_entry(ha, &gdth_instances, list)
 	list_for_each_entry(ha, &gdth_instances, list)
 		gdth_remove_one(ha);
 		gdth_remove_one(ha);
 }
 }

+ 0 - 2
drivers/scsi/gdth.h

@@ -839,8 +839,6 @@ typedef struct {
     struct pci_dev      *pdev;
     struct pci_dev      *pdev;
     ulong               dpmem;                  /* DPRAM address */
     ulong               dpmem;                  /* DPRAM address */
     ulong               io;                     /* IO address */
     ulong               io;                     /* IO address */
-    ulong               io_mm;                  /* IO address mem. mapped */
-    unchar              irq;                    /* IRQ */
 } gdth_pci_str;
 } gdth_pci_str;
 
 
 
 

+ 3 - 0
drivers/scsi/gvp11.c

@@ -322,6 +322,9 @@ int __init gvp11_detect(struct scsi_host_template *tpnt)
 	 */
 	 */
 	regs.SASR = &(DMA(instance)->SASR);
 	regs.SASR = &(DMA(instance)->SASR);
 	regs.SCMD = &(DMA(instance)->SCMD);
 	regs.SCMD = &(DMA(instance)->SCMD);
+	HDATA(instance)->no_sync = 0xff;
+	HDATA(instance)->fast = 0;
+	HDATA(instance)->dma_mode = CTRL_DMA;
 	wd33c93_init(instance, regs, dma_setup, dma_stop,
 	wd33c93_init(instance, regs, dma_setup, dma_stop,
 		     (epc & GVP_SCSICLKMASK) ? WD33C93_FS_8_10
 		     (epc & GVP_SCSICLKMASK) ? WD33C93_FS_8_10
 					     : WD33C93_FS_12_15);
 					     : WD33C93_FS_12_15);

+ 0 - 1
drivers/scsi/hosts.c

@@ -347,7 +347,6 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
 	shost->unchecked_isa_dma = sht->unchecked_isa_dma;
 	shost->unchecked_isa_dma = sht->unchecked_isa_dma;
 	shost->use_clustering = sht->use_clustering;
 	shost->use_clustering = sht->use_clustering;
 	shost->ordered_tag = sht->ordered_tag;
 	shost->ordered_tag = sht->ordered_tag;
-	shost->active_mode = sht->supported_mode;
 
 
 	if (sht->supported_mode == MODE_UNKNOWN)
 	if (sht->supported_mode == MODE_UNKNOWN)
 		/* means we didn't set it ... default to INITIATOR */
 		/* means we didn't set it ... default to INITIATOR */

+ 4 - 3
drivers/scsi/hptiop.c

@@ -338,7 +338,8 @@ static int iop_get_config_mv(struct hptiop_hba *hba,
 	req->header.size =
 	req->header.size =
 		cpu_to_le32(sizeof(struct hpt_iop_request_get_config));
 		cpu_to_le32(sizeof(struct hpt_iop_request_get_config));
 	req->header.result = cpu_to_le32(IOP_RESULT_PENDING);
 	req->header.result = cpu_to_le32(IOP_RESULT_PENDING);
-	req->header.context = cpu_to_le64(IOP_REQUEST_TYPE_GET_CONFIG<<5);
+	req->header.context = cpu_to_le32(IOP_REQUEST_TYPE_GET_CONFIG<<5);
+	req->header.context_hi32 = 0;
 
 
 	if (iop_send_sync_request_mv(hba, 0, 20000)) {
 	if (iop_send_sync_request_mv(hba, 0, 20000)) {
 		dprintk("Get config send cmd failed\n");
 		dprintk("Get config send cmd failed\n");
@@ -392,7 +393,8 @@ static int iop_set_config_mv(struct hptiop_hba *hba,
 	req->header.size =
 	req->header.size =
 		cpu_to_le32(sizeof(struct hpt_iop_request_set_config));
 		cpu_to_le32(sizeof(struct hpt_iop_request_set_config));
 	req->header.result = cpu_to_le32(IOP_RESULT_PENDING);
 	req->header.result = cpu_to_le32(IOP_RESULT_PENDING);
-	req->header.context = cpu_to_le64(IOP_REQUEST_TYPE_SET_CONFIG<<5);
+	req->header.context = cpu_to_le32(IOP_REQUEST_TYPE_SET_CONFIG<<5);
+	req->header.context_hi32 = 0;
 
 
 	if (iop_send_sync_request_mv(hba, 0, 20000)) {
 	if (iop_send_sync_request_mv(hba, 0, 20000)) {
 		dprintk("Set config send cmd failed\n");
 		dprintk("Set config send cmd failed\n");
@@ -903,7 +905,6 @@ static struct scsi_host_template driver_template = {
 	.eh_device_reset_handler    = hptiop_reset,
 	.eh_device_reset_handler    = hptiop_reset,
 	.eh_bus_reset_handler       = hptiop_reset,
 	.eh_bus_reset_handler       = hptiop_reset,
 	.info                       = hptiop_info,
 	.info                       = hptiop_info,
-	.unchecked_isa_dma          = 0,
 	.emulated                   = 0,
 	.emulated                   = 0,
 	.use_clustering             = ENABLE_CLUSTERING,
 	.use_clustering             = ENABLE_CLUSTERING,
 	.proc_name                  = driver_name,
 	.proc_name                  = driver_name,

+ 5 - 4
drivers/scsi/initio.c

@@ -2581,8 +2581,8 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c
 	/* Map the sense buffer into bus memory */
 	/* Map the sense buffer into bus memory */
 	dma_addr = dma_map_single(&host->pci_dev->dev, cmnd->sense_buffer,
 	dma_addr = dma_map_single(&host->pci_dev->dev, cmnd->sense_buffer,
 				  SENSE_SIZE, DMA_FROM_DEVICE);
 				  SENSE_SIZE, DMA_FROM_DEVICE);
-	cblk->senseptr = cpu_to_le32((u32)dma_addr);
-	cblk->senselen = cpu_to_le32(SENSE_SIZE);
+	cblk->senseptr = (u32)dma_addr;
+	cblk->senselen = SENSE_SIZE;
 	cmnd->SCp.ptr = (char *)(unsigned long)dma_addr;
 	cmnd->SCp.ptr = (char *)(unsigned long)dma_addr;
 	cblk->cdblen = cmnd->cmd_len;
 	cblk->cdblen = cmnd->cmd_len;
 
 
@@ -2606,7 +2606,7 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c
 		dma_addr = dma_map_single(&host->pci_dev->dev, &cblk->sglist[0],
 		dma_addr = dma_map_single(&host->pci_dev->dev, &cblk->sglist[0],
 					  sizeof(struct sg_entry) * TOTAL_SG_ENTRY,
 					  sizeof(struct sg_entry) * TOTAL_SG_ENTRY,
 					  DMA_BIDIRECTIONAL);
 					  DMA_BIDIRECTIONAL);
-		cblk->bufptr = cpu_to_le32((u32)dma_addr);
+		cblk->bufptr = (u32)dma_addr;
 		cmnd->SCp.dma_handle = dma_addr;
 		cmnd->SCp.dma_handle = dma_addr;
 
 
 		cblk->sglen = nseg;
 		cblk->sglen = nseg;
@@ -2616,7 +2616,8 @@ static void initio_build_scb(struct initio_host * host, struct scsi_ctrl_blk * c
 		sg = &cblk->sglist[0];
 		sg = &cblk->sglist[0];
 		scsi_for_each_sg(cmnd, sglist, cblk->sglen, i) {
 		scsi_for_each_sg(cmnd, sglist, cblk->sglen, i) {
 			sg->data = cpu_to_le32((u32)sg_dma_address(sglist));
 			sg->data = cpu_to_le32((u32)sg_dma_address(sglist));
-			total_len += sg->len = cpu_to_le32((u32)sg_dma_len(sglist));
+			sg->len = cpu_to_le32((u32)sg_dma_len(sglist));
+			total_len += sg_dma_len(sglist);
 			++sg;
 			++sg;
 		}
 		}
 
 

+ 26 - 63
drivers/scsi/ips.c

@@ -2377,7 +2377,7 @@ ips_get_bios_version(ips_ha_t * ha, int intr)
 			if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
 			if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
 				return;
 				return;
 
 
-			outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
+			outl(1, ha->io_addr + IPS_REG_FLAP);
 			if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
 			if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
 				udelay(25);	/* 25 us */
 				udelay(25);	/* 25 us */
 
 
@@ -2385,21 +2385,21 @@ ips_get_bios_version(ips_ha_t * ha, int intr)
 				return;
 				return;
 
 
 			/* Get Major version */
 			/* Get Major version */
-			outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP);
+			outl(0x1FF, ha->io_addr + IPS_REG_FLAP);
 			if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
 			if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
 				udelay(25);	/* 25 us */
 				udelay(25);	/* 25 us */
 
 
 			major = inb(ha->io_addr + IPS_REG_FLDP);
 			major = inb(ha->io_addr + IPS_REG_FLDP);
 
 
 			/* Get Minor version */
 			/* Get Minor version */
-			outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP);
+			outl(0x1FE, ha->io_addr + IPS_REG_FLAP);
 			if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
 			if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
 				udelay(25);	/* 25 us */
 				udelay(25);	/* 25 us */
 
 
 			minor = inb(ha->io_addr + IPS_REG_FLDP);
 			minor = inb(ha->io_addr + IPS_REG_FLDP);
 
 
 			/* Get SubMinor version */
 			/* Get SubMinor version */
-			outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP);
+			outl(0x1FD, ha->io_addr + IPS_REG_FLAP);
 			if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
 			if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
 				udelay(25);	/* 25 us */
 				udelay(25);	/* 25 us */
 
 
@@ -3502,27 +3502,11 @@ ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr)
 static void
 static void
 ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
 ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
 {
 {
-        int i;
-        unsigned int min_cnt, xfer_cnt;
-        char *cdata = (char *) data;
-        unsigned char *buffer;
-        unsigned long flags;
-        struct scatterlist *sg = scsi_sglist(scmd);
-
-        for (i = 0, xfer_cnt = 0;
-             (i < scsi_sg_count(scmd)) && (xfer_cnt < count); i++) {
-                min_cnt = min(count - xfer_cnt, sg[i].length);
-
-                /* kmap_atomic() ensures addressability of the data buffer.*/
-                /* local_irq_save() protects the KM_IRQ0 address slot.     */
-                local_irq_save(flags);
-                buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
-                memcpy(buffer, &cdata[xfer_cnt], min_cnt);
-                kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
-                local_irq_restore(flags);
+	unsigned long flags;
 
 
-                xfer_cnt += min_cnt;
-        }
+	local_irq_save(flags);
+	scsi_sg_copy_from_buffer(scmd, data, count);
+	local_irq_restore(flags);
 }
 }
 
 
 /****************************************************************************/
 /****************************************************************************/
@@ -3535,27 +3519,11 @@ ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
 static void
 static void
 ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
 ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
 {
 {
-        int i;
-        unsigned int min_cnt, xfer_cnt;
-        char *cdata = (char *) data;
-        unsigned char *buffer;
-        unsigned long flags;
-        struct scatterlist *sg = scsi_sglist(scmd);
-
-        for (i = 0, xfer_cnt = 0;
-             (i < scsi_sg_count(scmd)) && (xfer_cnt < count); i++) {
-                min_cnt = min(count - xfer_cnt, sg[i].length);
-
-                /* kmap_atomic() ensures addressability of the data buffer.*/
-                /* local_irq_save() protects the KM_IRQ0 address slot.     */
-                local_irq_save(flags);
-                buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
-                memcpy(&cdata[xfer_cnt], buffer, min_cnt);
-                kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
-                local_irq_restore(flags);
+	unsigned long flags;
 
 
-                xfer_cnt += min_cnt;
-        }
+	local_irq_save(flags);
+	scsi_sg_copy_to_buffer(scmd, data, count);
+	local_irq_restore(flags);
 }
 }
 
 
 /****************************************************************************/
 /****************************************************************************/
@@ -3696,9 +3664,7 @@ ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb)
 			scb->cmd.basic_io.sg_count = scb->sg_len;
 			scb->cmd.basic_io.sg_count = scb->sg_len;
 
 
 			if (scb->cmd.basic_io.lba)
 			if (scb->cmd.basic_io.lba)
-				scb->cmd.basic_io.lba =
-				    cpu_to_le32(le32_to_cpu
-						(scb->cmd.basic_io.lba) +
+				le32_add_cpu(&scb->cmd.basic_io.lba,
 						le16_to_cpu(scb->cmd.basic_io.
 						le16_to_cpu(scb->cmd.basic_io.
 							    sector_count));
 							    sector_count));
 			else
 			else
@@ -3744,9 +3710,7 @@ ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb)
 			scb->cmd.basic_io.sg_count = scb->sg_len;
 			scb->cmd.basic_io.sg_count = scb->sg_len;
 
 
 			if (scb->cmd.basic_io.lba)
 			if (scb->cmd.basic_io.lba)
-				scb->cmd.basic_io.lba =
-				    cpu_to_le32(le32_to_cpu
-						(scb->cmd.basic_io.lba) +
+				le32_add_cpu(&scb->cmd.basic_io.lba,
 						le16_to_cpu(scb->cmd.basic_io.
 						le16_to_cpu(scb->cmd.basic_io.
 							    sector_count));
 							    sector_count));
 			else
 			else
@@ -4888,7 +4852,7 @@ ips_init_copperhead(ips_ha_t * ha)
 		return (0);
 		return (0);
 
 
 	/* setup CCCR */
 	/* setup CCCR */
-	outl(cpu_to_le32(0x1010), ha->io_addr + IPS_REG_CCCR);
+	outl(0x1010, ha->io_addr + IPS_REG_CCCR);
 
 
 	/* Enable busmastering */
 	/* Enable busmastering */
 	outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR);
 	outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR);
@@ -5270,12 +5234,12 @@ ips_statinit(ips_ha_t * ha)
 	ha->adapt->p_status_tail = ha->adapt->status;
 	ha->adapt->p_status_tail = ha->adapt->status;
 
 
 	phys_status_start = ha->adapt->hw_status_start;
 	phys_status_start = ha->adapt->hw_status_start;
-	outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQSR);
-	outl(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE),
+	outl(phys_status_start, ha->io_addr + IPS_REG_SQSR);
+	outl(phys_status_start + IPS_STATUS_Q_SIZE,
 	     ha->io_addr + IPS_REG_SQER);
 	     ha->io_addr + IPS_REG_SQER);
-	outl(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE),
+	outl(phys_status_start + IPS_STATUS_SIZE,
 	     ha->io_addr + IPS_REG_SQHR);
 	     ha->io_addr + IPS_REG_SQHR);
-	outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQTR);
+	outl(phys_status_start, ha->io_addr + IPS_REG_SQTR);
 
 
 	ha->adapt->hw_status_tail = phys_status_start;
 	ha->adapt->hw_status_tail = phys_status_start;
 }
 }
@@ -5332,7 +5296,7 @@ ips_statupd_copperhead(ips_ha_t * ha)
 		ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
 		ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
 	}
 	}
 
 
-	outl(cpu_to_le32(ha->adapt->hw_status_tail),
+	outl(ha->adapt->hw_status_tail,
 	     ha->io_addr + IPS_REG_SQTR);
 	     ha->io_addr + IPS_REG_SQTR);
 
 
 	return (ha->adapt->p_status_tail->value);
 	return (ha->adapt->p_status_tail->value);
@@ -5434,8 +5398,8 @@ ips_issue_copperhead(ips_ha_t * ha, ips_scb_t * scb)
 		}		/* end if */
 		}		/* end if */
 	}			/* end while */
 	}			/* end while */
 
 
-	outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR);
-	outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR);
+	outl(scb->scb_busaddr, ha->io_addr + IPS_REG_CCSAR);
+	outw(IPS_BIT_START_CMD, ha->io_addr + IPS_REG_CCCR);
 
 
 	return (IPS_SUCCESS);
 	return (IPS_SUCCESS);
 }
 }
@@ -5520,7 +5484,7 @@ ips_issue_i2o(ips_ha_t * ha, ips_scb_t * scb)
 			  ips_name, ha->host_num, scb->cmd.basic_io.command_id);
 			  ips_name, ha->host_num, scb->cmd.basic_io.command_id);
 	}
 	}
 
 
-	outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ);
+	outl(scb->scb_busaddr, ha->io_addr + IPS_REG_I2O_INMSGQ);
 
 
 	return (IPS_SUCCESS);
 	return (IPS_SUCCESS);
 }
 }
@@ -6412,7 +6376,7 @@ ips_program_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize,
 
 
 	for (i = 0; i < buffersize; i++) {
 	for (i = 0; i < buffersize; i++) {
 		/* write a byte */
 		/* write a byte */
-		outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
+		outl(i + offset, ha->io_addr + IPS_REG_FLAP);
 		if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
 		if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
 			udelay(25);	/* 25 us */
 			udelay(25);	/* 25 us */
 
 
@@ -6597,7 +6561,7 @@ ips_verify_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize,
 	if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
 	if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
 		return (1);
 		return (1);
 
 
-	outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
+	outl(1, ha->io_addr + IPS_REG_FLAP);
 	if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
 	if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
 		udelay(25);	/* 25 us */
 		udelay(25);	/* 25 us */
 	if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
 	if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
@@ -6606,7 +6570,7 @@ ips_verify_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize,
 	checksum = 0xff;
 	checksum = 0xff;
 	for (i = 2; i < buffersize; i++) {
 	for (i = 2; i < buffersize; i++) {
 
 
-		outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
+		outl(i + offset, ha->io_addr + IPS_REG_FLAP);
 		if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
 		if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
 			udelay(25);	/* 25 us */
 			udelay(25);	/* 25 us */
 
 
@@ -6842,7 +6806,6 @@ ips_register_scsi(int index)
 	sh->sg_tablesize = sh->hostt->sg_tablesize;
 	sh->sg_tablesize = sh->hostt->sg_tablesize;
 	sh->can_queue = sh->hostt->can_queue;
 	sh->can_queue = sh->hostt->can_queue;
 	sh->cmd_per_lun = sh->hostt->cmd_per_lun;
 	sh->cmd_per_lun = sh->hostt->cmd_per_lun;
-	sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma;
 	sh->use_clustering = sh->hostt->use_clustering;
 	sh->use_clustering = sh->hostt->use_clustering;
 	sh->max_sectors = 128;
 	sh->max_sectors = 128;
 
 

+ 17 - 14
drivers/scsi/iscsi_tcp.c

@@ -528,6 +528,7 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
 	struct iscsi_session *session = conn->session;
 	struct iscsi_session *session = conn->session;
 	struct scsi_cmnd *sc = ctask->sc;
 	struct scsi_cmnd *sc = ctask->sc;
 	int datasn = be32_to_cpu(rhdr->datasn);
 	int datasn = be32_to_cpu(rhdr->datasn);
+	unsigned total_in_length = scsi_in(sc)->length;
 
 
 	iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr);
 	iscsi_update_cmdsn(session, (struct iscsi_nopin*)rhdr);
 	if (tcp_conn->in.datalen == 0)
 	if (tcp_conn->in.datalen == 0)
@@ -542,10 +543,10 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
 	tcp_ctask->exp_datasn++;
 	tcp_ctask->exp_datasn++;
 
 
 	tcp_ctask->data_offset = be32_to_cpu(rhdr->offset);
 	tcp_ctask->data_offset = be32_to_cpu(rhdr->offset);
-	if (tcp_ctask->data_offset + tcp_conn->in.datalen > scsi_bufflen(sc)) {
+	if (tcp_ctask->data_offset + tcp_conn->in.datalen > total_in_length) {
 		debug_tcp("%s: data_offset(%d) + data_len(%d) > total_length_in(%d)\n",
 		debug_tcp("%s: data_offset(%d) + data_len(%d) > total_length_in(%d)\n",
 		          __FUNCTION__, tcp_ctask->data_offset,
 		          __FUNCTION__, tcp_ctask->data_offset,
-		          tcp_conn->in.datalen, scsi_bufflen(sc));
+		          tcp_conn->in.datalen, total_in_length);
 		return ISCSI_ERR_DATA_OFFSET;
 		return ISCSI_ERR_DATA_OFFSET;
 	}
 	}
 
 
@@ -558,8 +559,8 @@ iscsi_data_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
 
 
 			if (res_count > 0 &&
 			if (res_count > 0 &&
 			    (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW ||
 			    (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW ||
-			     res_count <= scsi_bufflen(sc)))
-				scsi_set_resid(sc, res_count);
+			     res_count <= total_in_length))
+				scsi_in(sc)->resid = res_count;
 			else
 			else
 				sc->result = (DID_BAD_TARGET << 16) |
 				sc->result = (DID_BAD_TARGET << 16) |
 					rhdr->cmd_status;
 					rhdr->cmd_status;
@@ -670,11 +671,11 @@ iscsi_r2t_rsp(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
 			    r2t->data_length, session->max_burst);
 			    r2t->data_length, session->max_burst);
 
 
 	r2t->data_offset = be32_to_cpu(rhdr->data_offset);
 	r2t->data_offset = be32_to_cpu(rhdr->data_offset);
-	if (r2t->data_offset + r2t->data_length > scsi_bufflen(ctask->sc)) {
+	if (r2t->data_offset + r2t->data_length > scsi_out(ctask->sc)->length) {
 		iscsi_conn_printk(KERN_ERR, conn,
 		iscsi_conn_printk(KERN_ERR, conn,
 				  "invalid R2T with data len %u at offset %u "
 				  "invalid R2T with data len %u at offset %u "
 				  "and total length %d\n", r2t->data_length,
 				  "and total length %d\n", r2t->data_length,
-				  r2t->data_offset, scsi_bufflen(ctask->sc));
+				  r2t->data_offset, scsi_out(ctask->sc)->length);
 		__kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
 		__kfifo_put(tcp_ctask->r2tpool.queue, (void*)&r2t,
 			    sizeof(void*));
 			    sizeof(void*));
 		return ISCSI_ERR_DATALEN;
 		return ISCSI_ERR_DATALEN;
@@ -771,6 +772,7 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
 		if (tcp_conn->in.datalen) {
 		if (tcp_conn->in.datalen) {
 			struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
 			struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
 			struct hash_desc *rx_hash = NULL;
 			struct hash_desc *rx_hash = NULL;
+			struct scsi_data_buffer *sdb = scsi_in(ctask->sc);
 
 
 			/*
 			/*
 			 * Setup copy of Data-In into the Scsi_Cmnd
 			 * Setup copy of Data-In into the Scsi_Cmnd
@@ -788,8 +790,8 @@ iscsi_tcp_hdr_dissect(struct iscsi_conn *conn, struct iscsi_hdr *hdr)
 				  tcp_ctask->data_offset,
 				  tcp_ctask->data_offset,
 				  tcp_conn->in.datalen);
 				  tcp_conn->in.datalen);
 			return iscsi_segment_seek_sg(&tcp_conn->in.segment,
 			return iscsi_segment_seek_sg(&tcp_conn->in.segment,
-						     scsi_sglist(ctask->sc),
-						     scsi_sg_count(ctask->sc),
+						     sdb->table.sgl,
+						     sdb->table.nents,
 						     tcp_ctask->data_offset,
 						     tcp_ctask->data_offset,
 						     tcp_conn->in.datalen,
 						     tcp_conn->in.datalen,
 						     iscsi_tcp_process_data_in,
 						     iscsi_tcp_process_data_in,
@@ -1332,7 +1334,8 @@ iscsi_tcp_ctask_init(struct iscsi_cmd_task *ctask)
 		return 0;
 		return 0;
 
 
 	/* If we have immediate data, attach a payload */
 	/* If we have immediate data, attach a payload */
-	err = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc), scsi_sg_count(sc),
+	err = iscsi_tcp_send_data_prep(conn, scsi_out(sc)->table.sgl,
+				       scsi_out(sc)->table.nents,
 				       0, ctask->imm_count);
 				       0, ctask->imm_count);
 	if (err)
 	if (err)
 		return err;
 		return err;
@@ -1386,6 +1389,7 @@ iscsi_tcp_ctask_xmit(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask)
 {
 {
 	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
 	struct iscsi_tcp_cmd_task *tcp_ctask = ctask->dd_data;
 	struct scsi_cmnd *sc = ctask->sc;
 	struct scsi_cmnd *sc = ctask->sc;
+	struct scsi_data_buffer *sdb = scsi_out(sc);
 	int rc = 0;
 	int rc = 0;
 
 
 flush:
 flush:
@@ -1412,9 +1416,8 @@ flush:
 				ctask->itt, tcp_ctask->sent, ctask->data_count);
 				ctask->itt, tcp_ctask->sent, ctask->data_count);
 
 
 		iscsi_tcp_send_hdr_prep(conn, hdr, sizeof(*hdr));
 		iscsi_tcp_send_hdr_prep(conn, hdr, sizeof(*hdr));
-		rc = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc),
-					      scsi_sg_count(sc),
-					      tcp_ctask->sent,
+		rc = iscsi_tcp_send_data_prep(conn, sdb->table.sgl,
+					      sdb->table.nents, tcp_ctask->sent,
 					      ctask->data_count);
 					      ctask->data_count);
 		if (rc)
 		if (rc)
 			goto fail;
 			goto fail;
@@ -1460,8 +1463,8 @@ flush:
 		iscsi_tcp_send_hdr_prep(conn, &r2t->dtask.hdr,
 		iscsi_tcp_send_hdr_prep(conn, &r2t->dtask.hdr,
 					sizeof(struct iscsi_hdr));
 					sizeof(struct iscsi_hdr));
 
 
-		rc = iscsi_tcp_send_data_prep(conn, scsi_sglist(sc),
-					      scsi_sg_count(sc),
+		rc = iscsi_tcp_send_data_prep(conn, sdb->table.sgl,
+					      sdb->table.nents,
 					      r2t->data_offset + r2t->sent,
 					      r2t->data_offset + r2t->sent,
 					      r2t->data_count);
 					      r2t->data_count);
 		if (rc)
 		if (rc)

+ 120 - 20
drivers/scsi/libiscsi.c

@@ -137,6 +137,70 @@ static int iscsi_add_hdr(struct iscsi_cmd_task *ctask, unsigned len)
 	return 0;
 	return 0;
 }
 }
 
 
+/*
+ * make an extended cdb AHS
+ */
+static int iscsi_prep_ecdb_ahs(struct iscsi_cmd_task *ctask)
+{
+	struct scsi_cmnd *cmd = ctask->sc;
+	unsigned rlen, pad_len;
+	unsigned short ahslength;
+	struct iscsi_ecdb_ahdr *ecdb_ahdr;
+	int rc;
+
+	ecdb_ahdr = iscsi_next_hdr(ctask);
+	rlen = cmd->cmd_len - ISCSI_CDB_SIZE;
+
+	BUG_ON(rlen > sizeof(ecdb_ahdr->ecdb));
+	ahslength = rlen + sizeof(ecdb_ahdr->reserved);
+
+	pad_len = iscsi_padding(rlen);
+
+	rc = iscsi_add_hdr(ctask, sizeof(ecdb_ahdr->ahslength) +
+	                   sizeof(ecdb_ahdr->ahstype) + ahslength + pad_len);
+	if (rc)
+		return rc;
+
+	if (pad_len)
+		memset(&ecdb_ahdr->ecdb[rlen], 0, pad_len);
+
+	ecdb_ahdr->ahslength = cpu_to_be16(ahslength);
+	ecdb_ahdr->ahstype = ISCSI_AHSTYPE_CDB;
+	ecdb_ahdr->reserved = 0;
+	memcpy(ecdb_ahdr->ecdb, cmd->cmnd + ISCSI_CDB_SIZE, rlen);
+
+	debug_scsi("iscsi_prep_ecdb_ahs: varlen_cdb_len %d "
+		   "rlen %d pad_len %d ahs_length %d iscsi_headers_size %u\n",
+		   cmd->cmd_len, rlen, pad_len, ahslength, ctask->hdr_len);
+
+	return 0;
+}
+
+static int iscsi_prep_bidi_ahs(struct iscsi_cmd_task *ctask)
+{
+	struct scsi_cmnd *sc = ctask->sc;
+	struct iscsi_rlength_ahdr *rlen_ahdr;
+	int rc;
+
+	rlen_ahdr = iscsi_next_hdr(ctask);
+	rc = iscsi_add_hdr(ctask, sizeof(*rlen_ahdr));
+	if (rc)
+		return rc;
+
+	rlen_ahdr->ahslength =
+		cpu_to_be16(sizeof(rlen_ahdr->read_length) +
+						  sizeof(rlen_ahdr->reserved));
+	rlen_ahdr->ahstype = ISCSI_AHSTYPE_RLENGTH;
+	rlen_ahdr->reserved = 0;
+	rlen_ahdr->read_length = cpu_to_be32(scsi_in(sc)->length);
+
+	debug_scsi("bidi-in rlen_ahdr->read_length(%d) "
+		   "rlen_ahdr->ahslength(%d)\n",
+		   be32_to_cpu(rlen_ahdr->read_length),
+		   be16_to_cpu(rlen_ahdr->ahslength));
+	return 0;
+}
+
 /**
 /**
  * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu
  * iscsi_prep_scsi_cmd_pdu - prep iscsi scsi cmd pdu
  * @ctask: iscsi cmd task
  * @ctask: iscsi cmd task
@@ -150,7 +214,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
 	struct iscsi_session *session = conn->session;
 	struct iscsi_session *session = conn->session;
 	struct iscsi_cmd *hdr = ctask->hdr;
 	struct iscsi_cmd *hdr = ctask->hdr;
 	struct scsi_cmnd *sc = ctask->sc;
 	struct scsi_cmnd *sc = ctask->sc;
-	unsigned hdrlength;
+	unsigned hdrlength, cmd_len;
 	int rc;
 	int rc;
 
 
 	ctask->hdr_len = 0;
 	ctask->hdr_len = 0;
@@ -161,17 +225,30 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
 	hdr->flags = ISCSI_ATTR_SIMPLE;
 	hdr->flags = ISCSI_ATTR_SIMPLE;
 	int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun);
 	int_to_scsilun(sc->device->lun, (struct scsi_lun *)hdr->lun);
 	hdr->itt = build_itt(ctask->itt, session->age);
 	hdr->itt = build_itt(ctask->itt, session->age);
-	hdr->data_length = cpu_to_be32(scsi_bufflen(sc));
 	hdr->cmdsn = cpu_to_be32(session->cmdsn);
 	hdr->cmdsn = cpu_to_be32(session->cmdsn);
 	session->cmdsn++;
 	session->cmdsn++;
 	hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
 	hdr->exp_statsn = cpu_to_be32(conn->exp_statsn);
-	memcpy(hdr->cdb, sc->cmnd, sc->cmd_len);
-	if (sc->cmd_len < MAX_COMMAND_SIZE)
-		memset(&hdr->cdb[sc->cmd_len], 0,
-			MAX_COMMAND_SIZE - sc->cmd_len);
+	cmd_len = sc->cmd_len;
+	if (cmd_len < ISCSI_CDB_SIZE)
+		memset(&hdr->cdb[cmd_len], 0, ISCSI_CDB_SIZE - cmd_len);
+	else if (cmd_len > ISCSI_CDB_SIZE) {
+		rc = iscsi_prep_ecdb_ahs(ctask);
+		if (rc)
+			return rc;
+		cmd_len = ISCSI_CDB_SIZE;
+	}
+	memcpy(hdr->cdb, sc->cmnd, cmd_len);
 
 
 	ctask->imm_count = 0;
 	ctask->imm_count = 0;
+	if (scsi_bidi_cmnd(sc)) {
+		hdr->flags |= ISCSI_FLAG_CMD_READ;
+		rc = iscsi_prep_bidi_ahs(ctask);
+		if (rc)
+			return rc;
+	}
 	if (sc->sc_data_direction == DMA_TO_DEVICE) {
 	if (sc->sc_data_direction == DMA_TO_DEVICE) {
+		unsigned out_len = scsi_out(sc)->length;
+		hdr->data_length = cpu_to_be32(out_len);
 		hdr->flags |= ISCSI_FLAG_CMD_WRITE;
 		hdr->flags |= ISCSI_FLAG_CMD_WRITE;
 		/*
 		/*
 		 * Write counters:
 		 * Write counters:
@@ -192,19 +269,19 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
 		ctask->unsol_datasn = 0;
 		ctask->unsol_datasn = 0;
 
 
 		if (session->imm_data_en) {
 		if (session->imm_data_en) {
-			if (scsi_bufflen(sc) >= session->first_burst)
+			if (out_len >= session->first_burst)
 				ctask->imm_count = min(session->first_burst,
 				ctask->imm_count = min(session->first_burst,
 							conn->max_xmit_dlength);
 							conn->max_xmit_dlength);
 			else
 			else
-				ctask->imm_count = min(scsi_bufflen(sc),
+				ctask->imm_count = min(out_len,
 							conn->max_xmit_dlength);
 							conn->max_xmit_dlength);
 			hton24(hdr->dlength, ctask->imm_count);
 			hton24(hdr->dlength, ctask->imm_count);
 		} else
 		} else
 			zero_data(hdr->dlength);
 			zero_data(hdr->dlength);
 
 
 		if (!session->initial_r2t_en) {
 		if (!session->initial_r2t_en) {
-			ctask->unsol_count = min((session->first_burst),
-				(scsi_bufflen(sc))) - ctask->imm_count;
+			ctask->unsol_count = min(session->first_burst, out_len)
+							     - ctask->imm_count;
 			ctask->unsol_offset = ctask->imm_count;
 			ctask->unsol_offset = ctask->imm_count;
 		}
 		}
 
 
@@ -214,6 +291,7 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
 	} else {
 	} else {
 		hdr->flags |= ISCSI_FLAG_CMD_FINAL;
 		hdr->flags |= ISCSI_FLAG_CMD_FINAL;
 		zero_data(hdr->dlength);
 		zero_data(hdr->dlength);
+		hdr->data_length = cpu_to_be32(scsi_in(sc)->length);
 
 
 		if (sc->sc_data_direction == DMA_FROM_DEVICE)
 		if (sc->sc_data_direction == DMA_FROM_DEVICE)
 			hdr->flags |= ISCSI_FLAG_CMD_READ;
 			hdr->flags |= ISCSI_FLAG_CMD_READ;
@@ -232,10 +310,12 @@ static int iscsi_prep_scsi_cmd_pdu(struct iscsi_cmd_task *ctask)
 		return EIO;
 		return EIO;
 
 
 	conn->scsicmd_pdus_cnt++;
 	conn->scsicmd_pdus_cnt++;
-	debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x len %d "
-		"cmdsn %d win %d]\n",
-		sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read",
-		conn->id, sc, sc->cmnd[0], ctask->itt, scsi_bufflen(sc),
+	debug_scsi("iscsi prep [%s cid %d sc %p cdb 0x%x itt 0x%x "
+		"len %d bidi_len %d cmdsn %d win %d]\n",
+		scsi_bidi_cmnd(sc) ? "bidirectional" :
+		     sc->sc_data_direction == DMA_TO_DEVICE ? "write" : "read",
+		conn->id, sc, sc->cmnd[0], ctask->itt,
+		scsi_bufflen(sc), scsi_bidi_cmnd(sc) ? scsi_in(sc)->length : 0,
 		session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
 		session->cmdsn, session->max_cmdsn - session->exp_cmdsn + 1);
 	return 0;
 	return 0;
 }
 }
@@ -298,7 +378,12 @@ static void fail_command(struct iscsi_conn *conn, struct iscsi_cmd_task *ctask,
 		conn->session->tt->cleanup_cmd_task(conn, ctask);
 		conn->session->tt->cleanup_cmd_task(conn, ctask);
 
 
 	sc->result = err;
 	sc->result = err;
-	scsi_set_resid(sc, scsi_bufflen(sc));
+	if (!scsi_bidi_cmnd(sc))
+		scsi_set_resid(sc, scsi_bufflen(sc));
+	else {
+		scsi_out(sc)->resid = scsi_out(sc)->length;
+		scsi_in(sc)->resid = scsi_in(sc)->length;
+	}
 	if (conn->ctask == ctask)
 	if (conn->ctask == ctask)
 		conn->ctask = NULL;
 		conn->ctask = NULL;
 	/* release ref from queuecommand */
 	/* release ref from queuecommand */
@@ -433,6 +518,18 @@ invalid_datalen:
 			   min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE));
 			   min_t(uint16_t, senselen, SCSI_SENSE_BUFFERSIZE));
 	}
 	}
 
 
+	if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW |
+			   ISCSI_FLAG_CMD_BIDI_OVERFLOW)) {
+		int res_count = be32_to_cpu(rhdr->bi_residual_count);
+
+		if (scsi_bidi_cmnd(sc) && res_count > 0 &&
+				(rhdr->flags & ISCSI_FLAG_CMD_BIDI_OVERFLOW ||
+				 res_count <= scsi_in(sc)->length))
+			scsi_in(sc)->resid = res_count;
+		else
+			sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
+	}
+
 	if (rhdr->flags & (ISCSI_FLAG_CMD_UNDERFLOW |
 	if (rhdr->flags & (ISCSI_FLAG_CMD_UNDERFLOW |
 	                   ISCSI_FLAG_CMD_OVERFLOW)) {
 	                   ISCSI_FLAG_CMD_OVERFLOW)) {
 		int res_count = be32_to_cpu(rhdr->residual_count);
 		int res_count = be32_to_cpu(rhdr->residual_count);
@@ -440,13 +537,11 @@ invalid_datalen:
 		if (res_count > 0 &&
 		if (res_count > 0 &&
 		    (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW ||
 		    (rhdr->flags & ISCSI_FLAG_CMD_OVERFLOW ||
 		     res_count <= scsi_bufflen(sc)))
 		     res_count <= scsi_bufflen(sc)))
+			/* write side for bidi or uni-io set_resid */
 			scsi_set_resid(sc, res_count);
 			scsi_set_resid(sc, res_count);
 		else
 		else
 			sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
 			sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
-	} else if (rhdr->flags & (ISCSI_FLAG_CMD_BIDI_UNDERFLOW |
-	                          ISCSI_FLAG_CMD_BIDI_OVERFLOW))
-		sc->result = (DID_BAD_TARGET << 16) | rhdr->cmd_status;
-
+	}
 out:
 out:
 	debug_scsi("done [sc %lx res %d itt 0x%x]\n",
 	debug_scsi("done [sc %lx res %d itt 0x%x]\n",
 		   (long)sc, sc->result, ctask->itt);
 		   (long)sc, sc->result, ctask->itt);
@@ -1102,7 +1197,12 @@ reject:
 fault:
 fault:
 	spin_unlock(&session->lock);
 	spin_unlock(&session->lock);
 	debug_scsi("iscsi: cmd 0x%x is not queued (%d)\n", sc->cmnd[0], reason);
 	debug_scsi("iscsi: cmd 0x%x is not queued (%d)\n", sc->cmnd[0], reason);
-	scsi_set_resid(sc, scsi_bufflen(sc));
+	if (!scsi_bidi_cmnd(sc))
+		scsi_set_resid(sc, scsi_bufflen(sc));
+	else {
+		scsi_out(sc)->resid = scsi_out(sc)->length;
+		scsi_in(sc)->resid = scsi_in(sc)->length;
+	}
 	sc->scsi_done(sc);
 	sc->scsi_done(sc);
 	spin_lock(host->host_lock);
 	spin_lock(host->host_lock);
 	return 0;
 	return 0;

+ 1 - 1
drivers/scsi/libsas/sas_ata.c

@@ -691,7 +691,7 @@ static int sas_discover_sata_dev(struct domain_device *dev)
 		/* incomplete response */
 		/* incomplete response */
 		SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to "
 		SAS_DPRINTK("sending SET FEATURE/PUP_STBY_SPIN_UP to "
 			    "dev %llx\n", SAS_ADDR(dev->sas_addr));
 			    "dev %llx\n", SAS_ADDR(dev->sas_addr));
-		if (!le16_to_cpu(identify_x[83] & (1<<6)))
+		if (!(identify_x[83] & cpu_to_le16(1<<6)))
 			goto cont1;
 			goto cont1;
 		res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES,
 		res = sas_issue_ata_cmd(dev, ATA_SET_FEATURES,
 					ATA_FEATURE_PUP_STBY_SPIN_UP,
 					ATA_FEATURE_PUP_STBY_SPIN_UP,

+ 41 - 0
drivers/scsi/libsas/sas_scsi_host.c

@@ -24,6 +24,8 @@
  */
  */
 
 
 #include <linux/kthread.h>
 #include <linux/kthread.h>
+#include <linux/firmware.h>
+#include <linux/ctype.h>
 
 
 #include "sas_internal.h"
 #include "sas_internal.h"
 
 
@@ -1064,6 +1066,45 @@ void sas_target_destroy(struct scsi_target *starget)
 	return;
 	return;
 }
 }
 
 
+static void sas_parse_addr(u8 *sas_addr, const char *p)
+{
+	int i;
+	for (i = 0; i < SAS_ADDR_SIZE; i++) {
+		u8 h, l;
+		if (!*p)
+			break;
+		h = isdigit(*p) ? *p-'0' : toupper(*p)-'A'+10;
+		p++;
+		l = isdigit(*p) ? *p-'0' : toupper(*p)-'A'+10;
+		p++;
+		sas_addr[i] = (h<<4) | l;
+	}
+}
+
+#define SAS_STRING_ADDR_SIZE	16
+
+int sas_request_addr(struct Scsi_Host *shost, u8 *addr)
+{
+	int res;
+	const struct firmware *fw;
+
+	res = request_firmware(&fw, "sas_addr", &shost->shost_gendev);
+	if (res)
+		return res;
+
+	if (fw->size < SAS_STRING_ADDR_SIZE) {
+		res = -ENODEV;
+		goto out;
+	}
+
+	sas_parse_addr(addr, fw->data);
+
+out:
+	release_firmware(fw);
+	return res;
+}
+EXPORT_SYMBOL_GPL(sas_request_addr);
+
 EXPORT_SYMBOL_GPL(sas_queuecommand);
 EXPORT_SYMBOL_GPL(sas_queuecommand);
 EXPORT_SYMBOL_GPL(sas_target_alloc);
 EXPORT_SYMBOL_GPL(sas_target_alloc);
 EXPORT_SYMBOL_GPL(sas_slave_configure);
 EXPORT_SYMBOL_GPL(sas_slave_configure);

+ 1 - 4
drivers/scsi/lpfc/lpfc.h

@@ -23,7 +23,7 @@
 
 
 struct lpfc_sli2_slim;
 struct lpfc_sli2_slim;
 
 
-#define LPFC_MAX_TARGET		256	/* max number of targets supported */
+#define LPFC_MAX_TARGET		4096	/* max number of targets supported */
 #define LPFC_MAX_DISC_THREADS	64	/* max outstanding discovery els
 #define LPFC_MAX_DISC_THREADS	64	/* max outstanding discovery els
 					   requests */
 					   requests */
 #define LPFC_MAX_NS_RETRY	3	/* Number of retry attempts to contact
 #define LPFC_MAX_NS_RETRY	3	/* Number of retry attempts to contact
@@ -268,7 +268,6 @@ struct lpfc_vport {
 #define FC_NLP_MORE             0x40	 /* More node to process in node tbl */
 #define FC_NLP_MORE             0x40	 /* More node to process in node tbl */
 #define FC_OFFLINE_MODE         0x80	 /* Interface is offline for diag */
 #define FC_OFFLINE_MODE         0x80	 /* Interface is offline for diag */
 #define FC_FABRIC               0x100	 /* We are fabric attached */
 #define FC_FABRIC               0x100	 /* We are fabric attached */
-#define FC_ESTABLISH_LINK       0x200	 /* Reestablish Link */
 #define FC_RSCN_DISCOVERY       0x400	 /* Auth all devices after RSCN */
 #define FC_RSCN_DISCOVERY       0x400	 /* Auth all devices after RSCN */
 #define FC_SCSI_SCAN_TMO        0x4000	 /* scsi scan timer running */
 #define FC_SCSI_SCAN_TMO        0x4000	 /* scsi scan timer running */
 #define FC_ABORT_DISCOVERY      0x8000	 /* we want to abort discovery */
 #define FC_ABORT_DISCOVERY      0x8000	 /* we want to abort discovery */
@@ -433,8 +432,6 @@ struct lpfc_hba {
 
 
 	uint32_t fc_eventTag;	/* event tag for link attention */
 	uint32_t fc_eventTag;	/* event tag for link attention */
 
 
-
-	struct timer_list fc_estabtmo;	/* link establishment timer */
 	/* These fields used to be binfo */
 	/* These fields used to be binfo */
 	uint32_t fc_pref_DID;	/* preferred D_ID */
 	uint32_t fc_pref_DID;	/* preferred D_ID */
 	uint8_t  fc_pref_ALPA;	/* preferred AL_PA */
 	uint8_t  fc_pref_ALPA;	/* preferred AL_PA */

+ 8 - 2
drivers/scsi/lpfc/lpfc_attr.c

@@ -1954,7 +1954,9 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
 			(phba->sysfs_mbox.mbox->mb.mbxCommand !=
 			(phba->sysfs_mbox.mbox->mb.mbxCommand !=
 				MBX_DUMP_MEMORY &&
 				MBX_DUMP_MEMORY &&
 			 phba->sysfs_mbox.mbox->mb.mbxCommand !=
 			 phba->sysfs_mbox.mbox->mb.mbxCommand !=
-				MBX_RESTART)) {
+				MBX_RESTART &&
+			 phba->sysfs_mbox.mbox->mb.mbxCommand !=
+				MBX_WRITE_VPARMS)) {
 			sysfs_mbox_idle(phba);
 			sysfs_mbox_idle(phba);
 			spin_unlock_irq(&phba->hbalock);
 			spin_unlock_irq(&phba->hbalock);
 			return -EPERM;
 			return -EPERM;
@@ -1962,7 +1964,11 @@ sysfs_mbox_read(struct kobject *kobj, struct bin_attribute *bin_attr,
 
 
 		phba->sysfs_mbox.mbox->vport = vport;
 		phba->sysfs_mbox.mbox->vport = vport;
 
 
-		if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO) {
+		/* Don't allow mailbox commands to be sent when blocked
+		 * or when in the middle of discovery
+		 */
+		if (phba->sli.sli_flag & LPFC_BLOCK_MGMT_IO ||
+		    vport->fc_flag & FC_NDISC_ACTIVE) {
 			sysfs_mbox_idle(phba);
 			sysfs_mbox_idle(phba);
 			spin_unlock_irq(&phba->hbalock);
 			spin_unlock_irq(&phba->hbalock);
 			return  -EAGAIN;
 			return  -EAGAIN;

+ 16 - 32
drivers/scsi/lpfc/lpfc_ct.c

@@ -63,7 +63,7 @@ lpfc_ct_ignore_hbq_buffer(struct lpfc_hba *phba, struct lpfc_iocbq *piocbq,
 {
 {
 	if (!mp) {
 	if (!mp) {
 		lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
 		lpfc_printf_log(phba, KERN_INFO, LOG_ELS,
-				"0146 Ignoring unsolicted CT No HBQ "
+				"0146 Ignoring unsolicited CT No HBQ "
 				"status = x%x\n",
 				"status = x%x\n",
 				piocbq->iocb.ulpStatus);
 				piocbq->iocb.ulpStatus);
 	}
 	}
@@ -438,7 +438,7 @@ lpfc_ns_rsp(struct lpfc_vport *vport, struct lpfc_dmabuf *mp, uint32_t Size)
 				    (!(vport->ct_flags & FC_CT_RFF_ID)) ||
 				    (!(vport->ct_flags & FC_CT_RFF_ID)) ||
 				    (!vport->cfg_restrict_login)) {
 				    (!vport->cfg_restrict_login)) {
 					ndlp = lpfc_setup_disc_node(vport, Did);
 					ndlp = lpfc_setup_disc_node(vport, Did);
-					if (ndlp) {
+					if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
 						lpfc_debugfs_disc_trc(vport,
 						lpfc_debugfs_disc_trc(vport,
 						LPFC_DISC_TRC_CT,
 						LPFC_DISC_TRC_CT,
 						"Parse GID_FTrsp: "
 						"Parse GID_FTrsp: "
@@ -543,7 +543,7 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 	struct lpfc_dmabuf *outp;
 	struct lpfc_dmabuf *outp;
 	struct lpfc_sli_ct_request *CTrsp;
 	struct lpfc_sli_ct_request *CTrsp;
 	struct lpfc_nodelist *ndlp;
 	struct lpfc_nodelist *ndlp;
-	int rc, retry;
+	int rc;
 
 
 	/* First save ndlp, before we overwrite it */
 	/* First save ndlp, before we overwrite it */
 	ndlp = cmdiocb->context_un.ndlp;
 	ndlp = cmdiocb->context_un.ndlp;
@@ -563,45 +563,29 @@ lpfc_cmpl_ct_cmd_gid_ft(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 	if (vport->load_flag & FC_UNLOADING)
 	if (vport->load_flag & FC_UNLOADING)
 		goto out;
 		goto out;
 
 
-	if (lpfc_els_chk_latt(vport) || lpfc_error_lost_link(irsp)) {
+	if (lpfc_els_chk_latt(vport)) {
 		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
 		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
 				 "0216 Link event during NS query\n");
 				 "0216 Link event during NS query\n");
 		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
 		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
 		goto out;
 		goto out;
 	}
 	}
-
+	if (lpfc_error_lost_link(irsp)) {
+		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
+				 "0226 NS query failed due to link event\n");
+		goto out;
+	}
 	if (irsp->ulpStatus) {
 	if (irsp->ulpStatus) {
 		/* Check for retry */
 		/* Check for retry */
 		if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
 		if (vport->fc_ns_retry < LPFC_MAX_NS_RETRY) {
-			retry = 1;
-			if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
-				switch (irsp->un.ulpWord[4]) {
-				case IOERR_NO_RESOURCES:
-					/* We don't increment the retry
-					 * count for this case.
-					 */
-					break;
-				case IOERR_LINK_DOWN:
-				case IOERR_SLI_ABORTED:
-				case IOERR_SLI_DOWN:
-					retry = 0;
-					break;
-				default:
-					vport->fc_ns_retry++;
-				}
-			}
-			else
+			if (irsp->ulpStatus != IOSTAT_LOCAL_REJECT ||
+			    irsp->un.ulpWord[4] != IOERR_NO_RESOURCES)
 				vport->fc_ns_retry++;
 				vport->fc_ns_retry++;
 
 
-			if (retry) {
-				/* CT command is being retried */
-				rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
+			/* CT command is being retried */
+			rc = lpfc_ns_cmd(vport, SLI_CTNS_GID_FT,
 					 vport->fc_ns_retry, 0);
 					 vport->fc_ns_retry, 0);
-				if (rc == 0) {
-					/* success */
-					goto out;
-				}
-			}
+			if (rc == 0)
+				goto out;
 		}
 		}
 		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
 		lpfc_vport_set_state(vport, FC_VPORT_FAILED);
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
@@ -780,7 +764,7 @@ lpfc_cmpl_ct_cmd_gff_id(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 
 
 	/* This is a target port, unregistered port, or the GFF_ID failed */
 	/* This is a target port, unregistered port, or the GFF_ID failed */
 	ndlp = lpfc_setup_disc_node(vport, did);
 	ndlp = lpfc_setup_disc_node(vport, did);
-	if (ndlp) {
+	if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
 		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
 		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
 				 "0242 Process x%x GFF "
 				 "0242 Process x%x GFF "
 				 "NameServer Rsp Data: x%x x%x x%x\n",
 				 "NameServer Rsp Data: x%x x%x x%x\n",

+ 2 - 0
drivers/scsi/lpfc/lpfc_debugfs.c

@@ -503,6 +503,8 @@ lpfc_debugfs_nodelist_data(struct lpfc_vport *vport, char *buf, int size)
 				ndlp->nlp_sid);
 				ndlp->nlp_sid);
 		if (ndlp->nlp_type & NLP_FCP_INITIATOR)
 		if (ndlp->nlp_type & NLP_FCP_INITIATOR)
 			len +=  snprintf(buf+len, size-len, "FCP_INITIATOR ");
 			len +=  snprintf(buf+len, size-len, "FCP_INITIATOR ");
+		len += snprintf(buf+len, size-len, "usgmap:%x ",
+			ndlp->nlp_usg_map);
 		len += snprintf(buf+len, size-len, "refcnt:%x",
 		len += snprintf(buf+len, size-len, "refcnt:%x",
 			atomic_read(&ndlp->kref.refcount));
 			atomic_read(&ndlp->kref.refcount));
 		len +=  snprintf(buf+len, size-len, "\n");
 		len +=  snprintf(buf+len, size-len, "\n");

+ 54 - 67
drivers/scsi/lpfc/lpfc_els.c

@@ -719,9 +719,9 @@ lpfc_els_abort_flogi(struct lpfc_hba *phba)
 		if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR &&
 		if (icmd->ulpCommand == CMD_ELS_REQUEST64_CR &&
 		    icmd->un.elsreq64.bdl.ulpIoTag32) {
 		    icmd->un.elsreq64.bdl.ulpIoTag32) {
 			ndlp = (struct lpfc_nodelist *)(iocb->context1);
 			ndlp = (struct lpfc_nodelist *)(iocb->context1);
-			if (ndlp && (ndlp->nlp_DID == Fabric_DID)) {
+			if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
+			    (ndlp->nlp_DID == Fabric_DID))
 				lpfc_sli_issue_abort_iotag(phba, pring, iocb);
 				lpfc_sli_issue_abort_iotag(phba, pring, iocb);
-			}
 		}
 		}
 	}
 	}
 	spin_unlock_irq(&phba->hbalock);
 	spin_unlock_irq(&phba->hbalock);
@@ -829,7 +829,7 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
 	struct fc_rport *rport;
 	struct fc_rport *rport;
 	struct serv_parm *sp;
 	struct serv_parm *sp;
 	uint8_t  name[sizeof(struct lpfc_name)];
 	uint8_t  name[sizeof(struct lpfc_name)];
-	uint32_t rc;
+	uint32_t rc, keepDID = 0;
 
 
 	/* Fabric nodes can have the same WWPN so we don't bother searching
 	/* Fabric nodes can have the same WWPN so we don't bother searching
 	 * by WWPN.  Just return the ndlp that was given to us.
 	 * by WWPN.  Just return the ndlp that was given to us.
@@ -858,11 +858,17 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
 			return ndlp;
 			return ndlp;
 		lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID);
 		lpfc_nlp_init(vport, new_ndlp, ndlp->nlp_DID);
 	} else if (!NLP_CHK_NODE_ACT(new_ndlp)) {
 	} else if (!NLP_CHK_NODE_ACT(new_ndlp)) {
+		rc = memcmp(&ndlp->nlp_portname, name,
+			    sizeof(struct lpfc_name));
+		if (!rc)
+			return ndlp;
 		new_ndlp = lpfc_enable_node(vport, new_ndlp,
 		new_ndlp = lpfc_enable_node(vport, new_ndlp,
 						NLP_STE_UNUSED_NODE);
 						NLP_STE_UNUSED_NODE);
 		if (!new_ndlp)
 		if (!new_ndlp)
 			return ndlp;
 			return ndlp;
-	}
+		keepDID = new_ndlp->nlp_DID;
+	} else
+		keepDID = new_ndlp->nlp_DID;
 
 
 	lpfc_unreg_rpi(vport, new_ndlp);
 	lpfc_unreg_rpi(vport, new_ndlp);
 	new_ndlp->nlp_DID = ndlp->nlp_DID;
 	new_ndlp->nlp_DID = ndlp->nlp_DID;
@@ -893,12 +899,24 @@ lpfc_plogi_confirm_nport(struct lpfc_hba *phba, uint32_t *prsp,
 			}
 			}
 			new_ndlp->nlp_type = ndlp->nlp_type;
 			new_ndlp->nlp_type = ndlp->nlp_type;
 		}
 		}
+		/* We shall actually free the ndlp with both nlp_DID and
+		 * nlp_portname fields equals 0 to avoid any ndlp on the
+		 * nodelist never to be used.
+		 */
+		if (ndlp->nlp_DID == 0) {
+			spin_lock_irq(&phba->ndlp_lock);
+			NLP_SET_FREE_REQ(ndlp);
+			spin_unlock_irq(&phba->ndlp_lock);
+		}
 
 
+		/* Two ndlps cannot have the same did on the nodelist */
+		ndlp->nlp_DID = keepDID;
 		lpfc_drop_node(vport, ndlp);
 		lpfc_drop_node(vport, ndlp);
 	}
 	}
 	else {
 	else {
 		lpfc_unreg_rpi(vport, ndlp);
 		lpfc_unreg_rpi(vport, ndlp);
-		ndlp->nlp_DID = 0; /* Two ndlps cannot have the same did */
+		/* Two ndlps cannot have the same did */
+		ndlp->nlp_DID = keepDID;
 		lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
 		lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
 	}
 	}
 	return new_ndlp;
 	return new_ndlp;
@@ -2091,7 +2109,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 		}
 		}
 
 
 		phba->fc_stat.elsXmitRetry++;
 		phba->fc_stat.elsXmitRetry++;
-		if (ndlp && delay) {
+		if (ndlp && NLP_CHK_NODE_ACT(ndlp) && delay) {
 			phba->fc_stat.elsDelayRetry++;
 			phba->fc_stat.elsDelayRetry++;
 			ndlp->nlp_retry = cmdiocb->retry;
 			ndlp->nlp_retry = cmdiocb->retry;
 
 
@@ -2121,7 +2139,7 @@ lpfc_els_retry(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 			lpfc_issue_els_fdisc(vport, ndlp, cmdiocb->retry);
 			lpfc_issue_els_fdisc(vport, ndlp, cmdiocb->retry);
 			return 1;
 			return 1;
 		case ELS_CMD_PLOGI:
 		case ELS_CMD_PLOGI:
-			if (ndlp) {
+			if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
 				ndlp->nlp_prev_state = ndlp->nlp_state;
 				ndlp->nlp_prev_state = ndlp->nlp_state;
 				lpfc_nlp_set_state(vport, ndlp,
 				lpfc_nlp_set_state(vport, ndlp,
 						   NLP_STE_PLOGI_ISSUE);
 						   NLP_STE_PLOGI_ISSUE);
@@ -2302,7 +2320,7 @@ lpfc_mbx_cmpl_dflt_rpi(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 	lpfc_mbuf_free(phba, mp->virt, mp->phys);
 	lpfc_mbuf_free(phba, mp->virt, mp->phys);
 	kfree(mp);
 	kfree(mp);
 	mempool_free(pmb, phba->mbox_mem_pool);
 	mempool_free(pmb, phba->mbox_mem_pool);
-	if (ndlp) {
+	if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
 		lpfc_nlp_put(ndlp);
 		lpfc_nlp_put(ndlp);
 		/* This is the end of the default RPI cleanup logic for this
 		/* This is the end of the default RPI cleanup logic for this
 		 * ndlp. If no other discovery threads are using this ndlp.
 		 * ndlp. If no other discovery threads are using this ndlp.
@@ -2335,7 +2353,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 	 * function can have cmdiocb->contest1 (ndlp) field set to NULL.
 	 * function can have cmdiocb->contest1 (ndlp) field set to NULL.
 	 */
 	 */
 	pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
 	pcmd = (uint8_t *) (((struct lpfc_dmabuf *) cmdiocb->context2)->virt);
-	if (ndlp && (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) {
+	if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
+	    (*((uint32_t *) (pcmd)) == ELS_CMD_LS_RJT)) {
 		/* A LS_RJT associated with Default RPI cleanup has its own
 		/* A LS_RJT associated with Default RPI cleanup has its own
 		 * seperate code path.
 		 * seperate code path.
 		 */
 		 */
@@ -2344,7 +2363,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 	}
 	}
 
 
 	/* Check to see if link went down during discovery */
 	/* Check to see if link went down during discovery */
-	if (!ndlp || lpfc_els_chk_latt(vport)) {
+	if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) || lpfc_els_chk_latt(vport)) {
 		if (mbox) {
 		if (mbox) {
 			mp = (struct lpfc_dmabuf *) mbox->context1;
 			mp = (struct lpfc_dmabuf *) mbox->context1;
 			if (mp) {
 			if (mp) {
@@ -2353,7 +2372,8 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 			}
 			}
 			mempool_free(mbox, phba->mbox_mem_pool);
 			mempool_free(mbox, phba->mbox_mem_pool);
 		}
 		}
-		if (ndlp && (ndlp->nlp_flag & NLP_RM_DFLT_RPI))
+		if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
+		    (ndlp->nlp_flag & NLP_RM_DFLT_RPI))
 			if (lpfc_nlp_not_used(ndlp)) {
 			if (lpfc_nlp_not_used(ndlp)) {
 				ndlp = NULL;
 				ndlp = NULL;
 				/* Indicate the node has already released,
 				/* Indicate the node has already released,
@@ -2443,7 +2463,7 @@ lpfc_cmpl_els_rsp(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 		mempool_free(mbox, phba->mbox_mem_pool);
 		mempool_free(mbox, phba->mbox_mem_pool);
 	}
 	}
 out:
 out:
-	if (ndlp) {
+	if (ndlp && NLP_CHK_NODE_ACT(ndlp)) {
 		spin_lock_irq(shost->host_lock);
 		spin_lock_irq(shost->host_lock);
 		ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI);
 		ndlp->nlp_flag &= ~(NLP_ACC_REGLOGIN | NLP_RM_DFLT_RPI);
 		spin_unlock_irq(shost->host_lock);
 		spin_unlock_irq(shost->host_lock);
@@ -3139,6 +3159,8 @@ lpfc_els_rcv_rscn(struct lpfc_vport *vport, struct lpfc_iocbq *cmdiocb,
 		/* Another thread is walking fc_rscn_id_list on this vport */
 		/* Another thread is walking fc_rscn_id_list on this vport */
 		spin_unlock_irq(shost->host_lock);
 		spin_unlock_irq(shost->host_lock);
 		vport->fc_flag |= FC_RSCN_DISCOVERY;
 		vport->fc_flag |= FC_RSCN_DISCOVERY;
+		/* Send back ACC */
+		lpfc_els_rsp_acc(vport, ELS_CMD_ACC, cmdiocb, ndlp, NULL);
 		return 0;
 		return 0;
 	}
 	}
 	/* Indicate we are walking fc_rscn_id_list on this vport */
 	/* Indicate we are walking fc_rscn_id_list on this vport */
@@ -3928,7 +3950,7 @@ lpfc_els_timeout_handler(struct lpfc_vport *vport)
 		else {
 		else {
 			struct lpfc_nodelist *ndlp;
 			struct lpfc_nodelist *ndlp;
 			ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext);
 			ndlp = __lpfc_findnode_rpi(vport, cmd->ulpContext);
-			if (ndlp)
+			if (ndlp && NLP_CHK_NODE_ACT(ndlp))
 				remote_ID = ndlp->nlp_DID;
 				remote_ID = ndlp->nlp_DID;
 		}
 		}
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
@@ -4097,21 +4119,22 @@ lpfc_els_unsol_buffer(struct lpfc_hba *phba, struct lpfc_sli_ring *pring,
 		newnode = 1;
 		newnode = 1;
 		if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
 		if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
 			ndlp->nlp_type |= NLP_FABRIC;
 			ndlp->nlp_type |= NLP_FABRIC;
-	} else {
-		if (!NLP_CHK_NODE_ACT(ndlp)) {
-			ndlp = lpfc_enable_node(vport, ndlp,
-						NLP_STE_UNUSED_NODE);
-			if (!ndlp)
-				goto dropit;
-		}
-		if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) {
-			/* This is simular to the new node path */
-			ndlp = lpfc_nlp_get(ndlp);
-			if (!ndlp)
-				goto dropit;
-			lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
-			newnode = 1;
-		}
+	} else if (!NLP_CHK_NODE_ACT(ndlp)) {
+		ndlp = lpfc_enable_node(vport, ndlp,
+					NLP_STE_UNUSED_NODE);
+		if (!ndlp)
+			goto dropit;
+		lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+		newnode = 1;
+		if ((did & Fabric_DID_MASK) == Fabric_DID_MASK)
+			ndlp->nlp_type |= NLP_FABRIC;
+	} else if (ndlp->nlp_state == NLP_STE_UNUSED_NODE) {
+		/* This is similar to the new node path */
+		ndlp = lpfc_nlp_get(ndlp);
+		if (!ndlp)
+			goto dropit;
+		lpfc_nlp_set_state(vport, ndlp, NLP_STE_NPR_NODE);
+		newnode = 1;
 	}
 	}
 
 
 	phba->fc_stat.elsRcvFrame++;
 	phba->fc_stat.elsRcvFrame++;
@@ -4451,7 +4474,6 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
 			return;
 			return;
 		}
 		}
 		lpfc_nlp_init(vport, ndlp, NameServer_DID);
 		lpfc_nlp_init(vport, ndlp, NameServer_DID);
-		ndlp->nlp_type |= NLP_FABRIC;
 	} else if (!NLP_CHK_NODE_ACT(ndlp)) {
 	} else if (!NLP_CHK_NODE_ACT(ndlp)) {
 		ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
 		ndlp = lpfc_enable_node(vport, ndlp, NLP_STE_UNUSED_NODE);
 		if (!ndlp) {
 		if (!ndlp) {
@@ -4465,6 +4487,7 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
 			return;
 			return;
 		}
 		}
 	}
 	}
+	ndlp->nlp_type |= NLP_FABRIC;
 
 
 	lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
 	lpfc_nlp_set_state(vport, ndlp, NLP_STE_PLOGI_ISSUE);
 
 
@@ -4481,8 +4504,8 @@ lpfc_do_scr_ns_plogi(struct lpfc_hba *phba, struct lpfc_vport *vport)
 		if (ndlp_fdmi) {
 		if (ndlp_fdmi) {
 			lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID);
 			lpfc_nlp_init(vport, ndlp_fdmi, FDMI_DID);
 			ndlp_fdmi->nlp_type |= NLP_FABRIC;
 			ndlp_fdmi->nlp_type |= NLP_FABRIC;
-			ndlp_fdmi->nlp_state =
-				NLP_STE_PLOGI_ISSUE;
+			lpfc_nlp_set_state(vport, ndlp_fdmi,
+				NLP_STE_PLOGI_ISSUE);
 			lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID,
 			lpfc_issue_els_plogi(vport, ndlp_fdmi->nlp_DID,
 					     0);
 					     0);
 		}
 		}
@@ -5074,39 +5097,3 @@ void lpfc_fabric_abort_hba(struct lpfc_hba *phba)
 		(piocb->iocb_cmpl) (phba, piocb, piocb);
 		(piocb->iocb_cmpl) (phba, piocb, piocb);
 	}
 	}
 }
 }
-
-
-#if 0
-void lpfc_fabric_abort_flogi(struct lpfc_hba *phba)
-{
-	LIST_HEAD(completions);
-	struct lpfc_iocbq *tmp_iocb, *piocb;
-	IOCB_t *cmd;
-	struct lpfc_nodelist *ndlp;
-
-	spin_lock_irq(&phba->hbalock);
-	list_for_each_entry_safe(piocb, tmp_iocb, &phba->fabric_iocb_list,
-				 list) {
-
-		cmd = &piocb->iocb;
-		ndlp = (struct lpfc_nodelist *) piocb->context1;
-		if (cmd->ulpCommand == CMD_ELS_REQUEST64_CR &&
-		    ndlp != NULL &&
-		    ndlp->nlp_DID == Fabric_DID)
-			list_move_tail(&piocb->list, &completions);
-	}
-	spin_unlock_irq(&phba->hbalock);
-
-	while (!list_empty(&completions)) {
-		piocb = list_get_first(&completions, struct lpfc_iocbq, list);
-		list_del_init(&piocb->list);
-
-		cmd = &piocb->iocb;
-		cmd->ulpStatus = IOSTAT_LOCAL_REJECT;
-		cmd->un.ulpWord[4] = IOERR_SLI_ABORTED;
-		(piocb->iocb_cmpl) (phba, piocb, piocb);
-	}
-}
-#endif  /*  0  */
-
-

+ 21 - 52
drivers/scsi/lpfc/lpfc_hbadisc.c

@@ -69,7 +69,7 @@ lpfc_terminate_rport_io(struct fc_rport *rport)
 	rdata = rport->dd_data;
 	rdata = rport->dd_data;
 	ndlp = rdata->pnode;
 	ndlp = rdata->pnode;
 
 
-	if (!ndlp) {
+	if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
 		if (rport->roles & FC_RPORT_ROLE_FCP_TARGET)
 		if (rport->roles & FC_RPORT_ROLE_FCP_TARGET)
 			printk(KERN_ERR "Cannot find remote node"
 			printk(KERN_ERR "Cannot find remote node"
 			" to terminate I/O Data x%x\n",
 			" to terminate I/O Data x%x\n",
@@ -114,7 +114,7 @@ lpfc_dev_loss_tmo_callbk(struct fc_rport *rport)
 
 
 	rdata = rport->dd_data;
 	rdata = rport->dd_data;
 	ndlp = rdata->pnode;
 	ndlp = rdata->pnode;
-	if (!ndlp)
+	if (!ndlp || !NLP_CHK_NODE_ACT(ndlp))
 		return;
 		return;
 
 
 	vport = ndlp->vport;
 	vport = ndlp->vport;
@@ -243,8 +243,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
 	if (warn_on) {
 	if (warn_on) {
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_DISCOVERY,
 				 "0203 Devloss timeout on "
 				 "0203 Devloss timeout on "
-				 "WWPN %x:%x:%x:%x:%x:%x:%x:%x "
-				 "NPort x%x Data: x%x x%x x%x\n",
+				 "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
+				 "NPort x%06x Data: x%x x%x x%x\n",
 				 *name, *(name+1), *(name+2), *(name+3),
 				 *name, *(name+1), *(name+2), *(name+3),
 				 *(name+4), *(name+5), *(name+6), *(name+7),
 				 *(name+4), *(name+5), *(name+6), *(name+7),
 				 ndlp->nlp_DID, ndlp->nlp_flag,
 				 ndlp->nlp_DID, ndlp->nlp_flag,
@@ -252,8 +252,8 @@ lpfc_dev_loss_tmo_handler(struct lpfc_nodelist *ndlp)
 	} else {
 	} else {
 		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
 		lpfc_printf_vlog(vport, KERN_INFO, LOG_DISCOVERY,
 				 "0204 Devloss timeout on "
 				 "0204 Devloss timeout on "
-				 "WWPN %x:%x:%x:%x:%x:%x:%x:%x "
-				 "NPort x%x Data: x%x x%x x%x\n",
+				 "WWPN %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x "
+				 "NPort x%06x Data: x%x x%x x%x\n",
 				 *name, *(name+1), *(name+2), *(name+3),
 				 *name, *(name+1), *(name+2), *(name+3),
 				 *(name+4), *(name+5), *(name+6), *(name+7),
 				 *(name+4), *(name+5), *(name+6), *(name+7),
 				 ndlp->nlp_DID, ndlp->nlp_flag,
 				 ndlp->nlp_DID, ndlp->nlp_flag,
@@ -399,7 +399,10 @@ lpfc_work_done(struct lpfc_hba *phba)
 				vport = vports[i];
 				vport = vports[i];
 			if (vport == NULL)
 			if (vport == NULL)
 				break;
 				break;
+			spin_lock_irq(&vport->work_port_lock);
 			work_port_events = vport->work_port_events;
 			work_port_events = vport->work_port_events;
+			vport->work_port_events &= ~work_port_events;
+			spin_unlock_irq(&vport->work_port_lock);
 			if (work_port_events & WORKER_DISC_TMO)
 			if (work_port_events & WORKER_DISC_TMO)
 				lpfc_disc_timeout_handler(vport);
 				lpfc_disc_timeout_handler(vport);
 			if (work_port_events & WORKER_ELS_TMO)
 			if (work_port_events & WORKER_ELS_TMO)
@@ -416,9 +419,6 @@ lpfc_work_done(struct lpfc_hba *phba)
 				lpfc_ramp_down_queue_handler(phba);
 				lpfc_ramp_down_queue_handler(phba);
 			if (work_port_events & WORKER_RAMP_UP_QUEUE)
 			if (work_port_events & WORKER_RAMP_UP_QUEUE)
 				lpfc_ramp_up_queue_handler(phba);
 				lpfc_ramp_up_queue_handler(phba);
-			spin_lock_irq(&vport->work_port_lock);
-			vport->work_port_events &= ~work_port_events;
-			spin_unlock_irq(&vport->work_port_lock);
 		}
 		}
 	lpfc_destroy_vport_work_array(phba, vports);
 	lpfc_destroy_vport_work_array(phba, vports);
 
 
@@ -430,10 +430,10 @@ lpfc_work_done(struct lpfc_hba *phba)
 		if (pring->flag & LPFC_STOP_IOCB_EVENT) {
 		if (pring->flag & LPFC_STOP_IOCB_EVENT) {
 			pring->flag |= LPFC_DEFERRED_RING_EVENT;
 			pring->flag |= LPFC_DEFERRED_RING_EVENT;
 		} else {
 		} else {
+			pring->flag &= ~LPFC_DEFERRED_RING_EVENT;
 			lpfc_sli_handle_slow_ring_event(phba, pring,
 			lpfc_sli_handle_slow_ring_event(phba, pring,
 							(status &
 							(status &
 							 HA_RXMASK));
 							 HA_RXMASK));
-			pring->flag &= ~LPFC_DEFERRED_RING_EVENT;
 		}
 		}
 		/*
 		/*
 		 * Turn on Ring interrupts
 		 * Turn on Ring interrupts
@@ -519,7 +519,9 @@ lpfc_do_work(void *p)
 			schedule();
 			schedule();
 		}
 		}
 	}
 	}
+	spin_lock_irq(&phba->hbalock);
 	phba->work_wait = NULL;
 	phba->work_wait = NULL;
+	spin_unlock_irq(&phba->hbalock);
 	return 0;
 	return 0;
 }
 }
 
 
@@ -809,11 +811,9 @@ out:
 	mempool_free(pmb, phba->mbox_mem_pool);
 	mempool_free(pmb, phba->mbox_mem_pool);
 
 
 	spin_lock_irq(shost->host_lock);
 	spin_lock_irq(shost->host_lock);
-	vport->fc_flag &= ~(FC_ABORT_DISCOVERY | FC_ESTABLISH_LINK);
+	vport->fc_flag &= ~FC_ABORT_DISCOVERY;
 	spin_unlock_irq(shost->host_lock);
 	spin_unlock_irq(shost->host_lock);
 
 
-	del_timer_sync(&phba->fc_estabtmo);
-
 	lpfc_can_disctmo(vport);
 	lpfc_can_disctmo(vport);
 
 
 	/* turn on Link Attention interrupts */
 	/* turn on Link Attention interrupts */
@@ -1340,10 +1340,14 @@ lpfc_mbx_cmpl_fabric_reg_login(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmb)
 			    i++) {
 			    i++) {
 				if (vports[i]->port_type == LPFC_PHYSICAL_PORT)
 				if (vports[i]->port_type == LPFC_PHYSICAL_PORT)
 					continue;
 					continue;
+				if (phba->fc_topology == TOPOLOGY_LOOP) {
+					lpfc_vport_set_state(vports[i],
+							FC_VPORT_LINKDOWN);
+					continue;
+				}
 				if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
 				if (phba->link_flag & LS_NPIV_FAB_SUPPORTED)
 					lpfc_initial_fdisc(vports[i]);
 					lpfc_initial_fdisc(vports[i]);
-				else if (phba->sli3_options &
-						LPFC_SLI3_NPIV_ENABLED) {
+				else {
 					lpfc_vport_set_state(vports[i],
 					lpfc_vport_set_state(vports[i],
 						FC_VPORT_NO_FABRIC_SUPP);
 						FC_VPORT_NO_FABRIC_SUPP);
 					lpfc_printf_vlog(vport, KERN_ERR,
 					lpfc_printf_vlog(vport, KERN_ERR,
@@ -2190,10 +2194,6 @@ lpfc_matchdid(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 	if (did == Bcast_DID)
 	if (did == Bcast_DID)
 		return 0;
 		return 0;
 
 
-	if (ndlp->nlp_DID == 0) {
-		return 0;
-	}
-
 	/* First check for Direct match */
 	/* First check for Direct match */
 	if (ndlp->nlp_DID == did)
 	if (ndlp->nlp_DID == did)
 		return 1;
 		return 1;
@@ -2301,7 +2301,8 @@ lpfc_setup_disc_node(struct lpfc_vport *vport, uint32_t did)
 		return ndlp;
 		return ndlp;
 	}
 	}
 
 
-	if (vport->fc_flag & FC_RSCN_MODE) {
+	if ((vport->fc_flag & FC_RSCN_MODE) &&
+	    !(vport->fc_flag & FC_NDISC_ACTIVE)) {
 		if (lpfc_rscn_payload_check(vport, did)) {
 		if (lpfc_rscn_payload_check(vport, did)) {
 			/* If we've already recieved a PLOGI from this NPort
 			/* If we've already recieved a PLOGI from this NPort
 			 * we don't need to try to discover it again.
 			 * we don't need to try to discover it again.
@@ -2947,24 +2948,6 @@ __lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param)
 	return NULL;
 	return NULL;
 }
 }
 
 
-#if 0
-/*
- * Search node lists for a remote port matching filter criteria
- * Caller needs to hold host_lock before calling this routine.
- */
-struct lpfc_nodelist *
-lpfc_find_node(struct lpfc_vport *vport, node_filter filter, void *param)
-{
-	struct Scsi_Host     *shost = lpfc_shost_from_vport(vport);
-	struct lpfc_nodelist *ndlp;
-
-	spin_lock_irq(shost->host_lock);
-	ndlp = __lpfc_find_node(vport, filter, param);
-	spin_unlock_irq(shost->host_lock);
-	return ndlp;
-}
-#endif  /*  0  */
-
 /*
 /*
  * This routine looks up the ndlp lists for the given RPI. If rpi found it
  * This routine looks up the ndlp lists for the given RPI. If rpi found it
  * returns the node list element pointer else return NULL.
  * returns the node list element pointer else return NULL.
@@ -2975,20 +2958,6 @@ __lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi)
 	return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi);
 	return __lpfc_find_node(vport, lpfc_filter_by_rpi, &rpi);
 }
 }
 
 
-#if 0
-struct lpfc_nodelist *
-lpfc_findnode_rpi(struct lpfc_vport *vport, uint16_t rpi)
-{
-	struct Scsi_Host *shost = lpfc_shost_from_vport(vport);
-	struct lpfc_nodelist *ndlp;
-
-	spin_lock_irq(shost->host_lock);
-	ndlp = __lpfc_findnode_rpi(vport, rpi);
-	spin_unlock_irq(shost->host_lock);
-	return ndlp;
-}
-#endif  /*  0  */
-
 /*
 /*
  * This routine looks up the ndlp lists for the given WWPN. If WWPN found it
  * This routine looks up the ndlp lists for the given WWPN. If WWPN found it
  * returns the node element list pointer else return NULL.
  * returns the node element list pointer else return NULL.

+ 43 - 55
drivers/scsi/lpfc/lpfc_init.c

@@ -559,8 +559,10 @@ lpfc_hb_timeout(unsigned long ptr)
 		phba->pport->work_port_events |= WORKER_HB_TMO;
 		phba->pport->work_port_events |= WORKER_HB_TMO;
 	spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag);
 	spin_unlock_irqrestore(&phba->pport->work_port_lock, iflag);
 
 
+	spin_lock_irqsave(&phba->hbalock, iflag);
 	if (phba->work_wait)
 	if (phba->work_wait)
 		wake_up(phba->work_wait);
 		wake_up(phba->work_wait);
+	spin_unlock_irqrestore(&phba->hbalock, iflag);
 	return;
 	return;
 }
 }
 
 
@@ -714,12 +716,10 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
 	struct lpfc_vport *vport = phba->pport;
 	struct lpfc_vport *vport = phba->pport;
 	struct lpfc_sli   *psli = &phba->sli;
 	struct lpfc_sli   *psli = &phba->sli;
 	struct lpfc_sli_ring  *pring;
 	struct lpfc_sli_ring  *pring;
-	struct lpfc_vport **vports;
 	uint32_t event_data;
 	uint32_t event_data;
 	unsigned long temperature;
 	unsigned long temperature;
 	struct temp_event temp_event_data;
 	struct temp_event temp_event_data;
 	struct Scsi_Host  *shost;
 	struct Scsi_Host  *shost;
-	int i;
 
 
 	/* If the pci channel is offline, ignore possible errors,
 	/* If the pci channel is offline, ignore possible errors,
 	 * since we cannot communicate with the pci card anyway. */
 	 * since we cannot communicate with the pci card anyway. */
@@ -729,25 +729,14 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
 	if (!phba->cfg_enable_hba_reset)
 	if (!phba->cfg_enable_hba_reset)
 		return;
 		return;
 
 
-	if (phba->work_hs & HS_FFER6 ||
-	    phba->work_hs & HS_FFER5) {
+	if (phba->work_hs & HS_FFER6) {
 		/* Re-establishing Link */
 		/* Re-establishing Link */
 		lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
 		lpfc_printf_log(phba, KERN_INFO, LOG_LINK_EVENT,
 				"1301 Re-establishing Link "
 				"1301 Re-establishing Link "
 				"Data: x%x x%x x%x\n",
 				"Data: x%x x%x x%x\n",
 				phba->work_hs,
 				phba->work_hs,
 				phba->work_status[0], phba->work_status[1]);
 				phba->work_status[0], phba->work_status[1]);
-		vports = lpfc_create_vport_work_array(phba);
-		if (vports != NULL)
-			for(i = 0;
-			    i <= phba->max_vpi && vports[i] != NULL;
-			    i++){
-				shost = lpfc_shost_from_vport(vports[i]);
-				spin_lock_irq(shost->host_lock);
-				vports[i]->fc_flag |= FC_ESTABLISH_LINK;
-				spin_unlock_irq(shost->host_lock);
-			}
-		lpfc_destroy_vport_work_array(phba, vports);
+
 		spin_lock_irq(&phba->hbalock);
 		spin_lock_irq(&phba->hbalock);
 		psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
 		psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
 		spin_unlock_irq(&phba->hbalock);
 		spin_unlock_irq(&phba->hbalock);
@@ -761,7 +750,6 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
 		pring = &psli->ring[psli->fcp_ring];
 		pring = &psli->ring[psli->fcp_ring];
 		lpfc_sli_abort_iocb_ring(phba, pring);
 		lpfc_sli_abort_iocb_ring(phba, pring);
 
 
-
 		/*
 		/*
 		 * There was a firmware error.  Take the hba offline and then
 		 * There was a firmware error.  Take the hba offline and then
 		 * attempt to restart it.
 		 * attempt to restart it.
@@ -770,7 +758,6 @@ lpfc_handle_eratt(struct lpfc_hba *phba)
 		lpfc_offline(phba);
 		lpfc_offline(phba);
 		lpfc_sli_brdrestart(phba);
 		lpfc_sli_brdrestart(phba);
 		if (lpfc_online(phba) == 0) {	/* Initialize the HBA */
 		if (lpfc_online(phba) == 0) {	/* Initialize the HBA */
-			mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60);
 			lpfc_unblock_mgmt_io(phba);
 			lpfc_unblock_mgmt_io(phba);
 			return;
 			return;
 		}
 		}
@@ -1454,6 +1441,13 @@ lpfc_cleanup(struct lpfc_vport *vport)
 			NLP_SET_FREE_REQ(ndlp);
 			NLP_SET_FREE_REQ(ndlp);
 		spin_unlock_irq(&phba->ndlp_lock);
 		spin_unlock_irq(&phba->ndlp_lock);
 
 
+		if (vport->port_type != LPFC_PHYSICAL_PORT &&
+		    ndlp->nlp_DID == Fabric_DID) {
+			/* Just free up ndlp with Fabric_DID for vports */
+			lpfc_nlp_put(ndlp);
+			continue;
+		}
+
 		if (ndlp->nlp_type & NLP_FABRIC)
 		if (ndlp->nlp_type & NLP_FABRIC)
 			lpfc_disc_state_machine(vport, ndlp, NULL,
 			lpfc_disc_state_machine(vport, ndlp, NULL,
 					NLP_EVT_DEVICE_RECOVERY);
 					NLP_EVT_DEVICE_RECOVERY);
@@ -1491,31 +1485,6 @@ lpfc_cleanup(struct lpfc_vport *vport)
 	return;
 	return;
 }
 }
 
 
-static void
-lpfc_establish_link_tmo(unsigned long ptr)
-{
-	struct lpfc_hba   *phba = (struct lpfc_hba *) ptr;
-	struct lpfc_vport **vports;
-	unsigned long iflag;
-	int i;
-
-	/* Re-establishing Link, timer expired */
-	lpfc_printf_log(phba, KERN_ERR, LOG_LINK_EVENT,
-			"1300 Re-establishing Link, timer expired "
-			"Data: x%x x%x\n",
-			phba->pport->fc_flag, phba->pport->port_state);
-	vports = lpfc_create_vport_work_array(phba);
-	if (vports != NULL)
-		for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
-			struct Scsi_Host *shost;
-			shost = lpfc_shost_from_vport(vports[i]);
-			spin_lock_irqsave(shost->host_lock, iflag);
-			vports[i]->fc_flag &= ~FC_ESTABLISH_LINK;
-			spin_unlock_irqrestore(shost->host_lock, iflag);
-		}
-	lpfc_destroy_vport_work_array(phba, vports);
-}
-
 void
 void
 lpfc_stop_vport_timers(struct lpfc_vport *vport)
 lpfc_stop_vport_timers(struct lpfc_vport *vport)
 {
 {
@@ -1529,7 +1498,6 @@ static void
 lpfc_stop_phba_timers(struct lpfc_hba *phba)
 lpfc_stop_phba_timers(struct lpfc_hba *phba)
 {
 {
 	del_timer_sync(&phba->fcp_poll_timer);
 	del_timer_sync(&phba->fcp_poll_timer);
-	del_timer_sync(&phba->fc_estabtmo);
 	lpfc_stop_vport_timers(phba->pport);
 	lpfc_stop_vport_timers(phba->pport);
 	del_timer_sync(&phba->sli.mbox_tmo);
 	del_timer_sync(&phba->sli.mbox_tmo);
 	del_timer_sync(&phba->fabric_block_timer);
 	del_timer_sync(&phba->fabric_block_timer);
@@ -2005,10 +1973,6 @@ lpfc_pci_probe_one(struct pci_dev *pdev, const struct pci_device_id *pid)
 	phba->max_vpi = LPFC_MAX_VPI;
 	phba->max_vpi = LPFC_MAX_VPI;
 
 
 	/* Initialize timers used by driver */
 	/* Initialize timers used by driver */
-	init_timer(&phba->fc_estabtmo);
-	phba->fc_estabtmo.function = lpfc_establish_link_tmo;
-	phba->fc_estabtmo.data = (unsigned long)phba;
-
 	init_timer(&phba->hb_tmofunc);
 	init_timer(&phba->hb_tmofunc);
 	phba->hb_tmofunc.function = lpfc_hb_timeout;
 	phba->hb_tmofunc.function = lpfc_hb_timeout;
 	phba->hb_tmofunc.data = (unsigned long)phba;
 	phba->hb_tmofunc.data = (unsigned long)phba;
@@ -2406,6 +2370,7 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
 	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
 	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
 	struct lpfc_sli *psli = &phba->sli;
 	struct lpfc_sli *psli = &phba->sli;
+	int error, retval;
 
 
 	dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n");
 	dev_printk(KERN_INFO, &pdev->dev, "recovering from a slot reset.\n");
 	if (pci_enable_device_mem(pdev)) {
 	if (pci_enable_device_mem(pdev)) {
@@ -2416,15 +2381,40 @@ static pci_ers_result_t lpfc_io_slot_reset(struct pci_dev *pdev)
 
 
 	pci_set_master(pdev);
 	pci_set_master(pdev);
 
 
-	/* Re-establishing Link */
-	spin_lock_irq(shost->host_lock);
-	phba->pport->fc_flag |= FC_ESTABLISH_LINK;
-	spin_unlock_irq(shost->host_lock);
-
 	spin_lock_irq(&phba->hbalock);
 	spin_lock_irq(&phba->hbalock);
 	psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
 	psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
 	spin_unlock_irq(&phba->hbalock);
 	spin_unlock_irq(&phba->hbalock);
 
 
+	/* Enable configured interrupt method */
+	phba->intr_type = NONE;
+	if (phba->cfg_use_msi == 2) {
+		error = lpfc_enable_msix(phba);
+		if (!error)
+			phba->intr_type = MSIX;
+	}
+
+	/* Fallback to MSI if MSI-X initialization failed */
+	if (phba->cfg_use_msi >= 1 && phba->intr_type == NONE) {
+		retval = pci_enable_msi(phba->pcidev);
+		if (!retval)
+			phba->intr_type = MSI;
+		else
+			lpfc_printf_log(phba, KERN_INFO, LOG_INIT,
+					"0470 Enable MSI failed, continuing "
+					"with IRQ\n");
+	}
+
+	/* MSI-X is the only case the doesn't need to call request_irq */
+	if (phba->intr_type != MSIX) {
+		retval = request_irq(phba->pcidev->irq, lpfc_intr_handler,
+				     IRQF_SHARED, LPFC_DRIVER_NAME, phba);
+		if (retval) {
+			lpfc_printf_log(phba, KERN_ERR, LOG_INIT,
+					"0471 Enable interrupt handler "
+					"failed\n");
+		} else if (phba->intr_type != MSI)
+			phba->intr_type = INTx;
+	}
 
 
 	/* Take device offline; this will perform cleanup */
 	/* Take device offline; this will perform cleanup */
 	lpfc_offline(phba);
 	lpfc_offline(phba);
@@ -2445,9 +2435,7 @@ static void lpfc_io_resume(struct pci_dev *pdev)
 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
 	struct Scsi_Host *shost = pci_get_drvdata(pdev);
 	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
 	struct lpfc_hba *phba = ((struct lpfc_vport *)shost->hostdata)->phba;
 
 
-	if (lpfc_online(phba) == 0) {
-		mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60);
-	}
+	lpfc_online(phba);
 }
 }
 
 
 static struct pci_device_id lpfc_id_table[] = {
 static struct pci_device_id lpfc_id_table[] = {

+ 23 - 17
drivers/scsi/lpfc/lpfc_nportdisc.c

@@ -451,7 +451,7 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 			spin_unlock_irq(shost->host_lock);
 			spin_unlock_irq(shost->host_lock);
 
 
 			if ((ndlp->nlp_flag & NLP_ADISC_SND) &&
 			if ((ndlp->nlp_flag & NLP_ADISC_SND) &&
-				(vport->num_disc_nodes)) {
+			    (vport->num_disc_nodes)) {
 				/* Check to see if there are more
 				/* Check to see if there are more
 				 * ADISCs to be sent
 				 * ADISCs to be sent
 				 */
 				 */
@@ -461,20 +461,6 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 					(vport->fc_npr_cnt))
 					(vport->fc_npr_cnt))
 					lpfc_els_disc_plogi(vport);
 					lpfc_els_disc_plogi(vport);
 
 
-				if (vport->num_disc_nodes == 0) {
-					spin_lock_irq(shost->host_lock);
-					vport->fc_flag &= ~FC_NDISC_ACTIVE;
-					spin_unlock_irq(shost->host_lock);
-					lpfc_can_disctmo(vport);
-					lpfc_end_rscn(vport);
-				}
-			}
-			else if (vport->num_disc_nodes) {
-				/* Check to see if there are more
-				 * PLOGIs to be sent
-				 */
-				lpfc_more_plogi(vport);
-
 				if (vport->num_disc_nodes == 0) {
 				if (vport->num_disc_nodes == 0) {
 					spin_lock_irq(shost->host_lock);
 					spin_lock_irq(shost->host_lock);
 					vport->fc_flag &= ~FC_NDISC_ACTIVE;
 					vport->fc_flag &= ~FC_NDISC_ACTIVE;
@@ -484,6 +470,23 @@ lpfc_rcv_plogi(struct lpfc_vport *vport, struct lpfc_nodelist *ndlp,
 				}
 				}
 			}
 			}
 		}
 		}
+	} else if ((ndlp->nlp_state == NLP_STE_PLOGI_ISSUE) &&
+		   (ndlp->nlp_flag & NLP_NPR_2B_DISC) &&
+		   (vport->num_disc_nodes)) {
+		spin_lock_irq(shost->host_lock);
+		ndlp->nlp_flag &= ~NLP_NPR_2B_DISC;
+		spin_unlock_irq(shost->host_lock);
+		/* Check to see if there are more
+		 * PLOGIs to be sent
+		 */
+		lpfc_more_plogi(vport);
+		if (vport->num_disc_nodes == 0) {
+			spin_lock_irq(shost->host_lock);
+			vport->fc_flag &= ~FC_NDISC_ACTIVE;
+			spin_unlock_irq(shost->host_lock);
+			lpfc_can_disctmo(vport);
+			lpfc_end_rscn(vport);
+		}
 	}
 	}
 
 
 	lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox);
 	lpfc_els_rsp_acc(vport, ELS_CMD_PLOGI, cmdiocb, ndlp, mbox);
@@ -869,8 +872,11 @@ lpfc_cmpl_plogi_plogi_issue(struct lpfc_vport *vport,
 
 
 	lp = (uint32_t *) prsp->virt;
 	lp = (uint32_t *) prsp->virt;
 	sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
 	sp = (struct serv_parm *) ((uint8_t *) lp + sizeof (uint32_t));
-	if (wwn_to_u64(sp->portName.u.wwn) == 0 ||
-	    wwn_to_u64(sp->nodeName.u.wwn) == 0) {
+
+	/* Some switches have FDMI servers returning 0 for WWN */
+	if ((ndlp->nlp_DID != FDMI_DID) &&
+		(wwn_to_u64(sp->portName.u.wwn) == 0 ||
+		wwn_to_u64(sp->nodeName.u.wwn) == 0)) {
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
 		lpfc_printf_vlog(vport, KERN_ERR, LOG_ELS,
 				 "0142 PLOGI RSP: Invalid WWN.\n");
 				 "0142 PLOGI RSP: Invalid WWN.\n");
 		goto out;
 		goto out;

+ 21 - 13
drivers/scsi/lpfc/lpfc_scsi.c

@@ -169,6 +169,9 @@ lpfc_ramp_up_queue_handler(struct lpfc_hba *phba)
 		for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
 		for(i = 0; i <= phba->max_vpi && vports[i] != NULL; i++) {
 			shost = lpfc_shost_from_vport(vports[i]);
 			shost = lpfc_shost_from_vport(vports[i]);
 			shost_for_each_device(sdev, shost) {
 			shost_for_each_device(sdev, shost) {
+				if (vports[i]->cfg_lun_queue_depth <=
+				    sdev->queue_depth)
+					continue;
 				if (sdev->ordered_tags)
 				if (sdev->ordered_tags)
 					scsi_adjust_queue_depth(sdev,
 					scsi_adjust_queue_depth(sdev,
 							MSG_ORDERED_TAG,
 							MSG_ORDERED_TAG,
@@ -578,14 +581,14 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
 			    lpfc_cmd->result == IOERR_NO_RESOURCES ||
 			    lpfc_cmd->result == IOERR_NO_RESOURCES ||
 			    lpfc_cmd->result == RJT_LOGIN_REQUIRED) {
 			    lpfc_cmd->result == RJT_LOGIN_REQUIRED) {
 				cmd->result = ScsiResult(DID_REQUEUE, 0);
 				cmd->result = ScsiResult(DID_REQUEUE, 0);
-			break;
-		} /* else: fall through */
+				break;
+			} /* else: fall through */
 		default:
 		default:
 			cmd->result = ScsiResult(DID_ERROR, 0);
 			cmd->result = ScsiResult(DID_ERROR, 0);
 			break;
 			break;
 		}
 		}
 
 
-		if ((pnode == NULL )
+		if (!pnode || !NLP_CHK_NODE_ACT(pnode)
 		    || (pnode->nlp_state != NLP_STE_MAPPED_NODE))
 		    || (pnode->nlp_state != NLP_STE_MAPPED_NODE))
 			cmd->result = ScsiResult(DID_BUS_BUSY, SAM_STAT_BUSY);
 			cmd->result = ScsiResult(DID_BUS_BUSY, SAM_STAT_BUSY);
 	} else {
 	} else {
@@ -606,6 +609,9 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
 	result = cmd->result;
 	result = cmd->result;
 	sdev = cmd->device;
 	sdev = cmd->device;
 	lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
 	lpfc_scsi_unprep_dma_buf(phba, lpfc_cmd);
+	spin_lock_irqsave(sdev->host->host_lock, flags);
+	lpfc_cmd->pCmd = NULL;	/* This must be done before scsi_done */
+	spin_unlock_irqrestore(sdev->host->host_lock, flags);
 	cmd->scsi_done(cmd);
 	cmd->scsi_done(cmd);
 
 
 	if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
 	if (phba->cfg_poll & ENABLE_FCP_RING_POLLING) {
@@ -614,7 +620,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
 		 * wake up the thread.
 		 * wake up the thread.
 		 */
 		 */
 		spin_lock_irqsave(sdev->host->host_lock, flags);
 		spin_lock_irqsave(sdev->host->host_lock, flags);
-		lpfc_cmd->pCmd = NULL;
 		if (lpfc_cmd->waitq)
 		if (lpfc_cmd->waitq)
 			wake_up(lpfc_cmd->waitq);
 			wake_up(lpfc_cmd->waitq);
 		spin_unlock_irqrestore(sdev->host->host_lock, flags);
 		spin_unlock_irqrestore(sdev->host->host_lock, flags);
@@ -626,7 +631,7 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
 	if (!result)
 	if (!result)
 		lpfc_rampup_queue_depth(vport, sdev);
 		lpfc_rampup_queue_depth(vport, sdev);
 
 
-	if (!result && pnode != NULL &&
+	if (!result && pnode && NLP_CHK_NODE_ACT(pnode) &&
 	   ((jiffies - pnode->last_ramp_up_time) >
 	   ((jiffies - pnode->last_ramp_up_time) >
 		LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
 		LPFC_Q_RAMP_UP_INTERVAL * HZ) &&
 	   ((jiffies - pnode->last_q_full_time) >
 	   ((jiffies - pnode->last_q_full_time) >
@@ -654,7 +659,8 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
 	 * Check for queue full.  If the lun is reporting queue full, then
 	 * Check for queue full.  If the lun is reporting queue full, then
 	 * back off the lun queue depth to prevent target overloads.
 	 * back off the lun queue depth to prevent target overloads.
 	 */
 	 */
-	if (result == SAM_STAT_TASK_SET_FULL && pnode != NULL) {
+	if (result == SAM_STAT_TASK_SET_FULL && pnode &&
+	    NLP_CHK_NODE_ACT(pnode)) {
 		pnode->last_q_full_time = jiffies;
 		pnode->last_q_full_time = jiffies;
 
 
 		shost_for_each_device(tmp_sdev, sdev->host) {
 		shost_for_each_device(tmp_sdev, sdev->host) {
@@ -684,7 +690,6 @@ lpfc_scsi_cmd_iocb_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *pIocbIn,
 	 * wake up the thread.
 	 * wake up the thread.
 	 */
 	 */
 	spin_lock_irqsave(sdev->host->host_lock, flags);
 	spin_lock_irqsave(sdev->host->host_lock, flags);
-	lpfc_cmd->pCmd = NULL;
 	if (lpfc_cmd->waitq)
 	if (lpfc_cmd->waitq)
 		wake_up(lpfc_cmd->waitq);
 		wake_up(lpfc_cmd->waitq);
 	spin_unlock_irqrestore(sdev->host->host_lock, flags);
 	spin_unlock_irqrestore(sdev->host->host_lock, flags);
@@ -704,6 +709,9 @@ lpfc_scsi_prep_cmnd(struct lpfc_vport *vport, struct lpfc_scsi_buf *lpfc_cmd,
 	int datadir = scsi_cmnd->sc_data_direction;
 	int datadir = scsi_cmnd->sc_data_direction;
 	char tag[2];
 	char tag[2];
 
 
+	if (!pnode || !NLP_CHK_NODE_ACT(pnode))
+		return;
+
 	lpfc_cmd->fcp_rsp->rspSnsLen = 0;
 	lpfc_cmd->fcp_rsp->rspSnsLen = 0;
 	/* clear task management bits */
 	/* clear task management bits */
 	lpfc_cmd->fcp_cmnd->fcpCntl2 = 0;
 	lpfc_cmd->fcp_cmnd->fcpCntl2 = 0;
@@ -785,9 +793,9 @@ lpfc_scsi_prep_task_mgmt_cmd(struct lpfc_vport *vport,
 	struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
 	struct lpfc_rport_data *rdata = lpfc_cmd->rdata;
 	struct lpfc_nodelist *ndlp = rdata->pnode;
 	struct lpfc_nodelist *ndlp = rdata->pnode;
 
 
-	if ((ndlp == NULL) || (ndlp->nlp_state != NLP_STE_MAPPED_NODE)) {
+	if (!ndlp || !NLP_CHK_NODE_ACT(ndlp) ||
+	    ndlp->nlp_state != NLP_STE_MAPPED_NODE)
 		return 0;
 		return 0;
-	}
 
 
 	piocbq = &(lpfc_cmd->cur_iocbq);
 	piocbq = &(lpfc_cmd->cur_iocbq);
 	piocbq->vport = vport;
 	piocbq->vport = vport;
@@ -842,7 +850,7 @@ lpfc_scsi_tgt_reset(struct lpfc_scsi_buf *lpfc_cmd, struct lpfc_vport *vport,
 	struct lpfc_iocbq *iocbqrsp;
 	struct lpfc_iocbq *iocbqrsp;
 	int ret;
 	int ret;
 
 
-	if (!rdata->pnode)
+	if (!rdata->pnode || !NLP_CHK_NODE_ACT(rdata->pnode))
 		return FAILED;
 		return FAILED;
 
 
 	lpfc_cmd->rdata = rdata;
 	lpfc_cmd->rdata = rdata;
@@ -959,7 +967,7 @@ lpfc_queuecommand(struct scsi_cmnd *cmnd, void (*done) (struct scsi_cmnd *))
 	 * Catch race where our node has transitioned, but the
 	 * Catch race where our node has transitioned, but the
 	 * transport is still transitioning.
 	 * transport is still transitioning.
 	 */
 	 */
-	if (!ndlp) {
+	if (!ndlp || !NLP_CHK_NODE_ACT(ndlp)) {
 		cmnd->result = ScsiResult(DID_BUS_BUSY, 0);
 		cmnd->result = ScsiResult(DID_BUS_BUSY, 0);
 		goto out_fail_command;
 		goto out_fail_command;
 	}
 	}
@@ -1146,7 +1154,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
 	 * target is rediscovered or devloss timeout expires.
 	 * target is rediscovered or devloss timeout expires.
 	 */
 	 */
 	while (1) {
 	while (1) {
-		if (!pnode)
+		if (!pnode || !NLP_CHK_NODE_ACT(pnode))
 			goto out;
 			goto out;
 
 
 		if (pnode->nlp_state != NLP_STE_MAPPED_NODE) {
 		if (pnode->nlp_state != NLP_STE_MAPPED_NODE) {
@@ -1162,7 +1170,7 @@ lpfc_device_reset_handler(struct scsi_cmnd *cmnd)
 				goto out;
 				goto out;
 			}
 			}
 			pnode = rdata->pnode;
 			pnode = rdata->pnode;
-			if (!pnode)
+			if (!pnode || !NLP_CHK_NODE_ACT(pnode))
 				goto out;
 				goto out;
 		}
 		}
 		if (pnode->nlp_state == NLP_STE_MAPPED_NODE)
 		if (pnode->nlp_state == NLP_STE_MAPPED_NODE)

+ 68 - 44
drivers/scsi/lpfc/lpfc_sli.c

@@ -2648,7 +2648,6 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
 	spin_unlock_irq(&phba->pport->work_port_lock);
 	spin_unlock_irq(&phba->pport->work_port_lock);
 	spin_lock_irq(&phba->hbalock);
 	spin_lock_irq(&phba->hbalock);
 	phba->link_state = LPFC_LINK_UNKNOWN;
 	phba->link_state = LPFC_LINK_UNKNOWN;
-	phba->pport->fc_flag |= FC_ESTABLISH_LINK;
 	psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
 	psli->sli_flag &= ~LPFC_SLI2_ACTIVE;
 	spin_unlock_irq(&phba->hbalock);
 	spin_unlock_irq(&phba->hbalock);
 
 
@@ -2669,8 +2668,7 @@ lpfc_mbox_timeout_handler(struct lpfc_hba *phba)
 	lpfc_offline_prep(phba);
 	lpfc_offline_prep(phba);
 	lpfc_offline(phba);
 	lpfc_offline(phba);
 	lpfc_sli_brdrestart(phba);
 	lpfc_sli_brdrestart(phba);
-	if (lpfc_online(phba) == 0)		/* Initialize the HBA */
-		mod_timer(&phba->fc_estabtmo, jiffies + HZ * 60);
+	lpfc_online(phba);
 	lpfc_unblock_mgmt_io(phba);
 	lpfc_unblock_mgmt_io(phba);
 	return;
 	return;
 }
 }
@@ -2687,28 +2685,41 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
 	unsigned long drvr_flag = 0;
 	unsigned long drvr_flag = 0;
 	volatile uint32_t word0, ldata;
 	volatile uint32_t word0, ldata;
 	void __iomem *to_slim;
 	void __iomem *to_slim;
+	int processing_queue = 0;
+
+	spin_lock_irqsave(&phba->hbalock, drvr_flag);
+	if (!pmbox) {
+		/* processing mbox queue from intr_handler */
+		processing_queue = 1;
+		phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
+		pmbox = lpfc_mbox_get(phba);
+		if (!pmbox) {
+			spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
+			return MBX_SUCCESS;
+		}
+	}
 
 
 	if (pmbox->mbox_cmpl && pmbox->mbox_cmpl != lpfc_sli_def_mbox_cmpl &&
 	if (pmbox->mbox_cmpl && pmbox->mbox_cmpl != lpfc_sli_def_mbox_cmpl &&
 		pmbox->mbox_cmpl != lpfc_sli_wake_mbox_wait) {
 		pmbox->mbox_cmpl != lpfc_sli_wake_mbox_wait) {
 		if(!pmbox->vport) {
 		if(!pmbox->vport) {
+			spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
 			lpfc_printf_log(phba, KERN_ERR,
 			lpfc_printf_log(phba, KERN_ERR,
 					LOG_MBOX | LOG_VPORT,
 					LOG_MBOX | LOG_VPORT,
 					"1806 Mbox x%x failed. No vport\n",
 					"1806 Mbox x%x failed. No vport\n",
 					pmbox->mb.mbxCommand);
 					pmbox->mb.mbxCommand);
 			dump_stack();
 			dump_stack();
-			return MBX_NOT_FINISHED;
+			goto out_not_finished;
 		}
 		}
 	}
 	}
 
 
-
 	/* If the PCI channel is in offline state, do not post mbox. */
 	/* If the PCI channel is in offline state, do not post mbox. */
-	if (unlikely(pci_channel_offline(phba->pcidev)))
-		return MBX_NOT_FINISHED;
+	if (unlikely(pci_channel_offline(phba->pcidev))) {
+		spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
+		goto out_not_finished;
+	}
 
 
-	spin_lock_irqsave(&phba->hbalock, drvr_flag);
 	psli = &phba->sli;
 	psli = &phba->sli;
 
 
-
 	mb = &pmbox->mb;
 	mb = &pmbox->mb;
 	status = MBX_SUCCESS;
 	status = MBX_SUCCESS;
 
 
@@ -2717,14 +2728,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
 
 
 		/* Mbox command <mbxCommand> cannot issue */
 		/* Mbox command <mbxCommand> cannot issue */
 		LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
 		LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
-		return MBX_NOT_FINISHED;
+		goto out_not_finished;
 	}
 	}
 
 
 	if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT &&
 	if (mb->mbxCommand != MBX_KILL_BOARD && flag & MBX_NOWAIT &&
 	    !(readl(phba->HCregaddr) & HC_MBINT_ENA)) {
 	    !(readl(phba->HCregaddr) & HC_MBINT_ENA)) {
 		spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
 		spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
 		LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
 		LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
-		return MBX_NOT_FINISHED;
+		goto out_not_finished;
 	}
 	}
 
 
 	if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) {
 	if (psli->sli_flag & LPFC_SLI_MBOX_ACTIVE) {
@@ -2738,14 +2749,14 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
 
 
 			/* Mbox command <mbxCommand> cannot issue */
 			/* Mbox command <mbxCommand> cannot issue */
 			LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
 			LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
-			return MBX_NOT_FINISHED;
+			goto out_not_finished;
 		}
 		}
 
 
 		if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) {
 		if (!(psli->sli_flag & LPFC_SLI2_ACTIVE)) {
 			spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
 			spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
 			/* Mbox command <mbxCommand> cannot issue */
 			/* Mbox command <mbxCommand> cannot issue */
 			LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
 			LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
-			return MBX_NOT_FINISHED;
+			goto out_not_finished;
 		}
 		}
 
 
 		/* Another mailbox command is still being processed, queue this
 		/* Another mailbox command is still being processed, queue this
@@ -2792,7 +2803,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
 			spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
 			spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
 			/* Mbox command <mbxCommand> cannot issue */
 			/* Mbox command <mbxCommand> cannot issue */
 			LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
 			LOG_MBOX_CANNOT_ISSUE_DATA(phba, pmbox, psli, flag);
-			return MBX_NOT_FINISHED;
+			goto out_not_finished;
 		}
 		}
 		/* timeout active mbox command */
 		/* timeout active mbox command */
 		mod_timer(&psli->mbox_tmo, (jiffies +
 		mod_timer(&psli->mbox_tmo, (jiffies +
@@ -2900,7 +2911,7 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
 				psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
 				psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
 				spin_unlock_irqrestore(&phba->hbalock,
 				spin_unlock_irqrestore(&phba->hbalock,
 						       drvr_flag);
 						       drvr_flag);
-				return MBX_NOT_FINISHED;
+				goto out_not_finished;
 			}
 			}
 
 
 			/* Check if we took a mbox interrupt while we were
 			/* Check if we took a mbox interrupt while we were
@@ -2967,6 +2978,13 @@ lpfc_sli_issue_mbox(struct lpfc_hba *phba, LPFC_MBOXQ_t *pmbox, uint32_t flag)
 
 
 	spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
 	spin_unlock_irqrestore(&phba->hbalock, drvr_flag);
 	return status;
 	return status;
+
+out_not_finished:
+	if (processing_queue) {
+		pmbox->mb.mbxStatus = MBX_NOT_FINISHED;
+		lpfc_mbox_cmpl_put(phba, pmbox);
+	}
+	return MBX_NOT_FINISHED;
 }
 }
 
 
 /*
 /*
@@ -3463,26 +3481,21 @@ lpfc_sli_hba_down(struct lpfc_hba *phba)
 	phba->pport->work_port_events &= ~WORKER_MBOX_TMO;
 	phba->pport->work_port_events &= ~WORKER_MBOX_TMO;
 	spin_unlock(&phba->pport->work_port_lock);
 	spin_unlock(&phba->pport->work_port_lock);
 
 
+	/* Return any pending or completed mbox cmds */
+	list_splice_init(&phba->sli.mboxq, &completions);
 	if (psli->mbox_active) {
 	if (psli->mbox_active) {
 		list_add_tail(&psli->mbox_active->list, &completions);
 		list_add_tail(&psli->mbox_active->list, &completions);
 		psli->mbox_active = NULL;
 		psli->mbox_active = NULL;
 		psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
 		psli->sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
 	}
 	}
-
-	/* Return any pending or completed mbox cmds */
-	list_splice_init(&phba->sli.mboxq, &completions);
 	list_splice_init(&phba->sli.mboxq_cmpl, &completions);
 	list_splice_init(&phba->sli.mboxq_cmpl, &completions);
-	INIT_LIST_HEAD(&psli->mboxq);
-	INIT_LIST_HEAD(&psli->mboxq_cmpl);
-
 	spin_unlock_irqrestore(&phba->hbalock, flags);
 	spin_unlock_irqrestore(&phba->hbalock, flags);
 
 
 	while (!list_empty(&completions)) {
 	while (!list_empty(&completions)) {
 		list_remove_head(&completions, pmb, LPFC_MBOXQ_t, list);
 		list_remove_head(&completions, pmb, LPFC_MBOXQ_t, list);
 		pmb->mb.mbxStatus = MBX_NOT_FINISHED;
 		pmb->mb.mbxStatus = MBX_NOT_FINISHED;
-		if (pmb->mbox_cmpl) {
+		if (pmb->mbox_cmpl)
 			pmb->mbox_cmpl(phba,pmb);
 			pmb->mbox_cmpl(phba,pmb);
-		}
 	}
 	}
 	return 1;
 	return 1;
 }
 }
@@ -3612,6 +3625,15 @@ lpfc_sli_abort_els_cmpl(struct lpfc_hba *phba, struct lpfc_iocbq *cmdiocb,
 				abort_iocb, abort_iotag, abort_context,
 				abort_iocb, abort_iotag, abort_context,
 				irsp->ulpStatus, irsp->un.ulpWord[4]);
 				irsp->ulpStatus, irsp->un.ulpWord[4]);
 
 
+		/*
+		 *  If the iocb is not found in Firmware queue the iocb
+		 *  might have completed already. Do not free it again.
+		 */
+		if (irsp->ulpStatus == IOSTAT_LOCAL_REJECT) {
+			spin_unlock_irq(&phba->hbalock);
+			lpfc_sli_release_iocbq(phba, cmdiocb);
+			return;
+		}
 		/*
 		/*
 		 * make sure we have the right iocbq before taking it
 		 * make sure we have the right iocbq before taking it
 		 * off the txcmplq and try to call completion routine.
 		 * off the txcmplq and try to call completion routine.
@@ -4174,6 +4196,7 @@ lpfc_intr_handler(int irq, void *dev_id)
 			phba->pport->stopped = 1;
 			phba->pport->stopped = 1;
 		}
 		}
 
 
+		spin_lock(&phba->hbalock);
 		if ((work_ha_copy & HA_MBATT) &&
 		if ((work_ha_copy & HA_MBATT) &&
 		    (phba->sli.mbox_active)) {
 		    (phba->sli.mbox_active)) {
 			pmb = phba->sli.mbox_active;
 			pmb = phba->sli.mbox_active;
@@ -4184,6 +4207,7 @@ lpfc_intr_handler(int irq, void *dev_id)
 			/* First check out the status word */
 			/* First check out the status word */
 			lpfc_sli_pcimem_bcopy(mbox, pmbox, sizeof(uint32_t));
 			lpfc_sli_pcimem_bcopy(mbox, pmbox, sizeof(uint32_t));
 			if (pmbox->mbxOwner != OWN_HOST) {
 			if (pmbox->mbxOwner != OWN_HOST) {
+				spin_unlock(&phba->hbalock);
 				/*
 				/*
 				 * Stray Mailbox Interrupt, mbxCommand <cmd>
 				 * Stray Mailbox Interrupt, mbxCommand <cmd>
 				 * mbxStatus <status>
 				 * mbxStatus <status>
@@ -4199,10 +4223,10 @@ lpfc_intr_handler(int irq, void *dev_id)
 				/* clear mailbox attention bit */
 				/* clear mailbox attention bit */
 				work_ha_copy &= ~HA_MBATT;
 				work_ha_copy &= ~HA_MBATT;
 			} else {
 			} else {
+				phba->sli.mbox_active = NULL;
+				spin_unlock(&phba->hbalock);
 				phba->last_completion_time = jiffies;
 				phba->last_completion_time = jiffies;
 				del_timer(&phba->sli.mbox_tmo);
 				del_timer(&phba->sli.mbox_tmo);
-
-				phba->sli.mbox_active = NULL;
 				if (pmb->mbox_cmpl) {
 				if (pmb->mbox_cmpl) {
 					lpfc_sli_pcimem_bcopy(mbox, pmbox,
 					lpfc_sli_pcimem_bcopy(mbox, pmbox,
 							MAILBOX_CMD_SIZE);
 							MAILBOX_CMD_SIZE);
@@ -4237,10 +4261,15 @@ lpfc_intr_handler(int irq, void *dev_id)
 						pmb->context1 = mp;
 						pmb->context1 = mp;
 						pmb->context2 = ndlp;
 						pmb->context2 = ndlp;
 						pmb->vport = vport;
 						pmb->vport = vport;
-						spin_lock(&phba->hbalock);
-						phba->sli.sli_flag &=
-							~LPFC_SLI_MBOX_ACTIVE;
-						spin_unlock(&phba->hbalock);
+						rc = lpfc_sli_issue_mbox(phba,
+								pmb,
+								MBX_NOWAIT);
+						if (rc != MBX_BUSY)
+							lpfc_printf_log(phba,
+							KERN_ERR,
+							LOG_MBOX | LOG_SLI,
+							"0306 rc should have"
+							"been MBX_BUSY");
 						goto send_current_mbox;
 						goto send_current_mbox;
 					}
 					}
 				}
 				}
@@ -4250,25 +4279,20 @@ lpfc_intr_handler(int irq, void *dev_id)
 				spin_unlock(&phba->pport->work_port_lock);
 				spin_unlock(&phba->pport->work_port_lock);
 				lpfc_mbox_cmpl_put(phba, pmb);
 				lpfc_mbox_cmpl_put(phba, pmb);
 			}
 			}
-		}
+		} else
+			spin_unlock(&phba->hbalock);
 		if ((work_ha_copy & HA_MBATT) &&
 		if ((work_ha_copy & HA_MBATT) &&
 		    (phba->sli.mbox_active == NULL)) {
 		    (phba->sli.mbox_active == NULL)) {
-send_next_mbox:
-			spin_lock(&phba->hbalock);
-			phba->sli.sli_flag &= ~LPFC_SLI_MBOX_ACTIVE;
-			pmb = lpfc_mbox_get(phba);
-			spin_unlock(&phba->hbalock);
 send_current_mbox:
 send_current_mbox:
 			/* Process next mailbox command if there is one */
 			/* Process next mailbox command if there is one */
-			if (pmb != NULL) {
-				rc = lpfc_sli_issue_mbox(phba, pmb, MBX_NOWAIT);
-				if (rc == MBX_NOT_FINISHED) {
-					pmb->mb.mbxStatus = MBX_NOT_FINISHED;
-					lpfc_mbox_cmpl_put(phba, pmb);
-					goto send_next_mbox;
-				}
-			}
-
+			do {
+				rc = lpfc_sli_issue_mbox(phba, NULL,
+							 MBX_NOWAIT);
+			} while (rc == MBX_NOT_FINISHED);
+			if (rc != MBX_SUCCESS)
+				lpfc_printf_log(phba, KERN_ERR, LOG_MBOX |
+						LOG_SLI, "0349 rc should be "
+						"MBX_SUCCESS");
 		}
 		}
 
 
 		spin_lock(&phba->hbalock);
 		spin_lock(&phba->hbalock);

+ 1 - 1
drivers/scsi/lpfc/lpfc_version.h

@@ -18,7 +18,7 @@
  * included with this package.                                     *
  * included with this package.                                     *
  *******************************************************************/
  *******************************************************************/
 
 
-#define LPFC_DRIVER_VERSION "8.2.5"
+#define LPFC_DRIVER_VERSION "8.2.6"
 
 
 #define LPFC_DRIVER_NAME "lpfc"
 #define LPFC_DRIVER_NAME "lpfc"
 
 

+ 2 - 1
drivers/scsi/lpfc/lpfc_vport.c

@@ -538,7 +538,8 @@ lpfc_vport_delete(struct fc_vport *fc_vport)
 	/* Otherwise, we will perform fabric logo as needed */
 	/* Otherwise, we will perform fabric logo as needed */
 	if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
 	if (ndlp && NLP_CHK_NODE_ACT(ndlp) &&
 	    ndlp->nlp_state == NLP_STE_UNMAPPED_NODE &&
 	    ndlp->nlp_state == NLP_STE_UNMAPPED_NODE &&
-	    phba->link_state >= LPFC_LINK_UP) {
+	    phba->link_state >= LPFC_LINK_UP &&
+	    phba->fc_topology != TOPOLOGY_LOOP) {
 		if (vport->cfg_enable_da_id) {
 		if (vport->cfg_enable_da_id) {
 			timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
 			timeout = msecs_to_jiffies(phba->fc_ratov * 2000);
 			if (!lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0))
 			if (!lpfc_ns_cmd(vport, SLI_CTNS_DA_ID, 0, 0))

+ 0 - 1
drivers/scsi/mac_scsi.c

@@ -592,7 +592,6 @@ static struct scsi_host_template driver_template = {
 	.this_id			= 7,
 	.this_id			= 7,
 	.sg_tablesize			= SG_ALL,
 	.sg_tablesize			= SG_ALL,
 	.cmd_per_lun			= CMD_PER_LUN,
 	.cmd_per_lun			= CMD_PER_LUN,
-	.unchecked_isa_dma		= 0,
 	.use_clustering			= DISABLE_CLUSTERING
 	.use_clustering			= DISABLE_CLUSTERING
 };
 };
 
 

+ 31 - 18
drivers/scsi/megaraid/megaraid_sas.c

@@ -68,6 +68,8 @@ static struct pci_device_id megasas_pci_table[] = {
 	/* xscale IOP */
 	/* xscale IOP */
 	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)},
 	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)},
 	/* ppc IOP */
 	/* ppc IOP */
+	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078DE)},
+	/* ppc IOP */
 	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
 	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
 	/* xscale IOP, vega */
 	/* xscale IOP, vega */
 	{PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
 	{PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
@@ -488,12 +490,13 @@ megasas_make_sgl64(struct megasas_instance *instance, struct scsi_cmnd *scp,
 
 
  /**
  /**
  * megasas_get_frame_count - Computes the number of frames
  * megasas_get_frame_count - Computes the number of frames
+ * @frame_type		: type of frame- io or pthru frame
  * @sge_count		: number of sg elements
  * @sge_count		: number of sg elements
  *
  *
  * Returns the number of frames required for numnber of sge's (sge_count)
  * Returns the number of frames required for numnber of sge's (sge_count)
  */
  */
 
 
-static u32 megasas_get_frame_count(u8 sge_count)
+static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type)
 {
 {
 	int num_cnt;
 	int num_cnt;
 	int sge_bytes;
 	int sge_bytes;
@@ -504,13 +507,22 @@ static u32 megasas_get_frame_count(u8 sge_count)
 	    sizeof(struct megasas_sge32);
 	    sizeof(struct megasas_sge32);
 
 
 	/*
 	/*
-	* Main frame can contain 2 SGEs for 64-bit SGLs and
-	* 3 SGEs for 32-bit SGLs
-	*/
-	if (IS_DMA64)
-		num_cnt = sge_count - 2;
-	else
-		num_cnt = sge_count - 3;
+	 * Main frame can contain 2 SGEs for 64-bit SGLs and
+	 * 3 SGEs for 32-bit SGLs for ldio &
+	 * 1 SGEs for 64-bit SGLs and
+	 * 2 SGEs for 32-bit SGLs for pthru frame
+	 */
+	if (unlikely(frame_type == PTHRU_FRAME)) {
+		if (IS_DMA64)
+			num_cnt = sge_count - 1;
+		else
+			num_cnt = sge_count - 2;
+	} else {
+		if (IS_DMA64)
+			num_cnt = sge_count - 2;
+		else
+			num_cnt = sge_count - 3;
+	}
 
 
 	if(num_cnt>0){
 	if(num_cnt>0){
 		sge_bytes = sge_sz * num_cnt;
 		sge_bytes = sge_sz * num_cnt;
@@ -592,7 +604,8 @@ megasas_build_dcdb(struct megasas_instance *instance, struct scsi_cmnd *scp,
 	 * Compute the total number of frames this command consumes. FW uses
 	 * Compute the total number of frames this command consumes. FW uses
 	 * this number to pull sufficient number of frames from host memory.
 	 * this number to pull sufficient number of frames from host memory.
 	 */
 	 */
-	cmd->frame_count = megasas_get_frame_count(pthru->sge_count);
+	cmd->frame_count = megasas_get_frame_count(pthru->sge_count,
+							PTHRU_FRAME);
 
 
 	return cmd->frame_count;
 	return cmd->frame_count;
 }
 }
@@ -709,7 +722,7 @@ megasas_build_ldio(struct megasas_instance *instance, struct scsi_cmnd *scp,
 	 * Compute the total number of frames this command consumes. FW uses
 	 * Compute the total number of frames this command consumes. FW uses
 	 * this number to pull sufficient number of frames from host memory.
 	 * this number to pull sufficient number of frames from host memory.
 	 */
 	 */
-	cmd->frame_count = megasas_get_frame_count(ldio->sge_count);
+	cmd->frame_count = megasas_get_frame_count(ldio->sge_count, IO_FRAME);
 
 
 	return cmd->frame_count;
 	return cmd->frame_count;
 }
 }
@@ -1460,7 +1473,7 @@ megasas_transition_to_ready(struct megasas_instance* instance)
 			instance->instancet->disable_intr(instance->reg_set);
 			instance->instancet->disable_intr(instance->reg_set);
 			writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell);
 			writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell);
 
 
-			max_wait = 10;
+			max_wait = 60;
 			cur_state = MFI_STATE_OPERATIONAL;
 			cur_state = MFI_STATE_OPERATIONAL;
 			break;
 			break;
 
 
@@ -1980,7 +1993,8 @@ static int megasas_init_mfi(struct megasas_instance *instance)
 
 
 	switch(instance->pdev->device)
 	switch(instance->pdev->device)
 	{
 	{
-		case PCI_DEVICE_ID_LSI_SAS1078R:	
+		case PCI_DEVICE_ID_LSI_SAS1078R:
+		case PCI_DEVICE_ID_LSI_SAS1078DE:
 			instance->instancet = &megasas_instance_template_ppc;
 			instance->instancet = &megasas_instance_template_ppc;
 			break;
 			break;
 		case PCI_DEVICE_ID_LSI_SAS1064R:
 		case PCI_DEVICE_ID_LSI_SAS1064R:
@@ -2909,7 +2923,6 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
 	void *sense = NULL;
 	void *sense = NULL;
 	dma_addr_t sense_handle;
 	dma_addr_t sense_handle;
 	u32 *sense_ptr;
 	u32 *sense_ptr;
-	unsigned long *sense_buff;
 
 
 	memset(kbuff_arr, 0, sizeof(kbuff_arr));
 	memset(kbuff_arr, 0, sizeof(kbuff_arr));
 
 
@@ -3014,14 +3027,14 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
 	 */
 	 */
 	if (ioc->sense_len) {
 	if (ioc->sense_len) {
 		/*
 		/*
-		 * sense_buff points to the location that has the user
+		 * sense_ptr points to the location that has the user
 		 * sense buffer address
 		 * sense buffer address
 		 */
 		 */
-		sense_buff = (unsigned long *) ((unsigned long)ioc->frame.raw +
-								ioc->sense_off);
+		sense_ptr = (u32 *) ((unsigned long)ioc->frame.raw +
+				     ioc->sense_off);
 
 
-		if (copy_to_user((void __user *)(unsigned long)(*sense_buff),
-				sense, ioc->sense_len)) {
+		if (copy_to_user((void __user *)((unsigned long)(*sense_ptr)),
+				 sense, ioc->sense_len)) {
 			printk(KERN_ERR "megasas: Failed to copy out to user "
 			printk(KERN_ERR "megasas: Failed to copy out to user "
 					"sense data\n");
 					"sense data\n");
 			error = -EFAULT;
 			error = -EFAULT;

+ 5 - 0
drivers/scsi/megaraid/megaraid_sas.h

@@ -26,6 +26,7 @@
  * Device IDs
  * Device IDs
  */
  */
 #define	PCI_DEVICE_ID_LSI_SAS1078R		0x0060
 #define	PCI_DEVICE_ID_LSI_SAS1078R		0x0060
+#define	PCI_DEVICE_ID_LSI_SAS1078DE		0x007C
 #define	PCI_DEVICE_ID_LSI_VERDE_ZCR		0x0413
 #define	PCI_DEVICE_ID_LSI_VERDE_ZCR		0x0413
 
 
 /*
 /*
@@ -542,6 +543,10 @@ struct megasas_ctrl_info {
 
 
 #define MEGASAS_FW_BUSY				1
 #define MEGASAS_FW_BUSY				1
 
 
+/* Frame Type */
+#define IO_FRAME				0
+#define PTHRU_FRAME				1
+
 /*
 /*
  * When SCSI mid-layer calls driver's reset routine, driver waits for
  * When SCSI mid-layer calls driver's reset routine, driver waits for
  * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note
  * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note

+ 3 - 0
drivers/scsi/mvme147.c

@@ -82,6 +82,9 @@ int mvme147_detect(struct scsi_host_template *tpnt)
     mvme147_host->irq = MVME147_IRQ_SCSI_PORT;
     mvme147_host->irq = MVME147_IRQ_SCSI_PORT;
     regs.SASR = (volatile unsigned char *)0xfffe4000;
     regs.SASR = (volatile unsigned char *)0xfffe4000;
     regs.SCMD = (volatile unsigned char *)0xfffe4001;
     regs.SCMD = (volatile unsigned char *)0xfffe4001;
+    HDATA(mvme147_host)->no_sync = 0xff;
+    HDATA(mvme147_host)->fast = 0;
+    HDATA(mvme147_host)->dma_mode = CTRL_DMA;
     wd33c93_init(mvme147_host, regs, dma_setup, dma_stop, WD33C93_FS_8_10);
     wd33c93_init(mvme147_host, regs, dma_setup, dma_stop, WD33C93_FS_8_10);
 
 
     if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0, "MVME147 SCSI PORT", mvme147_intr))
     if (request_irq(MVME147_IRQ_SCSI_PORT, mvme147_intr, 0, "MVME147 SCSI PORT", mvme147_intr))

+ 12 - 89
drivers/scsi/ps3rom.c

@@ -26,6 +26,7 @@
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_dbg.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_device.h>
 #include <scsi/scsi_host.h>
 #include <scsi/scsi_host.h>
+#include <scsi/scsi_eh.h>
 
 
 #include <asm/lv1call.h>
 #include <asm/lv1call.h>
 #include <asm/ps3stor.h>
 #include <asm/ps3stor.h>
@@ -90,78 +91,6 @@ static int ps3rom_slave_configure(struct scsi_device *scsi_dev)
 	return 0;
 	return 0;
 }
 }
 
 
-/*
- * copy data from device into scatter/gather buffer
- */
-static int fill_from_dev_buffer(struct scsi_cmnd *cmd, const void *buf)
-{
-	int k, req_len, act_len, len, active;
-	void *kaddr;
-	struct scatterlist *sgpnt;
-	unsigned int buflen;
-
-	buflen = scsi_bufflen(cmd);
-	if (!buflen)
-		return 0;
-
-	if (!scsi_sglist(cmd))
-		return -1;
-
-	active = 1;
-	req_len = act_len = 0;
-	scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) {
-		if (active) {
-			kaddr = kmap_atomic(sg_page(sgpnt), KM_IRQ0);
-			len = sgpnt->length;
-			if ((req_len + len) > buflen) {
-				active = 0;
-				len = buflen - req_len;
-			}
-			memcpy(kaddr + sgpnt->offset, buf + req_len, len);
-			flush_kernel_dcache_page(sg_page(sgpnt));
-			kunmap_atomic(kaddr, KM_IRQ0);
-			act_len += len;
-		}
-		req_len += sgpnt->length;
-	}
-	scsi_set_resid(cmd, buflen - act_len);
-	return 0;
-}
-
-/*
- * copy data from scatter/gather into device's buffer
- */
-static int fetch_to_dev_buffer(struct scsi_cmnd *cmd, void *buf)
-{
-	int k, req_len, len, fin;
-	void *kaddr;
-	struct scatterlist *sgpnt;
-	unsigned int buflen;
-
-	buflen = scsi_bufflen(cmd);
-	if (!buflen)
-		return 0;
-
-	if (!scsi_sglist(cmd))
-		return -1;
-
-	req_len = fin = 0;
-	scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) {
-		kaddr = kmap_atomic(sg_page(sgpnt), KM_IRQ0);
-		len = sgpnt->length;
-		if ((req_len + len) > buflen) {
-			len = buflen - req_len;
-			fin = 1;
-		}
-		memcpy(buf + req_len, kaddr + sgpnt->offset, len);
-		kunmap_atomic(kaddr, KM_IRQ0);
-		if (fin)
-			return req_len + len;
-		req_len += sgpnt->length;
-	}
-	return req_len;
-}
-
 static int ps3rom_atapi_request(struct ps3_storage_device *dev,
 static int ps3rom_atapi_request(struct ps3_storage_device *dev,
 				struct scsi_cmnd *cmd)
 				struct scsi_cmnd *cmd)
 {
 {
@@ -195,9 +124,7 @@ static int ps3rom_atapi_request(struct ps3_storage_device *dev,
 		else
 		else
 			atapi_cmnd.proto = PIO_DATA_OUT_PROTO;
 			atapi_cmnd.proto = PIO_DATA_OUT_PROTO;
 		atapi_cmnd.in_out = DIR_WRITE;
 		atapi_cmnd.in_out = DIR_WRITE;
-		res = fetch_to_dev_buffer(cmd, dev->bounce_buf);
-		if (res < 0)
-			return DID_ERROR << 16;
+		scsi_sg_copy_to_buffer(cmd, dev->bounce_buf, dev->bounce_size);
 		break;
 		break;
 
 
 	default:
 	default:
@@ -269,9 +196,7 @@ static int ps3rom_write_request(struct ps3_storage_device *dev,
 	dev_dbg(&dev->sbd.core, "%s:%u: write %u sectors starting at %u\n",
 	dev_dbg(&dev->sbd.core, "%s:%u: write %u sectors starting at %u\n",
 		__func__, __LINE__, sectors, start_sector);
 		__func__, __LINE__, sectors, start_sector);
 
 
-	res = fetch_to_dev_buffer(cmd, dev->bounce_buf);
-	if (res < 0)
-		return DID_ERROR << 16;
+	scsi_sg_copy_to_buffer(cmd, dev->bounce_buf, dev->bounce_size);
 
 
 	res = lv1_storage_write(dev->sbd.dev_id,
 	res = lv1_storage_write(dev->sbd.dev_id,
 				dev->regions[dev->region_idx].id, start_sector,
 				dev->regions[dev->region_idx].id, start_sector,
@@ -381,11 +306,13 @@ static irqreturn_t ps3rom_interrupt(int irq, void *data)
 	if (!status) {
 	if (!status) {
 		/* OK, completed */
 		/* OK, completed */
 		if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
 		if (cmd->sc_data_direction == DMA_FROM_DEVICE) {
-			res = fill_from_dev_buffer(cmd, dev->bounce_buf);
-			if (res) {
-				cmd->result = DID_ERROR << 16;
-				goto done;
-			}
+			int len;
+
+			len = scsi_sg_copy_from_buffer(cmd,
+						       dev->bounce_buf,
+						       dev->bounce_size);
+
+			scsi_set_resid(cmd, scsi_bufflen(cmd) - len);
 		}
 		}
 		cmd->result = DID_OK << 16;
 		cmd->result = DID_OK << 16;
 		goto done;
 		goto done;
@@ -404,11 +331,7 @@ static irqreturn_t ps3rom_interrupt(int irq, void *data)
 		goto done;
 		goto done;
 	}
 	}
 
 
-	cmd->sense_buffer[0]  = 0x70;
-	cmd->sense_buffer[2]  = sense_key;
-	cmd->sense_buffer[7]  = 16 - 6;
-	cmd->sense_buffer[12] = asc;
-	cmd->sense_buffer[13] = ascq;
+	scsi_build_sense_buffer(0, cmd->sense_buffer, sense_key, asc, ascq);
 	cmd->result = SAM_STAT_CHECK_CONDITION;
 	cmd->result = SAM_STAT_CHECK_CONDITION;
 
 
 done:
 done:
@@ -427,7 +350,7 @@ static struct scsi_host_template ps3rom_host_template = {
 	.cmd_per_lun =		1,
 	.cmd_per_lun =		1,
 	.emulated =             1,		/* only sg driver uses this */
 	.emulated =             1,		/* only sg driver uses this */
 	.max_sectors =		PS3ROM_MAX_SECTORS,
 	.max_sectors =		PS3ROM_MAX_SECTORS,
-	.use_clustering =	DISABLE_CLUSTERING,
+	.use_clustering =	ENABLE_CLUSTERING,
 	.module =		THIS_MODULE,
 	.module =		THIS_MODULE,
 };
 };
 
 

+ 0 - 5
drivers/scsi/qla1280.c

@@ -333,7 +333,6 @@
 
 
 #include <linux/module.h>
 #include <linux/module.h>
 
 
-#include <linux/version.h>
 #include <linux/types.h>
 #include <linux/types.h>
 #include <linux/string.h>
 #include <linux/string.h>
 #include <linux/errno.h>
 #include <linux/errno.h>
@@ -367,10 +366,6 @@
 #include <asm/sn/io.h>
 #include <asm/sn/io.h>
 #endif
 #endif
 
 
-#if LINUX_VERSION_CODE < 0x020600
-#error "Kernels older than 2.6.0 are no longer supported"
-#endif
-
 
 
 /*
 /*
  * Compile time Options:
  * Compile time Options:

+ 2 - 1
drivers/scsi/qla2xxx/Kconfig

@@ -16,7 +16,8 @@ config SCSI_QLA_FC
 	22xx              ql2200_fw.bin
 	22xx              ql2200_fw.bin
 	2300, 2312, 6312  ql2300_fw.bin
 	2300, 2312, 6312  ql2300_fw.bin
 	2322, 6322        ql2322_fw.bin
 	2322, 6322        ql2322_fw.bin
-	24xx              ql2400_fw.bin
+	24xx, 54xx        ql2400_fw.bin
+	25xx              ql2500_fw.bin
 
 
 	Upon request, the driver caches the firmware image until
 	Upon request, the driver caches the firmware image until
 	the driver is unloaded.
 	the driver is unloaded.

+ 27 - 9
drivers/scsi/qla2xxx/qla_attr.c

@@ -1,6 +1,6 @@
 /*
 /*
  * QLogic Fibre Channel HBA Driver
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2005 QLogic Corporation
+ * Copyright (c)  2003-2008 QLogic Corporation
  *
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
  */
@@ -849,20 +849,20 @@ static void
 qla2x00_get_host_speed(struct Scsi_Host *shost)
 qla2x00_get_host_speed(struct Scsi_Host *shost)
 {
 {
 	scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost));
 	scsi_qla_host_t *ha = to_qla_parent(shost_priv(shost));
-	uint32_t speed = 0;
+	u32 speed = FC_PORTSPEED_UNKNOWN;
 
 
 	switch (ha->link_data_rate) {
 	switch (ha->link_data_rate) {
 	case PORT_SPEED_1GB:
 	case PORT_SPEED_1GB:
-		speed = 1;
+		speed = FC_PORTSPEED_1GBIT;
 		break;
 		break;
 	case PORT_SPEED_2GB:
 	case PORT_SPEED_2GB:
-		speed = 2;
+		speed = FC_PORTSPEED_2GBIT;
 		break;
 		break;
 	case PORT_SPEED_4GB:
 	case PORT_SPEED_4GB:
-		speed = 4;
+		speed = FC_PORTSPEED_4GBIT;
 		break;
 		break;
 	case PORT_SPEED_8GB:
 	case PORT_SPEED_8GB:
-		speed = 8;
+		speed = FC_PORTSPEED_8GBIT;
 		break;
 		break;
 	}
 	}
 	fc_host_speed(shost) = speed;
 	fc_host_speed(shost) = speed;
@@ -900,7 +900,8 @@ qla2x00_get_starget_node_name(struct scsi_target *starget)
 	u64 node_name = 0;
 	u64 node_name = 0;
 
 
 	list_for_each_entry(fcport, &ha->fcports, list) {
 	list_for_each_entry(fcport, &ha->fcports, list) {
-		if (starget->id == fcport->os_target_id) {
+		if (fcport->rport &&
+		    starget->id == fcport->rport->scsi_target_id) {
 			node_name = wwn_to_u64(fcport->node_name);
 			node_name = wwn_to_u64(fcport->node_name);
 			break;
 			break;
 		}
 		}
@@ -918,7 +919,8 @@ qla2x00_get_starget_port_name(struct scsi_target *starget)
 	u64 port_name = 0;
 	u64 port_name = 0;
 
 
 	list_for_each_entry(fcport, &ha->fcports, list) {
 	list_for_each_entry(fcport, &ha->fcports, list) {
-		if (starget->id == fcport->os_target_id) {
+		if (fcport->rport &&
+		    starget->id == fcport->rport->scsi_target_id) {
 			port_name = wwn_to_u64(fcport->port_name);
 			port_name = wwn_to_u64(fcport->port_name);
 			break;
 			break;
 		}
 		}
@@ -936,7 +938,8 @@ qla2x00_get_starget_port_id(struct scsi_target *starget)
 	uint32_t port_id = ~0U;
 	uint32_t port_id = ~0U;
 
 
 	list_for_each_entry(fcport, &ha->fcports, list) {
 	list_for_each_entry(fcport, &ha->fcports, list) {
-		if (starget->id == fcport->os_target_id) {
+		if (fcport->rport &&
+		    starget->id == fcport->rport->scsi_target_id) {
 			port_id = fcport->d_id.b.domain << 16 |
 			port_id = fcport->d_id.b.domain << 16 |
 			    fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
 			    fcport->d_id.b.area << 8 | fcport->d_id.b.al_pa;
 			break;
 			break;
@@ -1196,6 +1199,7 @@ struct fc_function_template qla2xxx_transport_functions = {
 	.show_host_node_name = 1,
 	.show_host_node_name = 1,
 	.show_host_port_name = 1,
 	.show_host_port_name = 1,
 	.show_host_supported_classes = 1,
 	.show_host_supported_classes = 1,
+	.show_host_supported_speeds = 1,
 
 
 	.get_host_port_id = qla2x00_get_host_port_id,
 	.get_host_port_id = qla2x00_get_host_port_id,
 	.show_host_port_id = 1,
 	.show_host_port_id = 1,
@@ -1276,9 +1280,23 @@ struct fc_function_template qla2xxx_transport_vport_functions = {
 void
 void
 qla2x00_init_host_attr(scsi_qla_host_t *ha)
 qla2x00_init_host_attr(scsi_qla_host_t *ha)
 {
 {
+	u32 speed = FC_PORTSPEED_UNKNOWN;
+
 	fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name);
 	fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name);
 	fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name);
 	fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name);
 	fc_host_supported_classes(ha->host) = FC_COS_CLASS3;
 	fc_host_supported_classes(ha->host) = FC_COS_CLASS3;
 	fc_host_max_npiv_vports(ha->host) = ha->max_npiv_vports;;
 	fc_host_max_npiv_vports(ha->host) = ha->max_npiv_vports;;
 	fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count;
 	fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count;
+
+	if (IS_QLA25XX(ha))
+		speed = FC_PORTSPEED_8GBIT | FC_PORTSPEED_4GBIT |
+		    FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT;
+	else if (IS_QLA24XX_TYPE(ha))
+		speed = FC_PORTSPEED_4GBIT | FC_PORTSPEED_2GBIT |
+		    FC_PORTSPEED_1GBIT;
+	else if (IS_QLA23XX(ha))
+		speed = FC_PORTSPEED_2GBIT | FC_PORTSPEED_1GBIT;
+	else
+		speed = FC_PORTSPEED_1GBIT;
+	fc_host_supported_speeds(ha->host) = speed;
 }
 }

+ 1 - 123
drivers/scsi/qla2xxx/qla_dbg.c

@@ -1,6 +1,6 @@
 /*
 /*
  * QLogic Fibre Channel HBA Driver
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2005 QLogic Corporation
+ * Copyright (c)  2003-2008 QLogic Corporation
  *
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
  */
@@ -1410,125 +1410,3 @@ qla2x00_dump_buffer(uint8_t * b, uint32_t size)
 	if (cnt % 16)
 	if (cnt % 16)
 		printk("\n");
 		printk("\n");
 }
 }
-
-/**************************************************************************
- *   qla2x00_print_scsi_cmd
- *	 Dumps out info about the scsi cmd and srb.
- *   Input
- *	 cmd : struct scsi_cmnd
- **************************************************************************/
-void
-qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd)
-{
-	int i;
-	struct scsi_qla_host *ha;
-	srb_t *sp;
-
-	ha = shost_priv(cmd->device->host);
-
-	sp = (srb_t *) cmd->SCp.ptr;
-	printk("SCSI Command @=0x%p, Handle=0x%p\n", cmd, cmd->host_scribble);
-	printk("  chan=0x%02x, target=0x%02x, lun=0x%02x, cmd_len=0x%02x\n",
-	    cmd->device->channel, cmd->device->id, cmd->device->lun,
-	    cmd->cmd_len);
-	printk(" CDB: ");
-	for (i = 0; i < cmd->cmd_len; i++) {
-		printk("0x%02x ", cmd->cmnd[i]);
-	}
-	printk("\n  seg_cnt=%d, allowed=%d, retries=%d\n",
-	       scsi_sg_count(cmd), cmd->allowed, cmd->retries);
-	printk("  request buffer=0x%p, request buffer len=0x%x\n",
-	       scsi_sglist(cmd), scsi_bufflen(cmd));
-	printk("  tag=%d, transfersize=0x%x\n",
-	    cmd->tag, cmd->transfersize);
-	printk("  serial_number=%lx, SP=%p\n", cmd->serial_number, sp);
-	printk("  data direction=%d\n", cmd->sc_data_direction);
-
-	if (!sp)
-		return;
-
-	printk("  sp flags=0x%x\n", sp->flags);
-}
-
-#if defined(QL_DEBUG_ROUTINES)
-/*
- * qla2x00_formatted_dump_buffer
- *       Prints string plus buffer.
- *
- * Input:
- *       string  = Null terminated string (no newline at end).
- *       buffer  = buffer address.
- *       wd_size = word size 8, 16, 32 or 64 bits
- *       count   = number of words.
- */
-void
-qla2x00_formatted_dump_buffer(char *string, uint8_t * buffer,
-				uint8_t wd_size, uint32_t count)
-{
-	uint32_t cnt;
-	uint16_t *buf16;
-	uint32_t *buf32;
-
-	if (strcmp(string, "") != 0)
-		printk("%s\n",string);
-
-	switch (wd_size) {
-		case 8:
-			printk(" 0    1    2    3    4    5    6    7    "
-				"8    9    Ah   Bh   Ch   Dh   Eh   Fh\n");
-			printk("-----------------------------------------"
-				"-------------------------------------\n");
-
-			for (cnt = 1; cnt <= count; cnt++, buffer++) {
-				printk("%02x",*buffer);
-				if (cnt % 16 == 0)
-					printk("\n");
-				else
-					printk("  ");
-			}
-			if (cnt % 16 != 0)
-				printk("\n");
-			break;
-		case 16:
-			printk("   0      2      4      6      8      Ah "
-				"	Ch     Eh\n");
-			printk("-----------------------------------------"
-				"-------------\n");
-
-			buf16 = (uint16_t *) buffer;
-			for (cnt = 1; cnt <= count; cnt++, buf16++) {
-				printk("%4x",*buf16);
-
-				if (cnt % 8 == 0)
-					printk("\n");
-				else if (*buf16 < 10)
-					printk("   ");
-				else
-					printk("  ");
-			}
-			if (cnt % 8 != 0)
-				printk("\n");
-			break;
-		case 32:
-			printk("       0          4          8          Ch\n");
-			printk("------------------------------------------\n");
-
-			buf32 = (uint32_t *) buffer;
-			for (cnt = 1; cnt <= count; cnt++, buf32++) {
-				printk("%8x", *buf32);
-
-				if (cnt % 4 == 0)
-					printk("\n");
-				else if (*buf32 < 10)
-					printk("   ");
-				else
-					printk("  ");
-			}
-			if (cnt % 4 != 0)
-				printk("\n");
-			break;
-		default:
-			break;
-	}
-}
-#endif

+ 9 - 14
drivers/scsi/qla2xxx/qla_dbg.h

@@ -1,6 +1,6 @@
 /*
 /*
  * QLogic Fibre Channel HBA Driver
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2005 QLogic Corporation
+ * Copyright (c)  2003-2008 QLogic Corporation
  *
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
  */
@@ -22,19 +22,7 @@
 /* #define QL_DEBUG_LEVEL_13 */ /* Output fdmi function trace msgs */
 /* #define QL_DEBUG_LEVEL_13 */ /* Output fdmi function trace msgs */
 /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */
 /* #define QL_DEBUG_LEVEL_14 */ /* Output RSCN trace msgs */
 /* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */
 /* #define QL_DEBUG_LEVEL_15 */ /* Output NPIV trace msgs */
-/*
- *  Local Macro Definitions.
- */
-#if defined(QL_DEBUG_LEVEL_1)  || defined(QL_DEBUG_LEVEL_2) || \
-    defined(QL_DEBUG_LEVEL_3)  || defined(QL_DEBUG_LEVEL_4) || \
-    defined(QL_DEBUG_LEVEL_5)  || defined(QL_DEBUG_LEVEL_6) || \
-    defined(QL_DEBUG_LEVEL_7)  || defined(QL_DEBUG_LEVEL_8) || \
-    defined(QL_DEBUG_LEVEL_9)  || defined(QL_DEBUG_LEVEL_10) || \
-    defined(QL_DEBUG_LEVEL_11) || defined(QL_DEBUG_LEVEL_12) || \
-    defined(QL_DEBUG_LEVEL_13) || defined(QL_DEBUG_LEVEL_14) || \
-    defined(QL_DEBUG_LEVEL_15)
-    #define QL_DEBUG_ROUTINES
-#endif
+/* #define QL_DEBUG_LEVEL_16 */ /* Output ISP84XX trace msgs */
 
 
 /*
 /*
 * Macros use for debugging the driver.
 * Macros use for debugging the driver.
@@ -54,6 +42,7 @@
 #define DEBUG2_9_10(x)	do { if (ql2xextended_error_logging) { x; } } while (0)
 #define DEBUG2_9_10(x)	do { if (ql2xextended_error_logging) { x; } } while (0)
 #define DEBUG2_11(x)	do { if (ql2xextended_error_logging) { x; } } while (0)
 #define DEBUG2_11(x)	do { if (ql2xextended_error_logging) { x; } } while (0)
 #define DEBUG2_13(x)	do { if (ql2xextended_error_logging) { x; } } while (0)
 #define DEBUG2_13(x)	do { if (ql2xextended_error_logging) { x; } } while (0)
+#define DEBUG2_16(x)	do { if (ql2xextended_error_logging) { x; } } while (0)
 
 
 #if defined(QL_DEBUG_LEVEL_3)
 #if defined(QL_DEBUG_LEVEL_3)
 #define DEBUG3(x)	do {x;} while (0)
 #define DEBUG3(x)	do {x;} while (0)
@@ -133,6 +122,12 @@
 #define DEBUG15(x)	do {} while (0)
 #define DEBUG15(x)	do {} while (0)
 #endif
 #endif
 
 
+#if defined(QL_DEBUG_LEVEL_16)
+#define DEBUG16(x)	do {x;} while (0)
+#else
+#define DEBUG16(x)	do {} while (0)
+#endif
+
 /*
 /*
  * Firmware Dump structure definition
  * Firmware Dump structure definition
  */
  */

+ 68 - 10
drivers/scsi/qla2xxx/qla_def.h

@@ -1,6 +1,6 @@
 /*
 /*
  * QLogic Fibre Channel HBA Driver
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2005 QLogic Corporation
+ * Copyright (c)  2003-2008 QLogic Corporation
  *
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
  */
@@ -24,6 +24,7 @@
 #include <linux/workqueue.h>
 #include <linux/workqueue.h>
 #include <linux/firmware.h>
 #include <linux/firmware.h>
 #include <linux/aer.h>
 #include <linux/aer.h>
+#include <linux/mutex.h>
 #include <asm/semaphore.h>
 #include <asm/semaphore.h>
 
 
 #include <scsi/scsi.h>
 #include <scsi/scsi.h>
@@ -192,9 +193,6 @@ typedef struct srb {
 
 
 	uint16_t flags;
 	uint16_t flags;
 
 
-	/* Single transfer DMA context */
-	dma_addr_t dma_handle;
-
 	uint32_t request_sense_length;
 	uint32_t request_sense_length;
 	uint8_t *request_sense_ptr;
 	uint8_t *request_sense_ptr;
 } srb_t;
 } srb_t;
@@ -1542,8 +1540,6 @@ typedef struct fc_port {
 	atomic_t state;
 	atomic_t state;
 	uint32_t flags;
 	uint32_t flags;
 
 
-	unsigned int os_target_id;
-
 	int port_login_retry_count;
 	int port_login_retry_count;
 	int login_retry;
 	int login_retry;
 	atomic_t port_down_timer;
 	atomic_t port_down_timer;
@@ -1613,6 +1609,7 @@ typedef struct fc_port {
 #define CT_ACCEPT_RESPONSE	0x8002
 #define CT_ACCEPT_RESPONSE	0x8002
 #define CT_REASON_INVALID_COMMAND_CODE	0x01
 #define CT_REASON_INVALID_COMMAND_CODE	0x01
 #define CT_REASON_CANNOT_PERFORM	0x09
 #define CT_REASON_CANNOT_PERFORM	0x09
+#define CT_REASON_COMMAND_UNSUPPORTED	0x0b
 #define CT_EXPL_ALREADY_REGISTERED	0x10
 #define CT_EXPL_ALREADY_REGISTERED	0x10
 
 
 #define NS_N_PORT_TYPE	0x01
 #define NS_N_PORT_TYPE	0x01
@@ -2063,7 +2060,8 @@ struct isp_operations {
 	void (*disable_intrs) (struct scsi_qla_host *);
 	void (*disable_intrs) (struct scsi_qla_host *);
 
 
 	int (*abort_command) (struct scsi_qla_host *, srb_t *);
 	int (*abort_command) (struct scsi_qla_host *, srb_t *);
-	int (*abort_target) (struct fc_port *);
+	int (*target_reset) (struct fc_port *, unsigned int);
+	int (*lun_reset) (struct fc_port *, unsigned int);
 	int (*fabric_login) (struct scsi_qla_host *, uint16_t, uint8_t,
 	int (*fabric_login) (struct scsi_qla_host *, uint16_t, uint8_t,
 		uint8_t, uint8_t, uint16_t *, uint8_t);
 		uint8_t, uint8_t, uint16_t *, uint8_t);
 	int (*fabric_logout) (struct scsi_qla_host *, uint16_t, uint8_t,
 	int (*fabric_logout) (struct scsi_qla_host *, uint16_t, uint8_t,
@@ -2117,6 +2115,46 @@ struct qla_msix_entry {
 
 
 #define	WATCH_INTERVAL		1       /* number of seconds */
 #define	WATCH_INTERVAL		1       /* number of seconds */
 
 
+/* Work events.  */
+enum qla_work_type {
+	QLA_EVT_AEN,
+	QLA_EVT_HWE_LOG,
+};
+
+
+struct qla_work_evt {
+	struct list_head	list;
+	enum qla_work_type	type;
+	u32			flags;
+#define QLA_EVT_FLAG_FREE	0x1
+
+	union {
+		struct {
+			enum fc_host_event_code code;
+			u32 data;
+		} aen;
+		struct {
+			uint16_t code;
+			uint16_t d1, d2, d3;
+		} hwe;
+	} u;
+};
+
+struct qla_chip_state_84xx {
+	struct list_head list;
+	struct kref kref;
+
+	void *bus;
+	spinlock_t access_lock;
+	struct mutex fw_update_mutex;
+	uint32_t fw_update;
+	uint32_t op_fw_version;
+	uint32_t op_fw_size;
+	uint32_t op_fw_seq_size;
+	uint32_t diag_fw_version;
+	uint32_t gold_fw_version;
+};
+
 /*
 /*
  * Linux Host Adapter structure
  * Linux Host Adapter structure
  */
  */
@@ -2155,6 +2193,7 @@ typedef struct scsi_qla_host {
 		uint32_t        vsan_enabled            :1;
 		uint32_t        vsan_enabled            :1;
 		uint32_t	npiv_supported		:1;
 		uint32_t	npiv_supported		:1;
 		uint32_t	fce_enabled		:1;
 		uint32_t	fce_enabled		:1;
+		uint32_t	hw_event_marker_found	:1;
 	} flags;
 	} flags;
 
 
 	atomic_t	loop_state;
 	atomic_t	loop_state;
@@ -2204,6 +2243,7 @@ typedef struct scsi_qla_host {
 #define	DFLG_NO_CABLE			BIT_4
 #define	DFLG_NO_CABLE			BIT_4
 
 
 #define PCI_DEVICE_ID_QLOGIC_ISP2532	0x2532
 #define PCI_DEVICE_ID_QLOGIC_ISP2532	0x2532
+#define PCI_DEVICE_ID_QLOGIC_ISP8432	0x8432
 	uint32_t	device_type;
 	uint32_t	device_type;
 #define DT_ISP2100			BIT_0
 #define DT_ISP2100			BIT_0
 #define DT_ISP2200			BIT_1
 #define DT_ISP2200			BIT_1
@@ -2217,7 +2257,8 @@ typedef struct scsi_qla_host {
 #define DT_ISP5422			BIT_9
 #define DT_ISP5422			BIT_9
 #define DT_ISP5432			BIT_10
 #define DT_ISP5432			BIT_10
 #define DT_ISP2532			BIT_11
 #define DT_ISP2532			BIT_11
-#define DT_ISP_LAST			(DT_ISP2532 << 1)
+#define DT_ISP8432			BIT_12
+#define DT_ISP_LAST			(DT_ISP8432 << 1)
 
 
 #define DT_IIDMA			BIT_26
 #define DT_IIDMA			BIT_26
 #define DT_FWI2				BIT_27
 #define DT_FWI2				BIT_27
@@ -2239,12 +2280,16 @@ typedef struct scsi_qla_host {
 #define IS_QLA5422(ha)	(DT_MASK(ha) & DT_ISP5422)
 #define IS_QLA5422(ha)	(DT_MASK(ha) & DT_ISP5422)
 #define IS_QLA5432(ha)	(DT_MASK(ha) & DT_ISP5432)
 #define IS_QLA5432(ha)	(DT_MASK(ha) & DT_ISP5432)
 #define IS_QLA2532(ha)	(DT_MASK(ha) & DT_ISP2532)
 #define IS_QLA2532(ha)	(DT_MASK(ha) & DT_ISP2532)
+#define IS_QLA8432(ha)	(DT_MASK(ha) & DT_ISP8432)
 
 
 #define IS_QLA23XX(ha)	(IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
 #define IS_QLA23XX(ha)	(IS_QLA2300(ha) || IS_QLA2312(ha) || IS_QLA2322(ha) || \
     			 IS_QLA6312(ha) || IS_QLA6322(ha))
     			 IS_QLA6312(ha) || IS_QLA6322(ha))
 #define IS_QLA24XX(ha)	(IS_QLA2422(ha) || IS_QLA2432(ha))
 #define IS_QLA24XX(ha)	(IS_QLA2422(ha) || IS_QLA2432(ha))
 #define IS_QLA54XX(ha)	(IS_QLA5422(ha) || IS_QLA5432(ha))
 #define IS_QLA54XX(ha)	(IS_QLA5422(ha) || IS_QLA5432(ha))
 #define IS_QLA25XX(ha)	(IS_QLA2532(ha))
 #define IS_QLA25XX(ha)	(IS_QLA2532(ha))
+#define IS_QLA84XX(ha)	(IS_QLA8432(ha))
+#define IS_QLA24XX_TYPE(ha)	(IS_QLA24XX(ha) || IS_QLA54XX(ha) || \
+			IS_QLA84XX(ha))
 
 
 #define IS_IIDMA_CAPABLE(ha)	((ha)->device_type & DT_IIDMA)
 #define IS_IIDMA_CAPABLE(ha)	((ha)->device_type & DT_IIDMA)
 #define IS_FWI2_CAPABLE(ha)	((ha)->device_type & DT_FWI2)
 #define IS_FWI2_CAPABLE(ha)	((ha)->device_type & DT_FWI2)
@@ -2356,6 +2401,8 @@ typedef struct scsi_qla_host {
         uint32_t	login_retry_count;
         uint32_t	login_retry_count;
 	int		max_q_depth;
 	int		max_q_depth;
 
 
+	struct list_head	work_list;
+
 	/* Fibre Channel Device List. */
 	/* Fibre Channel Device List. */
 	struct list_head	fcports;
 	struct list_head	fcports;
 
 
@@ -2423,8 +2470,6 @@ typedef struct scsi_qla_host {
 #define  MBX_TIMEDOUT		BIT_5
 #define  MBX_TIMEDOUT		BIT_5
 #define  MBX_ACCESS_TIMEDOUT	BIT_6
 #define  MBX_ACCESS_TIMEDOUT	BIT_6
 
 
-	mbx_cmd_t 	mc;
-
 	/* Basic firmware related information. */
 	/* Basic firmware related information. */
 	uint16_t	fw_major_version;
 	uint16_t	fw_major_version;
 	uint16_t	fw_minor_version;
 	uint16_t	fw_minor_version;
@@ -2458,6 +2503,10 @@ typedef struct scsi_qla_host {
 	uint64_t	fce_wr, fce_rd;
 	uint64_t	fce_wr, fce_rd;
 	struct mutex	fce_mutex;
 	struct mutex	fce_mutex;
 
 
+	uint32_t	hw_event_start;
+	uint32_t	hw_event_ptr;
+	uint32_t	hw_event_pause_errors;
+
 	uint8_t		host_str[16];
 	uint8_t		host_str[16];
 	uint32_t	pci_attr;
 	uint32_t	pci_attr;
 	uint16_t	chip_revision;
 	uint16_t	chip_revision;
@@ -2493,6 +2542,13 @@ typedef struct scsi_qla_host {
 	uint8_t		fcode_revision[16];
 	uint8_t		fcode_revision[16];
 	uint32_t	fw_revision[4];
 	uint32_t	fw_revision[4];
 
 
+	uint16_t	fdt_odd_index;
+	uint32_t	fdt_wrt_disable;
+	uint32_t	fdt_erase_cmd;
+	uint32_t	fdt_block_size;
+	uint32_t	fdt_unprotect_sec_cmd;
+	uint32_t	fdt_protect_sec_cmd;
+
 	/* Needed for BEACON */
 	/* Needed for BEACON */
 	uint16_t	beacon_blink_led;
 	uint16_t	beacon_blink_led;
 	uint8_t		beacon_color_state;
 	uint8_t		beacon_color_state;
@@ -2538,6 +2594,8 @@ typedef struct scsi_qla_host {
 #define VP_ERR_ADAP_NORESOURCES	5
 #define VP_ERR_ADAP_NORESOURCES	5
 	uint16_t	max_npiv_vports;	/* 63 or 125 per topoloty */
 	uint16_t	max_npiv_vports;	/* 63 or 125 per topoloty */
 	int		cur_vport_count;
 	int		cur_vport_count;
+
+	struct qla_chip_state_84xx *cs84xx;
 } scsi_qla_host_t;
 } scsi_qla_host_t;
 
 
 
 

+ 1 - 1
drivers/scsi/qla2xxx/qla_dfs.c

@@ -1,6 +1,6 @@
 /*
 /*
  * QLogic Fibre Channel HBA Driver
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2005 QLogic Corporation
+ * Copyright (c)  2003-2008 QLogic Corporation
  *
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
  */

+ 170 - 3
drivers/scsi/qla2xxx/qla_fw.h

@@ -1,6 +1,6 @@
 /*
 /*
  * QLogic Fibre Channel HBA Driver
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2005 QLogic Corporation
+ * Copyright (c)  2003-2008 QLogic Corporation
  *
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
  */
@@ -719,7 +719,7 @@ struct tsk_mgmt_entry {
 
 
 	uint16_t timeout;		/* Command timeout. */
 	uint16_t timeout;		/* Command timeout. */
 
 
-	uint8_t lun[8];			/* FCP LUN (BE). */
+	struct scsi_lun lun;		/* FCP LUN (BE). */
 
 
 	uint32_t control_flags;		/* Control Flags. */
 	uint32_t control_flags;		/* Control Flags. */
 #define TCF_NOTMCMD_TO_TARGET	BIT_31
 #define TCF_NOTMCMD_TO_TARGET	BIT_31
@@ -793,7 +793,19 @@ struct device_reg_24xx {
 #define FA_VPD_NVRAM_ADDR	0x48000
 #define FA_VPD_NVRAM_ADDR	0x48000
 #define FA_FEATURE_ADDR		0x4C000
 #define FA_FEATURE_ADDR		0x4C000
 #define FA_FLASH_DESCR_ADDR	0x50000
 #define FA_FLASH_DESCR_ADDR	0x50000
-#define FA_HW_EVENT_ADDR	0x54000
+#define FA_HW_EVENT0_ADDR	0x54000
+#define FA_HW_EVENT1_ADDR	0x54200
+#define FA_HW_EVENT_SIZE	0x200
+#define FA_HW_EVENT_ENTRY_SIZE	4
+/*
+ * Flash Error Log Event Codes.
+ */
+#define HW_EVENT_RESET_ERR	0xF00B
+#define HW_EVENT_ISP_ERR	0xF020
+#define HW_EVENT_PARITY_ERR	0xF022
+#define HW_EVENT_NVRAM_CHKSUM_ERR	0xF023
+#define HW_EVENT_FLASH_FW_ERR	0xF024
+
 #define FA_BOOT_LOG_ADDR	0x58000
 #define FA_BOOT_LOG_ADDR	0x58000
 #define FA_FW_DUMP0_ADDR	0x60000
 #define FA_FW_DUMP0_ADDR	0x60000
 #define FA_FW_DUMP1_ADDR	0x70000
 #define FA_FW_DUMP1_ADDR	0x70000
@@ -1174,4 +1186,159 @@ struct vf_evfp_entry_24xx {
 };
 };
 
 
 /* END MID Support ***********************************************************/
 /* END MID Support ***********************************************************/
+
+/* Flash Description Table ***************************************************/
+
+struct qla_fdt_layout {
+	uint8_t sig[4];
+	uint16_t version;
+	uint16_t len;
+	uint16_t checksum;
+	uint8_t unused1[2];
+	uint8_t model[16];
+	uint16_t man_id;
+	uint16_t id;
+	uint8_t flags;
+	uint8_t erase_cmd;
+	uint8_t alt_erase_cmd;
+	uint8_t wrt_enable_cmd;
+	uint8_t wrt_enable_bits;
+	uint8_t wrt_sts_reg_cmd;
+	uint8_t unprotect_sec_cmd;
+	uint8_t read_man_id_cmd;
+	uint32_t block_size;
+	uint32_t alt_block_size;
+	uint32_t flash_size;
+	uint32_t wrt_enable_data;
+	uint8_t read_id_addr_len;
+	uint8_t wrt_disable_bits;
+	uint8_t read_dev_id_len;
+	uint8_t chip_erase_cmd;
+	uint16_t read_timeout;
+	uint8_t protect_sec_cmd;
+	uint8_t unused2[65];
+};
+
+/* 84XX Support **************************************************************/
+
+#define MBA_ISP84XX_ALERT	0x800f  /* Alert Notification. */
+#define A84_PANIC_RECOVERY	0x1
+#define A84_OP_LOGIN_COMPLETE	0x2
+#define A84_DIAG_LOGIN_COMPLETE	0x3
+#define A84_GOLD_LOGIN_COMPLETE	0x4
+
+#define MBC_ISP84XX_RESET	0x3a    /* Reset. */
+
+#define FSTATE_REMOTE_FC_DOWN	BIT_0
+#define FSTATE_NSL_LINK_DOWN	BIT_1
+#define FSTATE_IS_DIAG_FW	BIT_2
+#define FSTATE_LOGGED_IN	BIT_3
+#define FSTATE_WAITING_FOR_VERIFY	BIT_4
+
+#define VERIFY_CHIP_IOCB_TYPE	0x1B
+struct verify_chip_entry_84xx {
+	uint8_t entry_type;
+	uint8_t entry_count;
+	uint8_t sys_defined;
+	uint8_t entry_status;
+
+	uint32_t handle;
+
+	uint16_t options;
+#define VCO_DONT_UPDATE_FW	BIT_0
+#define VCO_FORCE_UPDATE	BIT_1
+#define VCO_DONT_RESET_UPDATE	BIT_2
+#define VCO_DIAG_FW		BIT_3
+#define VCO_END_OF_DATA		BIT_14
+#define VCO_ENABLE_DSD		BIT_15
+
+	uint16_t reserved_1;
+
+	uint16_t data_seg_cnt;
+	uint16_t reserved_2[3];
+
+	uint32_t fw_ver;
+	uint32_t exchange_address;
+
+	uint32_t reserved_3[3];
+	uint32_t fw_size;
+	uint32_t fw_seq_size;
+	uint32_t relative_offset;
+
+	uint32_t dseg_address[2];
+	uint32_t dseg_length;
+};
+
+struct verify_chip_rsp_84xx {
+	uint8_t entry_type;
+	uint8_t entry_count;
+	uint8_t sys_defined;
+	uint8_t entry_status;
+
+	uint32_t handle;
+
+	uint16_t comp_status;
+#define CS_VCS_CHIP_FAILURE	0x3
+#define CS_VCS_BAD_EXCHANGE	0x8
+#define CS_VCS_SEQ_COMPLETEi	0x40
+
+	uint16_t failure_code;
+#define VFC_CHECKSUM_ERROR	0x1
+#define VFC_INVALID_LEN		0x2
+#define VFC_ALREADY_IN_PROGRESS	0x8
+
+	uint16_t reserved_1[4];
+
+	uint32_t fw_ver;
+	uint32_t exchange_address;
+
+	uint32_t reserved_2[6];
+};
+
+#define ACCESS_CHIP_IOCB_TYPE	0x2B
+struct access_chip_84xx {
+	uint8_t entry_type;
+	uint8_t entry_count;
+	uint8_t sys_defined;
+	uint8_t entry_status;
+
+	uint32_t handle;
+
+	uint16_t options;
+#define ACO_DUMP_MEMORY		0x0
+#define ACO_LOAD_MEMORY		0x1
+#define ACO_CHANGE_CONFIG_PARAM	0x2
+#define ACO_REQUEST_INFO	0x3
+
+	uint16_t reserved1;
+
+	uint16_t dseg_count;
+	uint16_t reserved2[3];
+
+	uint32_t parameter1;
+	uint32_t parameter2;
+	uint32_t parameter3;
+
+	uint32_t reserved3[3];
+	uint32_t total_byte_cnt;
+	uint32_t reserved4;
+
+	uint32_t dseg_address[2];
+	uint32_t dseg_length;
+};
+
+struct access_chip_rsp_84xx {
+	uint8_t entry_type;
+	uint8_t entry_count;
+	uint8_t sys_defined;
+	uint8_t entry_status;
+
+	uint32_t handle;
+
+	uint16_t comp_status;
+	uint16_t failure_code;
+	uint32_t residual_count;
+
+	uint32_t reserved[12];
+};
 #endif
 #endif

+ 24 - 9
drivers/scsi/qla2xxx/qla_gbl.h

@@ -1,6 +1,6 @@
 /*
 /*
  * QLogic Fibre Channel HBA Driver
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2005 QLogic Corporation
+ * Copyright (c)  2003-2008 QLogic Corporation
  *
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
  */
@@ -38,9 +38,6 @@ extern int qla2x00_loop_resync(scsi_qla_host_t *);
 extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *);
 extern int qla2x00_fabric_login(scsi_qla_host_t *, fc_port_t *, uint16_t *);
 extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *);
 extern int qla2x00_local_device_login(scsi_qla_host_t *, fc_port_t *);
 
 
-extern void qla2x00_restart_queues(scsi_qla_host_t *, uint8_t);
-
-extern void qla2x00_rescan_fcports(scsi_qla_host_t *);
 extern void qla2x00_update_fcports(scsi_qla_host_t *);
 extern void qla2x00_update_fcports(scsi_qla_host_t *);
 
 
 extern int qla2x00_abort_isp(scsi_qla_host_t *);
 extern int qla2x00_abort_isp(scsi_qla_host_t *);
@@ -50,6 +47,8 @@ extern void qla2x00_update_fcport(scsi_qla_host_t *, fc_port_t *);
 extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *);
 extern void qla2x00_alloc_fw_dump(scsi_qla_host_t *);
 extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *);
 extern void qla2x00_try_to_stop_firmware(scsi_qla_host_t *);
 
 
+extern void qla84xx_put_chip(struct scsi_qla_host *);
+
 /*
 /*
  * Global Data in qla_os.c source file.
  * Global Data in qla_os.c source file.
  */
  */
@@ -67,6 +66,10 @@ extern int num_hosts;
 
 
 extern int qla2x00_loop_reset(scsi_qla_host_t *);
 extern int qla2x00_loop_reset(scsi_qla_host_t *);
 extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
 extern void qla2x00_abort_all_cmds(scsi_qla_host_t *, int);
+extern int qla2x00_post_aen_work(struct scsi_qla_host *, enum
+    fc_host_event_code, u32);
+extern int qla2x00_post_hwe_work(struct scsi_qla_host *, uint16_t , uint16_t,
+    uint16_t, uint16_t);
 
 
 /*
 /*
  * Global Functions in qla_mid.c source file.
  * Global Functions in qla_mid.c source file.
@@ -148,13 +151,18 @@ qla2x00_verify_checksum(scsi_qla_host_t *, uint32_t);
 extern int
 extern int
 qla2x00_issue_iocb(scsi_qla_host_t *, void *, dma_addr_t, size_t);
 qla2x00_issue_iocb(scsi_qla_host_t *, void *, dma_addr_t, size_t);
 
 
+extern int
+qla2x00_issue_iocb_timeout(scsi_qla_host_t *, void *, dma_addr_t, size_t,
+    uint32_t);
+
 extern int
 extern int
 qla2x00_abort_command(scsi_qla_host_t *, srb_t *);
 qla2x00_abort_command(scsi_qla_host_t *, srb_t *);
 
 
-#if USE_ABORT_TGT
 extern int
 extern int
-qla2x00_abort_target(fc_port_t *);
-#endif
+qla2x00_abort_target(struct fc_port *, unsigned int);
+
+extern int
+qla2x00_lun_reset(struct fc_port *, unsigned int);
 
 
 extern int
 extern int
 qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *,
 qla2x00_get_adapter_id(scsi_qla_host_t *, uint16_t *, uint8_t *, uint8_t *,
@@ -220,7 +228,8 @@ qla24xx_get_isp_stats(scsi_qla_host_t *, struct link_statistics *,
     dma_addr_t);
     dma_addr_t);
 
 
 extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *);
 extern int qla24xx_abort_command(scsi_qla_host_t *, srb_t *);
-extern int qla24xx_abort_target(fc_port_t *);
+extern int qla24xx_abort_target(struct fc_port *, unsigned int);
+extern int qla24xx_lun_reset(struct fc_port *, unsigned int);
 
 
 extern int
 extern int
 qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
 qla2x00_set_serdes_params(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
@@ -246,6 +255,8 @@ qla2x00_read_sfp(scsi_qla_host_t *, dma_addr_t, uint16_t, uint16_t, uint16_t);
 extern int
 extern int
 qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *);
 qla2x00_set_idma_speed(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t *);
 
 
+extern int qla84xx_verify_chip(struct scsi_qla_host *, uint16_t *);
+
 /*
 /*
  * Global Function Prototypes in qla_isr.c source file.
  * Global Function Prototypes in qla_isr.c source file.
  */
  */
@@ -298,6 +309,11 @@ extern uint8_t *qla25xx_read_optrom_data(struct scsi_qla_host *, uint8_t *,
 extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *);
 extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *);
 extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *);
 extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *);
 
 
+extern int qla2xxx_hw_event_log(scsi_qla_host_t *, uint16_t , uint16_t,
+    uint16_t, uint16_t);
+
+extern void qla2xxx_get_flash_info(scsi_qla_host_t *);
+
 /*
 /*
  * Global Function Prototypes in qla_dbg.c source file.
  * Global Function Prototypes in qla_dbg.c source file.
  */
  */
@@ -307,7 +323,6 @@ extern void qla24xx_fw_dump(scsi_qla_host_t *, int);
 extern void qla25xx_fw_dump(scsi_qla_host_t *, int);
 extern void qla25xx_fw_dump(scsi_qla_host_t *, int);
 extern void qla2x00_dump_regs(scsi_qla_host_t *);
 extern void qla2x00_dump_regs(scsi_qla_host_t *);
 extern void qla2x00_dump_buffer(uint8_t *, uint32_t);
 extern void qla2x00_dump_buffer(uint8_t *, uint32_t);
-extern void qla2x00_print_scsi_cmd(struct scsi_cmnd *);
 
 
 /*
 /*
  * Global Function Prototypes in qla_gs.c source file.
  * Global Function Prototypes in qla_gs.c source file.

+ 6 - 10
drivers/scsi/qla2xxx/qla_gs.c

@@ -1,17 +1,11 @@
 /*
 /*
  * QLogic Fibre Channel HBA Driver
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2005 QLogic Corporation
+ * Copyright (c)  2003-2008 QLogic Corporation
  *
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
  */
 #include "qla_def.h"
 #include "qla_def.h"
 
 
-static inline struct ct_sns_req *
-qla2x00_prep_ct_req(struct ct_sns_req *, uint16_t, uint16_t);
-
-static inline struct sns_cmd_pkt *
-qla2x00_prep_sns_cmd(scsi_qla_host_t *, uint16_t, uint16_t, uint16_t);
-
 static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *);
 static int qla2x00_sns_ga_nxt(scsi_qla_host_t *, fc_port_t *);
 static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *);
 static int qla2x00_sns_gid_pt(scsi_qla_host_t *, sw_info_t *);
 static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *);
 static int qla2x00_sns_gpn_id(scsi_qla_host_t *, sw_info_t *);
@@ -1538,7 +1532,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha)
 		eiter->a.sup_speed = __constant_cpu_to_be32(
 		eiter->a.sup_speed = __constant_cpu_to_be32(
 		    FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
 		    FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
 		    FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB);
 		    FDMI_PORT_SPEED_4GB|FDMI_PORT_SPEED_8GB);
-	else if (IS_QLA24XX(ha) || IS_QLA54XX(ha))
+	else if (IS_QLA24XX_TYPE(ha))
 		eiter->a.sup_speed = __constant_cpu_to_be32(
 		eiter->a.sup_speed = __constant_cpu_to_be32(
 		    FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
 		    FDMI_PORT_SPEED_1GB|FDMI_PORT_SPEED_2GB|
 		    FDMI_PORT_SPEED_4GB);
 		    FDMI_PORT_SPEED_4GB);
@@ -1847,8 +1841,10 @@ qla2x00_gpsc(scsi_qla_host_t *ha, sw_info_t *list)
 		    "GPSC")) != QLA_SUCCESS) {
 		    "GPSC")) != QLA_SUCCESS) {
 			/* FM command unsupported? */
 			/* FM command unsupported? */
 			if (rval == QLA_INVALID_COMMAND &&
 			if (rval == QLA_INVALID_COMMAND &&
-			    ct_rsp->header.reason_code ==
-			    CT_REASON_INVALID_COMMAND_CODE) {
+			    (ct_rsp->header.reason_code ==
+				CT_REASON_INVALID_COMMAND_CODE ||
+			     ct_rsp->header.reason_code ==
+				CT_REASON_COMMAND_UNSUPPORTED)) {
 				DEBUG2(printk("scsi(%ld): GPSC command "
 				DEBUG2(printk("scsi(%ld): GPSC command "
 				    "unsupported, disabling query...\n",
 				    "unsupported, disabling query...\n",
 				    ha->host_no));
 				    ha->host_no));

+ 132 - 60
drivers/scsi/qla2xxx/qla_init.c

@@ -1,6 +1,6 @@
 /*
 /*
  * QLogic Fibre Channel HBA Driver
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2005 QLogic Corporation
+ * Copyright (c)  2003-2008 QLogic Corporation
  *
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
  */
@@ -15,14 +15,6 @@
 #include <asm/prom.h>
 #include <asm/prom.h>
 #endif
 #endif
 
 
-/* XXX(hch): this is ugly, but we don't want to pull in exioctl.h */
-#ifndef EXT_IS_LUN_BIT_SET
-#define EXT_IS_LUN_BIT_SET(P,L) \
-    (((P)->mask[L/8] & (0x80 >> (L%8)))?1:0)
-#define EXT_SET_LUN_BIT(P,L) \
-    ((P)->mask[L/8] |= (0x80 >> (L%8)))
-#endif
-
 /*
 /*
 *  QLogic ISP2x00 Hardware Support Function Prototypes.
 *  QLogic ISP2x00 Hardware Support Function Prototypes.
 */
 */
@@ -45,6 +37,9 @@ static int qla2x00_restart_isp(scsi_qla_host_t *);
 
 
 static int qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev);
 static int qla2x00_find_new_loop_id(scsi_qla_host_t *ha, fc_port_t *dev);
 
 
+static struct qla_chip_state_84xx *qla84xx_get_chip(struct scsi_qla_host *);
+static int qla84xx_init_chip(scsi_qla_host_t *);
+
 /****************************************************************************/
 /****************************************************************************/
 /*                QLogic ISP2x00 Hardware Support Functions.                */
 /*                QLogic ISP2x00 Hardware Support Functions.                */
 /****************************************************************************/
 /****************************************************************************/
@@ -114,6 +109,15 @@ qla2x00_initialize_adapter(scsi_qla_host_t *ha)
 		rval = qla2x00_setup_chip(ha);
 		rval = qla2x00_setup_chip(ha);
 		if (rval)
 		if (rval)
 			return (rval);
 			return (rval);
+		qla2xxx_get_flash_info(ha);
+	}
+	if (IS_QLA84XX(ha)) {
+		ha->cs84xx = qla84xx_get_chip(ha);
+		if (!ha->cs84xx) {
+			qla_printk(KERN_ERR, ha,
+			    "Unable to configure ISP84XX.\n");
+			return QLA_FUNCTION_FAILED;
+		}
 	}
 	}
 	rval = qla2x00_init_rings(ha);
 	rval = qla2x00_init_rings(ha);
 
 
@@ -500,6 +504,7 @@ qla2x00_reset_chip(scsi_qla_host_t *ha)
 static inline void
 static inline void
 qla24xx_reset_risc(scsi_qla_host_t *ha)
 qla24xx_reset_risc(scsi_qla_host_t *ha)
 {
 {
+	int hw_evt = 0;
 	unsigned long flags = 0;
 	unsigned long flags = 0;
 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
 	struct device_reg_24xx __iomem *reg = &ha->iobase->isp24;
 	uint32_t cnt, d2;
 	uint32_t cnt, d2;
@@ -528,6 +533,8 @@ qla24xx_reset_risc(scsi_qla_host_t *ha)
 		d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
 		d2 = (uint32_t) RD_REG_WORD(&reg->mailbox0);
 		barrier();
 		barrier();
 	}
 	}
+	if (cnt == 0)
+		hw_evt = 1;
 
 
 	/* Wait for soft-reset to complete. */
 	/* Wait for soft-reset to complete. */
 	d2 = RD_REG_DWORD(&reg->ctrl_status);
 	d2 = RD_REG_DWORD(&reg->ctrl_status);
@@ -536,6 +543,10 @@ qla24xx_reset_risc(scsi_qla_host_t *ha)
 		d2 = RD_REG_DWORD(&reg->ctrl_status);
 		d2 = RD_REG_DWORD(&reg->ctrl_status);
 		barrier();
 		barrier();
 	}
 	}
+	if (cnt == 0 || hw_evt)
+		qla2xxx_hw_event_log(ha, HW_EVENT_RESET_ERR,
+		    RD_REG_WORD(&reg->mailbox1), RD_REG_WORD(&reg->mailbox2),
+		    RD_REG_WORD(&reg->mailbox3));
 
 
 	WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
 	WRT_REG_DWORD(&reg->hccr, HCCRX_SET_RISC_RESET);
 	RD_REG_DWORD(&reg->hccr);
 	RD_REG_DWORD(&reg->hccr);
@@ -1243,10 +1254,10 @@ static int
 qla2x00_fw_ready(scsi_qla_host_t *ha)
 qla2x00_fw_ready(scsi_qla_host_t *ha)
 {
 {
 	int		rval;
 	int		rval;
-	unsigned long	wtime, mtime;
+	unsigned long	wtime, mtime, cs84xx_time;
 	uint16_t	min_wait;	/* Minimum wait time if loop is down */
 	uint16_t	min_wait;	/* Minimum wait time if loop is down */
 	uint16_t	wait_time;	/* Wait time if loop is coming ready */
 	uint16_t	wait_time;	/* Wait time if loop is coming ready */
-	uint16_t	fw_state;
+	uint16_t	state[3];
 
 
 	rval = QLA_SUCCESS;
 	rval = QLA_SUCCESS;
 
 
@@ -1275,12 +1286,34 @@ qla2x00_fw_ready(scsi_qla_host_t *ha)
 	    ha->host_no));
 	    ha->host_no));
 
 
 	do {
 	do {
-		rval = qla2x00_get_firmware_state(ha, &fw_state);
+		rval = qla2x00_get_firmware_state(ha, state);
 		if (rval == QLA_SUCCESS) {
 		if (rval == QLA_SUCCESS) {
-			if (fw_state < FSTATE_LOSS_OF_SYNC) {
+			if (state[0] < FSTATE_LOSS_OF_SYNC) {
 				ha->device_flags &= ~DFLG_NO_CABLE;
 				ha->device_flags &= ~DFLG_NO_CABLE;
 			}
 			}
-			if (fw_state == FSTATE_READY) {
+			if (IS_QLA84XX(ha) && state[0] != FSTATE_READY) {
+				DEBUG16(printk("scsi(%ld): fw_state=%x "
+				    "84xx=%x.\n", ha->host_no, state[0],
+				    state[2]));
+				if ((state[2] & FSTATE_LOGGED_IN) &&
+				     (state[2] & FSTATE_WAITING_FOR_VERIFY)) {
+					DEBUG16(printk("scsi(%ld): Sending "
+					    "verify iocb.\n", ha->host_no));
+
+					cs84xx_time = jiffies;
+					rval = qla84xx_init_chip(ha);
+					if (rval != QLA_SUCCESS)
+						break;
+
+					/* Add time taken to initialize. */
+					cs84xx_time = jiffies - cs84xx_time;
+					wtime += cs84xx_time;
+					mtime += cs84xx_time;
+					DEBUG16(printk("scsi(%ld): Increasing "
+					    "wait time by %ld. New time %ld\n",
+					    ha->host_no, cs84xx_time, wtime));
+				}
+			} else if (state[0] == FSTATE_READY) {
 				DEBUG(printk("scsi(%ld): F/W Ready - OK \n",
 				DEBUG(printk("scsi(%ld): F/W Ready - OK \n",
 				    ha->host_no));
 				    ha->host_no));
 
 
@@ -1294,7 +1327,7 @@ qla2x00_fw_ready(scsi_qla_host_t *ha)
 			rval = QLA_FUNCTION_FAILED;
 			rval = QLA_FUNCTION_FAILED;
 
 
 			if (atomic_read(&ha->loop_down_timer) &&
 			if (atomic_read(&ha->loop_down_timer) &&
-			    fw_state != FSTATE_READY) {
+			    state[0] != FSTATE_READY) {
 				/* Loop down. Timeout on min_wait for states
 				/* Loop down. Timeout on min_wait for states
 				 * other than Wait for Login.
 				 * other than Wait for Login.
 				 */
 				 */
@@ -1319,11 +1352,11 @@ qla2x00_fw_ready(scsi_qla_host_t *ha)
 		msleep(500);
 		msleep(500);
 
 
 		DEBUG3(printk("scsi(%ld): fw_state=%x curr time=%lx.\n",
 		DEBUG3(printk("scsi(%ld): fw_state=%x curr time=%lx.\n",
-		    ha->host_no, fw_state, jiffies));
+		    ha->host_no, state[0], jiffies));
 	} while (1);
 	} while (1);
 
 
 	DEBUG(printk("scsi(%ld): fw_state=%x curr time=%lx.\n",
 	DEBUG(printk("scsi(%ld): fw_state=%x curr time=%lx.\n",
-	    ha->host_no, fw_state, jiffies));
+	    ha->host_no, state[0], jiffies));
 
 
 	if (rval) {
 	if (rval) {
 		DEBUG2_3(printk("scsi(%ld): Firmware ready **** FAILED ****.\n",
 		DEBUG2_3(printk("scsi(%ld): Firmware ready **** FAILED ****.\n",
@@ -1555,6 +1588,10 @@ qla2x00_nvram_config(scsi_qla_host_t *ha)
 		qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet "
 		qla_printk(KERN_WARNING, ha, "Falling back to functioning (yet "
 		    "invalid -- WWPN) defaults.\n");
 		    "invalid -- WWPN) defaults.\n");
 
 
+		if (chksum)
+			qla2xxx_hw_event_log(ha, HW_EVENT_NVRAM_CHKSUM_ERR, 0,
+			    MSW(chksum), LSW(chksum));
+
 		/*
 		/*
 		 * Set default initialization control block.
 		 * Set default initialization control block.
 		 */
 		 */
@@ -2164,20 +2201,6 @@ cleanup_allocation:
 	return (rval);
 	return (rval);
 }
 }
 
 
-static void
-qla2x00_probe_for_all_luns(scsi_qla_host_t *ha)
-{
-	fc_port_t	*fcport;
-
-	qla2x00_mark_all_devices_lost(ha, 0);
- 	list_for_each_entry(fcport, &ha->fcports, list) {
-		if (fcport->port_type != FCT_TARGET)
-			continue;
-
-		qla2x00_update_fcport(ha, fcport);
-	}
-}
-
 static void
 static void
 qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
 qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport)
 {
 {
@@ -2251,10 +2274,6 @@ qla2x00_reg_remote_port(scsi_qla_host_t *ha, fc_port_t *fcport)
 	if (fcport->port_type == FCT_TARGET)
 	if (fcport->port_type == FCT_TARGET)
 		rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
 		rport_ids.roles |= FC_RPORT_ROLE_FCP_TARGET;
 	fc_remote_port_rolechg(rport, rport_ids.roles);
 	fc_remote_port_rolechg(rport, rport_ids.roles);
-
-	if (rport->scsi_target_id != -1 &&
-	    rport->scsi_target_id < ha->host->max_id)
-		fcport->os_target_id = rport->scsi_target_id;
 }
 }
 
 
 /*
 /*
@@ -2434,7 +2453,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
 
 
 			if (fcport->loop_id == FC_NO_LOOP_ID) {
 			if (fcport->loop_id == FC_NO_LOOP_ID) {
 				fcport->loop_id = next_loopid;
 				fcport->loop_id = next_loopid;
-				rval = qla2x00_find_new_loop_id(ha, fcport);
+				rval = qla2x00_find_new_loop_id(
+				    to_qla_parent(ha), fcport);
 				if (rval != QLA_SUCCESS) {
 				if (rval != QLA_SUCCESS) {
 					/* Ran out of IDs to use */
 					/* Ran out of IDs to use */
 					break;
 					break;
@@ -2459,7 +2479,8 @@ qla2x00_configure_fabric(scsi_qla_host_t *ha)
 
 
 			/* Find a new loop ID to use. */
 			/* Find a new loop ID to use. */
 			fcport->loop_id = next_loopid;
 			fcport->loop_id = next_loopid;
-			rval = qla2x00_find_new_loop_id(ha, fcport);
+			rval = qla2x00_find_new_loop_id(to_qla_parent(ha),
+			    fcport);
 			if (rval != QLA_SUCCESS) {
 			if (rval != QLA_SUCCESS) {
 				/* Ran out of IDs to use */
 				/* Ran out of IDs to use */
 				break;
 				break;
@@ -3192,25 +3213,6 @@ qla2x00_loop_resync(scsi_qla_host_t *ha)
 	return (rval);
 	return (rval);
 }
 }
 
 
-void
-qla2x00_rescan_fcports(scsi_qla_host_t *ha)
-{
-	int rescan_done;
-	fc_port_t *fcport;
-
-	rescan_done = 0;
-	list_for_each_entry(fcport, &ha->fcports, list) {
-		if ((fcport->flags & FCF_RESCAN_NEEDED) == 0)
-			continue;
-
-		qla2x00_update_fcport(ha, fcport);
-		fcport->flags &= ~FCF_RESCAN_NEEDED;
-
-		rescan_done = 1;
-	}
-	qla2x00_probe_for_all_luns(ha);
-}
-
 void
 void
 qla2x00_update_fcports(scsi_qla_host_t *ha)
 qla2x00_update_fcports(scsi_qla_host_t *ha)
 {
 {
@@ -4044,16 +4046,16 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha)
 	if (!ha->parent)
 	if (!ha->parent)
 		return -EINVAL;
 		return -EINVAL;
 
 
-	rval = qla2x00_fw_ready(ha);
+	rval = qla2x00_fw_ready(ha->parent);
 	if (rval == QLA_SUCCESS) {
 	if (rval == QLA_SUCCESS) {
 		clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
 		clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags);
-		qla2x00_marker(ha, 0, 0, MK_SYNC_ALL);
+		qla2x00_marker(ha->parent, 0, 0, MK_SYNC_ALL);
 	}
 	}
 
 
 	ha->flags.management_server_logged_in = 0;
 	ha->flags.management_server_logged_in = 0;
 
 
 	/* Login to SNS first */
 	/* Login to SNS first */
-	qla24xx_login_fabric(ha, NPH_SNS, 0xff, 0xff, 0xfc,
+	qla24xx_login_fabric(ha->parent, NPH_SNS, 0xff, 0xff, 0xfc,
 	    mb, BIT_1);
 	    mb, BIT_1);
 	if (mb[0] != MBS_COMMAND_COMPLETE) {
 	if (mb[0] != MBS_COMMAND_COMPLETE) {
 		DEBUG15(qla_printk(KERN_INFO, ha,
 		DEBUG15(qla_printk(KERN_INFO, ha,
@@ -4067,7 +4069,77 @@ qla24xx_configure_vhba(scsi_qla_host_t *ha)
 	atomic_set(&ha->loop_state, LOOP_UP);
 	atomic_set(&ha->loop_state, LOOP_UP);
 	set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
 	set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
 	set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
 	set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags);
-	rval = qla2x00_loop_resync(ha);
+	rval = qla2x00_loop_resync(ha->parent);
 
 
 	return rval;
 	return rval;
 }
 }
+
+/* 84XX Support **************************************************************/
+
+static LIST_HEAD(qla_cs84xx_list);
+static DEFINE_MUTEX(qla_cs84xx_mutex);
+
+static struct qla_chip_state_84xx *
+qla84xx_get_chip(struct scsi_qla_host *ha)
+{
+	struct qla_chip_state_84xx *cs84xx;
+
+	mutex_lock(&qla_cs84xx_mutex);
+
+	/* Find any shared 84xx chip. */
+	list_for_each_entry(cs84xx, &qla_cs84xx_list, list) {
+		if (cs84xx->bus == ha->pdev->bus) {
+			kref_get(&cs84xx->kref);
+			goto done;
+		}
+	}
+
+	cs84xx = kzalloc(sizeof(*cs84xx), GFP_KERNEL);
+	if (!cs84xx)
+		goto done;
+
+	kref_init(&cs84xx->kref);
+	spin_lock_init(&cs84xx->access_lock);
+	mutex_init(&cs84xx->fw_update_mutex);
+	cs84xx->bus = ha->pdev->bus;
+
+	list_add_tail(&cs84xx->list, &qla_cs84xx_list);
+done:
+	mutex_unlock(&qla_cs84xx_mutex);
+	return cs84xx;
+}
+
+static void
+__qla84xx_chip_release(struct kref *kref)
+{
+	struct qla_chip_state_84xx *cs84xx =
+	    container_of(kref, struct qla_chip_state_84xx, kref);
+
+	mutex_lock(&qla_cs84xx_mutex);
+	list_del(&cs84xx->list);
+	mutex_unlock(&qla_cs84xx_mutex);
+	kfree(cs84xx);
+}
+
+void
+qla84xx_put_chip(struct scsi_qla_host *ha)
+{
+	if (ha->cs84xx)
+		kref_put(&ha->cs84xx->kref, __qla84xx_chip_release);
+}
+
+static int
+qla84xx_init_chip(scsi_qla_host_t *ha)
+{
+	int rval;
+	uint16_t status[2];
+
+	mutex_lock(&ha->cs84xx->fw_update_mutex);
+
+	rval = qla84xx_verify_chip(ha, status);
+
+	mutex_unlock(&ha->cs84xx->fw_update_mutex);
+
+	return rval != QLA_SUCCESS || status[0] ? QLA_FUNCTION_FAILED:
+	    QLA_SUCCESS;
+}

+ 1 - 86
drivers/scsi/qla2xxx/qla_inline.h

@@ -1,11 +1,10 @@
 /*
 /*
  * QLogic Fibre Channel HBA Driver
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2005 QLogic Corporation
+ * Copyright (c)  2003-2008 QLogic Corporation
  *
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
  */
 
 
-static __inline__ uint16_t qla2x00_debounce_register(volatile uint16_t __iomem *);
 /*
 /*
  * qla2x00_debounce_register
  * qla2x00_debounce_register
  *      Debounce register.
  *      Debounce register.
@@ -32,94 +31,12 @@ qla2x00_debounce_register(volatile uint16_t __iomem *addr)
 	return (first);
 	return (first);
 }
 }
 
 
-static __inline__ int qla2x00_normalize_dma_addr(
-    dma_addr_t *e_addr,  uint32_t *e_len,
-    dma_addr_t *ne_addr, uint32_t *ne_len);
-
-/**
- * qla2x00_normalize_dma_addr() - Normalize an DMA address.
- * @e_addr: Raw DMA address
- * @e_len: Raw DMA length
- * @ne_addr: Normalized second DMA address
- * @ne_len: Normalized second DMA length
- *
- * If the address does not span a 4GB page boundary, the contents of @ne_addr
- * and @ne_len are undefined.  @e_len is updated to reflect a normalization.
- *
- * Example:
- *
- * 	ffffabc0ffffeeee	(e_addr) start of DMA address
- * 	0000000020000000	(e_len)  length of DMA transfer
- *	ffffabc11fffeeed	end of DMA transfer
- *
- * Is the 4GB boundary crossed?
- *
- * 	ffffabc0ffffeeee	(e_addr)
- *	ffffabc11fffeeed	(e_addr + e_len - 1)
- *	00000001e0000003	((e_addr ^ (e_addr + e_len - 1))
- *	0000000100000000	((e_addr ^ (e_addr + e_len - 1)) & ~(0xffffffff)
- *
- * Compute start of second DMA segment:
- *
- * 	ffffabc0ffffeeee	(e_addr)
- *	ffffabc1ffffeeee	(0x100000000 + e_addr)
- *	ffffabc100000000	(0x100000000 + e_addr) & ~(0xffffffff)
- *	ffffabc100000000	(ne_addr)
- *
- * Compute length of second DMA segment:
- *
- *	00000000ffffeeee	(e_addr & 0xffffffff)
- *	0000000000001112	(0x100000000 - (e_addr & 0xffffffff))
- *	000000001fffeeee	(e_len - (0x100000000 - (e_addr & 0xffffffff))
- *	000000001fffeeee	(ne_len)
- *
- * Adjust length of first DMA segment
- *
- * 	0000000020000000	(e_len)
- *	0000000000001112	(e_len - ne_len)
- *	0000000000001112	(e_len)
- *
- * Returns non-zero if the specified address was normalized, else zero.
- */
-static __inline__ int
-qla2x00_normalize_dma_addr(
-    dma_addr_t *e_addr,  uint32_t *e_len,
-    dma_addr_t *ne_addr, uint32_t *ne_len)
-{
-	int normalized;
-
-	normalized = 0;
-	if ((*e_addr ^ (*e_addr + *e_len - 1)) & ~(0xFFFFFFFFULL)) {
-		/* Compute normalized crossed address and len */
-		*ne_addr = (0x100000000ULL + *e_addr) & ~(0xFFFFFFFFULL);
-		*ne_len = *e_len - (0x100000000ULL - (*e_addr & 0xFFFFFFFFULL));
-		*e_len -= *ne_len;
-
-		normalized++;
-	}
-	return (normalized);
-}
-
-static __inline__ void qla2x00_poll(scsi_qla_host_t *);
 static inline void
 static inline void
 qla2x00_poll(scsi_qla_host_t *ha)
 qla2x00_poll(scsi_qla_host_t *ha)
 {
 {
 	ha->isp_ops->intr_handler(0, ha);
 	ha->isp_ops->intr_handler(0, ha);
 }
 }
 
 
-static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *);
-/*
- * This routine will wait for fabric devices for
- * the reset delay.
- */
-static __inline__ void qla2x00_check_fabric_devices(scsi_qla_host_t *ha)
-{
-	uint16_t	fw_state;
-
-	qla2x00_get_firmware_state(ha, &fw_state);
-}
-
-static __inline__ scsi_qla_host_t * to_qla_parent(scsi_qla_host_t *);
 static __inline__ scsi_qla_host_t *
 static __inline__ scsi_qla_host_t *
 to_qla_parent(scsi_qla_host_t *ha)
 to_qla_parent(scsi_qla_host_t *ha)
 {
 {
@@ -152,7 +69,6 @@ qla2x00_issue_marker(scsi_qla_host_t *ha, int ha_locked)
 	return (QLA_SUCCESS);
 	return (QLA_SUCCESS);
 }
 }
 
 
-static inline uint8_t *host_to_fcp_swap(uint8_t *, uint32_t);
 static inline uint8_t *
 static inline uint8_t *
 host_to_fcp_swap(uint8_t *fcp, uint32_t bsize)
 host_to_fcp_swap(uint8_t *fcp, uint32_t bsize)
 {
 {
@@ -166,7 +82,6 @@ host_to_fcp_swap(uint8_t *fcp, uint32_t bsize)
        return fcp;
        return fcp;
 }
 }
 
 
-static inline int qla2x00_is_reserved_id(scsi_qla_host_t *, uint16_t);
 static inline int
 static inline int
 qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id)
 qla2x00_is_reserved_id(scsi_qla_host_t *ha, uint16_t loop_id)
 {
 {

+ 1 - 4
drivers/scsi/qla2xxx/qla_iocb.c

@@ -1,6 +1,6 @@
 /*
 /*
  * QLogic Fibre Channel HBA Driver
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2005 QLogic Corporation
+ * Copyright (c)  2003-2008 QLogic Corporation
  *
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
  */
@@ -11,9 +11,6 @@
 
 
 #include <scsi/scsi_tcq.h>
 #include <scsi/scsi_tcq.h>
 
 
-static inline uint16_t qla2x00_get_cmd_direction(struct scsi_cmnd *cmd);
-static inline cont_entry_t *qla2x00_prep_cont_type0_iocb(scsi_qla_host_t *);
-static inline cont_a64_entry_t *qla2x00_prep_cont_type1_iocb(scsi_qla_host_t *);
 static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha);
 static request_t *qla2x00_req_pkt(scsi_qla_host_t *ha);
 static void qla2x00_isp_cmd(scsi_qla_host_t *ha);
 static void qla2x00_isp_cmd(scsi_qla_host_t *ha);
 
 

+ 102 - 121
drivers/scsi/qla2xxx/qla_isr.c

@@ -1,6 +1,6 @@
 /*
 /*
  * QLogic Fibre Channel HBA Driver
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2005 QLogic Corporation
+ * Copyright (c)  2003-2008 QLogic Corporation
  *
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
  */
@@ -14,9 +14,6 @@ static void qla2x00_process_completed_request(struct scsi_qla_host *, uint32_t);
 static void qla2x00_status_entry(scsi_qla_host_t *, void *);
 static void qla2x00_status_entry(scsi_qla_host_t *, void *);
 static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *);
 static void qla2x00_status_cont_entry(scsi_qla_host_t *, sts_cont_entry_t *);
 static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *);
 static void qla2x00_error_entry(scsi_qla_host_t *, sts_entry_t *);
-static void qla2x00_ms_entry(scsi_qla_host_t *, ms_iocb_entry_t *);
-
-static void qla24xx_ms_entry(scsi_qla_host_t *, struct ct_entry_24xx *);
 
 
 /**
 /**
  * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
  * qla2100_intr_handler() - Process interrupts for the ISP2100 and ISP2200.
@@ -33,7 +30,6 @@ qla2100_intr_handler(int irq, void *dev_id)
 	scsi_qla_host_t	*ha;
 	scsi_qla_host_t	*ha;
 	struct device_reg_2xxx __iomem *reg;
 	struct device_reg_2xxx __iomem *reg;
 	int		status;
 	int		status;
-	unsigned long	flags;
 	unsigned long	iter;
 	unsigned long	iter;
 	uint16_t	hccr;
 	uint16_t	hccr;
 	uint16_t	mb[4];
 	uint16_t	mb[4];
@@ -48,7 +44,7 @@ qla2100_intr_handler(int irq, void *dev_id)
 	reg = &ha->iobase->isp;
 	reg = &ha->iobase->isp;
 	status = 0;
 	status = 0;
 
 
-	spin_lock_irqsave(&ha->hardware_lock, flags);
+	spin_lock(&ha->hardware_lock);
 	for (iter = 50; iter--; ) {
 	for (iter = 50; iter--; ) {
 		hccr = RD_REG_WORD(&reg->hccr);
 		hccr = RD_REG_WORD(&reg->hccr);
 		if (hccr & HCCR_RISC_PAUSE) {
 		if (hccr & HCCR_RISC_PAUSE) {
@@ -99,7 +95,7 @@ qla2100_intr_handler(int irq, void *dev_id)
 			RD_REG_WORD(&reg->hccr);
 			RD_REG_WORD(&reg->hccr);
 		}
 		}
 	}
 	}
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock(&ha->hardware_lock);
 
 
 	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
 	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
 	    (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
 	    (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
@@ -125,7 +121,6 @@ qla2300_intr_handler(int irq, void *dev_id)
 	scsi_qla_host_t	*ha;
 	scsi_qla_host_t	*ha;
 	struct device_reg_2xxx __iomem *reg;
 	struct device_reg_2xxx __iomem *reg;
 	int		status;
 	int		status;
-	unsigned long	flags;
 	unsigned long	iter;
 	unsigned long	iter;
 	uint32_t	stat;
 	uint32_t	stat;
 	uint16_t	hccr;
 	uint16_t	hccr;
@@ -141,7 +136,7 @@ qla2300_intr_handler(int irq, void *dev_id)
 	reg = &ha->iobase->isp;
 	reg = &ha->iobase->isp;
 	status = 0;
 	status = 0;
 
 
-	spin_lock_irqsave(&ha->hardware_lock, flags);
+	spin_lock(&ha->hardware_lock);
 	for (iter = 50; iter--; ) {
 	for (iter = 50; iter--; ) {
 		stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
 		stat = RD_REG_DWORD(&reg->u.isp2300.host_status);
 		if (stat & HSR_RISC_PAUSED) {
 		if (stat & HSR_RISC_PAUSED) {
@@ -211,7 +206,7 @@ qla2300_intr_handler(int irq, void *dev_id)
 		WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
 		WRT_REG_WORD(&reg->hccr, HCCR_CLR_RISC_INT);
 		RD_REG_WORD_RELAXED(&reg->hccr);
 		RD_REG_WORD_RELAXED(&reg->hccr);
 	}
 	}
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock(&ha->hardware_lock);
 
 
 	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
 	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
 	    (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
 	    (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
@@ -276,6 +271,9 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 	struct device_reg_2xxx __iomem *reg = &ha->iobase->isp;
 	uint32_t	rscn_entry, host_pid;
 	uint32_t	rscn_entry, host_pid;
 	uint8_t		rscn_queue_index;
 	uint8_t		rscn_queue_index;
+	unsigned long	flags;
+	scsi_qla_host_t	*vha;
+	int		i;
 
 
 	/* Setup to process RIO completion. */
 	/* Setup to process RIO completion. */
 	handle_cnt = 0;
 	handle_cnt = 0;
@@ -351,6 +349,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 		    "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n",
 		    "ISP System Error - mbx1=%xh mbx2=%xh mbx3=%xh.\n",
 		    mb[1], mb[2], mb[3]);
 		    mb[1], mb[2], mb[3]);
 
 
+		qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]);
 		ha->isp_ops->fw_dump(ha, 1);
 		ha->isp_ops->fw_dump(ha, 1);
 
 
 		if (IS_FWI2_CAPABLE(ha)) {
 		if (IS_FWI2_CAPABLE(ha)) {
@@ -375,6 +374,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 		    ha->host_no));
 		    ha->host_no));
 		qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n");
 		qla_printk(KERN_WARNING, ha, "ISP Request Transfer Error.\n");
 
 
+		qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]);
 		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 		break;
 		break;
 
 
@@ -383,6 +383,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 		    ha->host_no));
 		    ha->host_no));
 		qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n");
 		qla_printk(KERN_WARNING, ha, "ISP Response Transfer Error.\n");
 
 
+		qla2x00_post_hwe_work(ha, mb[0], mb[1], mb[2], mb[3]);
 		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
 		break;
 		break;
 
 
@@ -410,6 +411,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 		set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
 		set_bit(REGISTER_FC4_NEEDED, &ha->dpc_flags);
 
 
 		ha->flags.management_server_logged_in = 0;
 		ha->flags.management_server_logged_in = 0;
+		qla2x00_post_aen_work(ha, FCH_EVT_LIP, mb[1]);
 		break;
 		break;
 
 
 	case MBA_LOOP_UP:		/* Loop Up Event */
 	case MBA_LOOP_UP:		/* Loop Up Event */
@@ -429,12 +431,14 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 		    link_speed);
 		    link_speed);
 
 
 		ha->flags.management_server_logged_in = 0;
 		ha->flags.management_server_logged_in = 0;
+		qla2x00_post_aen_work(ha, FCH_EVT_LINKUP, ha->link_data_rate);
 		break;
 		break;
 
 
 	case MBA_LOOP_DOWN:		/* Loop Down Event */
 	case MBA_LOOP_DOWN:		/* Loop Down Event */
-		DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN (%x).\n",
-		    ha->host_no, mb[1]));
-		qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x).\n", mb[1]);
+		DEBUG2(printk("scsi(%ld): Asynchronous LOOP DOWN "
+		    "(%x %x %x).\n", ha->host_no, mb[1], mb[2], mb[3]));
+		qla_printk(KERN_INFO, ha, "LOOP DOWN detected (%x %x %x).\n",
+		    mb[1], mb[2], mb[3]);
 
 
 		if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
 		if (atomic_read(&ha->loop_state) != LOOP_DOWN) {
 			atomic_set(&ha->loop_state, LOOP_DOWN);
 			atomic_set(&ha->loop_state, LOOP_DOWN);
@@ -452,6 +456,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 		ha->link_data_rate = PORT_SPEED_UNKNOWN;
 		ha->link_data_rate = PORT_SPEED_UNKNOWN;
 		if (ql2xfdmienable)
 		if (ql2xfdmienable)
 			set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
 			set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags);
+		qla2x00_post_aen_work(ha, FCH_EVT_LINKDOWN, 0);
 		break;
 		break;
 
 
 	case MBA_LIP_RESET:		/* LIP reset occurred */
 	case MBA_LIP_RESET:		/* LIP reset occurred */
@@ -475,6 +480,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 
 
 		ha->operating_mode = LOOP;
 		ha->operating_mode = LOOP;
 		ha->flags.management_server_logged_in = 0;
 		ha->flags.management_server_logged_in = 0;
+		qla2x00_post_aen_work(ha, FCH_EVT_LIPRESET, mb[1]);
 		break;
 		break;
 
 
 	case MBA_POINT_TO_POINT:	/* Point-to-Point */
 	case MBA_POINT_TO_POINT:	/* Point-to-Point */
@@ -538,6 +544,18 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 		break;
 		break;
 
 
 	case MBA_PORT_UPDATE:		/* Port database update */
 	case MBA_PORT_UPDATE:		/* Port database update */
+		if ((ha->flags.npiv_supported) && (ha->num_vhosts)) {
+			for_each_mapped_vp_idx(ha, i) {
+				list_for_each_entry(vha, &ha->vp_list,
+				    vp_list) {
+					if ((mb[3] & 0xff)
+					    == vha->vp_idx) {
+						ha = vha;
+						break;
+					}
+				}
+			}
+		}
 		/*
 		/*
 		 * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET
 		 * If PORT UPDATE is global (recieved LIP_OCCURED/LIP_RESET
 		 * event etc. earlier indicating loop is down) then process
 		 * event etc. earlier indicating loop is down) then process
@@ -572,12 +590,18 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 		break;
 		break;
 
 
 	case MBA_RSCN_UPDATE:		/* State Change Registration */
 	case MBA_RSCN_UPDATE:		/* State Change Registration */
-		/* Check if the Vport has issued a SCR */
-		if (ha->parent && test_bit(VP_SCR_NEEDED, &ha->vp_flags))
-			break;
-		/* Only handle SCNs for our Vport index. */
-		if (ha->flags.npiv_supported && ha->vp_idx != mb[3])
-			break;
+		if ((ha->flags.npiv_supported) && (ha->num_vhosts)) {
+			for_each_mapped_vp_idx(ha, i) {
+				list_for_each_entry(vha, &ha->vp_list,
+				    vp_list) {
+					if ((mb[3] & 0xff)
+					    == vha->vp_idx) {
+						ha = vha;
+						break;
+					}
+				}
+			}
+		}
 
 
 		DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n",
 		DEBUG2(printk("scsi(%ld): Asynchronous RSCR UPDATE.\n",
 		    ha->host_no));
 		    ha->host_no));
@@ -612,6 +636,7 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 
 
 		set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
 		set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
 		set_bit(RSCN_UPDATE, &ha->dpc_flags);
 		set_bit(RSCN_UPDATE, &ha->dpc_flags);
+		qla2x00_post_aen_work(ha, FCH_EVT_RSCN, rscn_entry);
 		break;
 		break;
 
 
 	/* case MBA_RIO_RESPONSE: */
 	/* case MBA_RIO_RESPONSE: */
@@ -637,6 +662,42 @@ qla2x00_async_event(scsi_qla_host_t *ha, uint16_t *mb)
 		DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n",
 		DEBUG2(printk("scsi(%ld): Trace Notification -- %04x %04x.\n",
 		ha->host_no, mb[1], mb[2]));
 		ha->host_no, mb[1], mb[2]));
 		break;
 		break;
+
+	case MBA_ISP84XX_ALERT:
+		DEBUG2(printk("scsi(%ld): ISP84XX Alert Notification -- "
+		    "%04x %04x %04x\n", ha->host_no, mb[1], mb[2], mb[3]));
+
+		spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
+		switch (mb[1]) {
+		case A84_PANIC_RECOVERY:
+			qla_printk(KERN_INFO, ha, "Alert 84XX: panic recovery "
+			    "%04x %04x\n", mb[2], mb[3]);
+			break;
+		case A84_OP_LOGIN_COMPLETE:
+			ha->cs84xx->op_fw_version = mb[3] << 16 | mb[2];
+			DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:"
+			    "firmware version %x\n", ha->cs84xx->op_fw_version));
+			break;
+		case A84_DIAG_LOGIN_COMPLETE:
+			ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2];
+			DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX:"
+			    "diagnostic firmware version %x\n",
+			    ha->cs84xx->diag_fw_version));
+			break;
+		case A84_GOLD_LOGIN_COMPLETE:
+			ha->cs84xx->diag_fw_version = mb[3] << 16 | mb[2];
+			ha->cs84xx->fw_update = 1;
+			DEBUG2(qla_printk(KERN_INFO, ha, "Alert 84XX: gold "
+			    "firmware version %x\n",
+			    ha->cs84xx->gold_fw_version));
+			break;
+		default:
+			qla_printk(KERN_ERR, ha,
+			    "Alert 84xx: Invalid Alert %04x %04x %04x\n",
+			    mb[1], mb[2], mb[3]);
+		}
+		spin_unlock_irqrestore(&ha->cs84xx->access_lock, flags);
+		break;
 	}
 	}
 
 
 	if (!ha->parent && ha->num_vhosts)
 	if (!ha->parent && ha->num_vhosts)
@@ -803,9 +864,6 @@ qla2x00_process_response_queue(struct scsi_qla_host *ha)
 		case STATUS_CONT_TYPE:
 		case STATUS_CONT_TYPE:
 			qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
 			qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
 			break;
 			break;
-		case MS_IOCB_TYPE:
-			qla2x00_ms_entry(ha, (ms_iocb_entry_t *)pkt);
-			break;
 		default:
 		default:
 			/* Type Not Supported. */
 			/* Type Not Supported. */
 			DEBUG4(printk(KERN_WARNING
 			DEBUG4(printk(KERN_WARNING
@@ -1339,44 +1397,6 @@ qla2x00_error_entry(scsi_qla_host_t *ha, sts_entry_t *pkt)
 	}
 	}
 }
 }
 
 
-/**
- * qla2x00_ms_entry() - Process a Management Server entry.
- * @ha: SCSI driver HA context
- * @index: Response queue out pointer
- */
-static void
-qla2x00_ms_entry(scsi_qla_host_t *ha, ms_iocb_entry_t *pkt)
-{
-	srb_t          *sp;
-
-	DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
-	    __func__, ha->host_no, pkt, pkt->handle1));
-
-	/* Validate handle. */
- 	if (pkt->handle1 < MAX_OUTSTANDING_COMMANDS)
- 		sp = ha->outstanding_cmds[pkt->handle1];
-	else
-		sp = NULL;
-
-	if (sp == NULL) {
-		DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",
-		    ha->host_no));
-		qla_printk(KERN_WARNING, ha, "MS entry - invalid handle\n");
-
-		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
-		return;
-	}
-
-	CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->status);
-	CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
-
-	/* Free outstanding command slot. */
-	ha->outstanding_cmds[pkt->handle1] = NULL;
-
-	qla2x00_sp_compl(ha, sp);
-}
-
-
 /**
 /**
  * qla24xx_mbx_completion() - Process mailbox command completions.
  * qla24xx_mbx_completion() - Process mailbox command completions.
  * @ha: SCSI driver HA context
  * @ha: SCSI driver HA context
@@ -1449,9 +1469,6 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha)
 		case STATUS_CONT_TYPE:
 		case STATUS_CONT_TYPE:
 			qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
 			qla2x00_status_cont_entry(ha, (sts_cont_entry_t *)pkt);
 			break;
 			break;
-		case MS_IOCB_TYPE:
-			qla24xx_ms_entry(ha, (struct ct_entry_24xx *)pkt);
-			break;
 		case VP_RPT_ID_IOCB_TYPE:
 		case VP_RPT_ID_IOCB_TYPE:
 			qla24xx_report_id_acquisition(ha,
 			qla24xx_report_id_acquisition(ha,
 			    (struct vp_rpt_id_entry_24xx *)pkt);
 			    (struct vp_rpt_id_entry_24xx *)pkt);
@@ -1533,7 +1550,6 @@ qla24xx_intr_handler(int irq, void *dev_id)
 	scsi_qla_host_t	*ha;
 	scsi_qla_host_t	*ha;
 	struct device_reg_24xx __iomem *reg;
 	struct device_reg_24xx __iomem *reg;
 	int		status;
 	int		status;
-	unsigned long	flags;
 	unsigned long	iter;
 	unsigned long	iter;
 	uint32_t	stat;
 	uint32_t	stat;
 	uint32_t	hccr;
 	uint32_t	hccr;
@@ -1549,13 +1565,19 @@ qla24xx_intr_handler(int irq, void *dev_id)
 	reg = &ha->iobase->isp24;
 	reg = &ha->iobase->isp24;
 	status = 0;
 	status = 0;
 
 
-	spin_lock_irqsave(&ha->hardware_lock, flags);
+	spin_lock(&ha->hardware_lock);
 	for (iter = 50; iter--; ) {
 	for (iter = 50; iter--; ) {
 		stat = RD_REG_DWORD(&reg->host_status);
 		stat = RD_REG_DWORD(&reg->host_status);
 		if (stat & HSRX_RISC_PAUSED) {
 		if (stat & HSRX_RISC_PAUSED) {
 			if (pci_channel_offline(ha->pdev))
 			if (pci_channel_offline(ha->pdev))
 				break;
 				break;
 
 
+			if (ha->hw_event_pause_errors == 0)
+				qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR,
+				    0, MSW(stat), LSW(stat));
+			else if (ha->hw_event_pause_errors < 0xffffffff)
+				ha->hw_event_pause_errors++;
+
 			hccr = RD_REG_DWORD(&reg->hccr);
 			hccr = RD_REG_DWORD(&reg->hccr);
 
 
 			qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
 			qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
@@ -1597,7 +1619,7 @@ qla24xx_intr_handler(int irq, void *dev_id)
 		WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
 		WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
 		RD_REG_DWORD_RELAXED(&reg->hccr);
 		RD_REG_DWORD_RELAXED(&reg->hccr);
 	}
 	}
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock(&ha->hardware_lock);
 
 
 	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
 	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
 	    (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
 	    (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
@@ -1608,66 +1630,21 @@ qla24xx_intr_handler(int irq, void *dev_id)
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
 
 
-/**
- * qla24xx_ms_entry() - Process a Management Server entry.
- * @ha: SCSI driver HA context
- * @index: Response queue out pointer
- */
-static void
-qla24xx_ms_entry(scsi_qla_host_t *ha, struct ct_entry_24xx *pkt)
-{
-	srb_t          *sp;
-
-	DEBUG3(printk("%s(%ld): pkt=%p pkthandle=%d.\n",
-	    __func__, ha->host_no, pkt, pkt->handle));
-
-	DEBUG9(printk("%s: ct pkt dump:\n", __func__));
-	DEBUG9(qla2x00_dump_buffer((void *)pkt, sizeof(struct ct_entry_24xx)));
-
-	/* Validate handle. */
- 	if (pkt->handle < MAX_OUTSTANDING_COMMANDS)
- 		sp = ha->outstanding_cmds[pkt->handle];
-	else
-		sp = NULL;
-
-	if (sp == NULL) {
-		DEBUG2(printk("scsi(%ld): MS entry - invalid handle\n",
-		    ha->host_no));
-		DEBUG10(printk("scsi(%ld): MS entry - invalid handle\n",
-		    ha->host_no));
-		qla_printk(KERN_WARNING, ha, "MS entry - invalid handle %d\n",
-		    pkt->handle);
-
-		set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags);
-		return;
-	}
-
-	CMD_COMPL_STATUS(sp->cmd) = le16_to_cpu(pkt->comp_status);
-	CMD_ENTRY_STATUS(sp->cmd) = pkt->entry_status;
-
-	/* Free outstanding command slot. */
-	ha->outstanding_cmds[pkt->handle] = NULL;
-
-	qla2x00_sp_compl(ha, sp);
-}
-
 static irqreturn_t
 static irqreturn_t
 qla24xx_msix_rsp_q(int irq, void *dev_id)
 qla24xx_msix_rsp_q(int irq, void *dev_id)
 {
 {
 	scsi_qla_host_t	*ha;
 	scsi_qla_host_t	*ha;
 	struct device_reg_24xx __iomem *reg;
 	struct device_reg_24xx __iomem *reg;
-	unsigned long flags;
 
 
 	ha = dev_id;
 	ha = dev_id;
 	reg = &ha->iobase->isp24;
 	reg = &ha->iobase->isp24;
 
 
-	spin_lock_irqsave(&ha->hardware_lock, flags);
+	spin_lock(&ha->hardware_lock);
 
 
 	qla24xx_process_response_queue(ha);
 	qla24xx_process_response_queue(ha);
-
 	WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
 	WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
 
 
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock(&ha->hardware_lock);
 
 
 	return IRQ_HANDLED;
 	return IRQ_HANDLED;
 }
 }
@@ -1678,7 +1655,6 @@ qla24xx_msix_default(int irq, void *dev_id)
 	scsi_qla_host_t	*ha;
 	scsi_qla_host_t	*ha;
 	struct device_reg_24xx __iomem *reg;
 	struct device_reg_24xx __iomem *reg;
 	int		status;
 	int		status;
-	unsigned long	flags;
 	uint32_t	stat;
 	uint32_t	stat;
 	uint32_t	hccr;
 	uint32_t	hccr;
 	uint16_t	mb[4];
 	uint16_t	mb[4];
@@ -1687,13 +1663,19 @@ qla24xx_msix_default(int irq, void *dev_id)
 	reg = &ha->iobase->isp24;
 	reg = &ha->iobase->isp24;
 	status = 0;
 	status = 0;
 
 
-	spin_lock_irqsave(&ha->hardware_lock, flags);
+	spin_lock(&ha->hardware_lock);
 	do {
 	do {
 		stat = RD_REG_DWORD(&reg->host_status);
 		stat = RD_REG_DWORD(&reg->host_status);
 		if (stat & HSRX_RISC_PAUSED) {
 		if (stat & HSRX_RISC_PAUSED) {
 			if (pci_channel_offline(ha->pdev))
 			if (pci_channel_offline(ha->pdev))
 				break;
 				break;
 
 
+			if (ha->hw_event_pause_errors == 0)
+				qla2x00_post_hwe_work(ha, HW_EVENT_PARITY_ERR,
+				    0, MSW(stat), LSW(stat));
+			else if (ha->hw_event_pause_errors < 0xffffffff)
+				ha->hw_event_pause_errors++;
+
 			hccr = RD_REG_DWORD(&reg->hccr);
 			hccr = RD_REG_DWORD(&reg->hccr);
 
 
 			qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
 			qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, "
@@ -1734,7 +1716,7 @@ qla24xx_msix_default(int irq, void *dev_id)
 		}
 		}
 		WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
 		WRT_REG_DWORD(&reg->hccr, HCCRX_CLR_RISC_INT);
 	} while (0);
 	} while (0);
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock(&ha->hardware_lock);
 
 
 	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
 	if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) &&
 	    (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
 	    (status & MBX_INTERRUPT) && ha->flags.mbox_int) {
@@ -1821,10 +1803,9 @@ qla2x00_request_irqs(scsi_qla_host_t *ha)
 {
 {
 	int ret;
 	int ret;
 	device_reg_t __iomem *reg = ha->iobase;
 	device_reg_t __iomem *reg = ha->iobase;
-	unsigned long flags;
 
 
 	/* If possible, enable MSI-X. */
 	/* If possible, enable MSI-X. */
-	if (!IS_QLA2432(ha) && !IS_QLA2532(ha))
+	if (!IS_QLA2432(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha))
 		goto skip_msix;
 		goto skip_msix;
 
 
         if (IS_QLA2432(ha) && (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX ||
         if (IS_QLA2432(ha) && (ha->chip_revision < QLA_MSIX_CHIP_REV_24XX ||
@@ -1859,7 +1840,7 @@ qla2x00_request_irqs(scsi_qla_host_t *ha)
 	    "MSI-X: Falling back-to INTa mode -- %d.\n", ret);
 	    "MSI-X: Falling back-to INTa mode -- %d.\n", ret);
 skip_msix:
 skip_msix:
 
 
-	if (!IS_QLA24XX(ha) && !IS_QLA2532(ha))
+	if (!IS_QLA24XX(ha) && !IS_QLA2532(ha) && !IS_QLA8432(ha))
 		goto skip_msi;
 		goto skip_msi;
 
 
 	ret = pci_enable_msi(ha->pdev);
 	ret = pci_enable_msi(ha->pdev);
@@ -1882,7 +1863,7 @@ skip_msi:
 clear_risc_ints:
 clear_risc_ints:
 
 
 	ha->isp_ops->disable_intrs(ha);
 	ha->isp_ops->disable_intrs(ha);
-	spin_lock_irqsave(&ha->hardware_lock, flags);
+	spin_lock_irq(&ha->hardware_lock);
 	if (IS_FWI2_CAPABLE(ha)) {
 	if (IS_FWI2_CAPABLE(ha)) {
 		WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_HOST_INT);
 		WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_HOST_INT);
 		WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_RISC_INT);
 		WRT_REG_DWORD(&reg->isp24.hccr, HCCRX_CLR_RISC_INT);
@@ -1891,7 +1872,7 @@ clear_risc_ints:
 		WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_RISC_INT);
 		WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_RISC_INT);
 		WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_HOST_INT);
 		WRT_REG_WORD(&reg->isp.hccr, HCCR_CLR_HOST_INT);
 	}
 	}
-	spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	spin_unlock_irq(&ha->hardware_lock);
 	ha->isp_ops->enable_intrs(ha);
 	ha->isp_ops->enable_intrs(ha);
 
 
 fail:
 fail:

+ 238 - 80
drivers/scsi/qla2xxx/qla_mbx.c

@@ -1,6 +1,6 @@
 /*
 /*
  * QLogic Fibre Channel HBA Driver
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2005 QLogic Corporation
+ * Copyright (c)  2003-2008 QLogic Corporation
  *
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
  */
@@ -310,7 +310,7 @@ qla2x00_load_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t risc_addr,
 	}
 	}
 
 
 	mcp->in_mb = MBX_0;
 	mcp->in_mb = MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -367,7 +367,7 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr)
 		}
 		}
 	}
 	}
 
 
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -417,7 +417,7 @@ qla2x00_get_fw_version(scsi_qla_host_t *ha, uint16_t *major, uint16_t *minor,
 	mcp->out_mb = MBX_0;
 	mcp->out_mb = MBX_0;
 	mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->flags = 0;
 	mcp->flags = 0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
 	/* Return mailbox data. */
 	/* Return mailbox data. */
@@ -466,7 +466,7 @@ qla2x00_get_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts)
 	mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
 	mcp->mb[0] = MBC_GET_FIRMWARE_OPTION;
 	mcp->out_mb = MBX_0;
 	mcp->out_mb = MBX_0;
 	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -524,7 +524,7 @@ qla2x00_set_fw_options(scsi_qla_host_t *ha, uint16_t *fwopts)
 		mcp->mb[12] = 0;	/* Undocumented, but used */
 		mcp->mb[12] = 0;	/* Undocumented, but used */
 		mcp->out_mb |= MBX_12|MBX_11|MBX_10;
 		mcp->out_mb |= MBX_12|MBX_11|MBX_10;
 	}
 	}
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -576,7 +576,7 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha)
 	mcp->mb[7] = 0x2525;
 	mcp->mb[7] = 0x2525;
 	mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -587,6 +587,14 @@ qla2x00_mbx_reg_test(scsi_qla_host_t *ha)
 		if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
 		if (mcp->mb[5] != 0xA5A5 || mcp->mb[6] != 0x5A5A ||
 		    mcp->mb[7] != 0x2525)
 		    mcp->mb[7] != 0x2525)
 			rval = QLA_FUNCTION_FAILED;
 			rval = QLA_FUNCTION_FAILED;
+		if (rval == QLA_FUNCTION_FAILED) {
+			struct device_reg_24xx __iomem *reg =
+			    &ha->iobase->isp24;
+
+			qla2xxx_hw_event_log(ha, HW_EVENT_ISP_ERR, 0,
+			    LSW(RD_REG_DWORD(&reg->hccr)),
+			    LSW(RD_REG_DWORD(&reg->istatus)));
+		}
 	}
 	}
 
 
 	if (rval != QLA_SUCCESS) {
 	if (rval != QLA_SUCCESS) {
@@ -640,7 +648,7 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr)
 		mcp->in_mb |= MBX_1;
 		mcp->in_mb |= MBX_1;
 	}
 	}
 
 
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -674,8 +682,8 @@ qla2x00_verify_checksum(scsi_qla_host_t *ha, uint32_t risc_addr)
  *	Kernel context.
  *	Kernel context.
  */
  */
 int
 int
-qla2x00_issue_iocb(scsi_qla_host_t *ha, void*  buffer, dma_addr_t phys_addr,
-    size_t size)
+qla2x00_issue_iocb_timeout(scsi_qla_host_t *ha, void *buffer,
+    dma_addr_t phys_addr, size_t size, uint32_t tov)
 {
 {
 	int		rval;
 	int		rval;
 	mbx_cmd_t	mc;
 	mbx_cmd_t	mc;
@@ -689,7 +697,7 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void*  buffer, dma_addr_t phys_addr,
 	mcp->mb[7] = LSW(MSD(phys_addr));
 	mcp->mb[7] = LSW(MSD(phys_addr));
 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->out_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_2|MBX_0;
 	mcp->in_mb = MBX_2|MBX_0;
-	mcp->tov = 30;
+	mcp->tov = tov;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -710,6 +718,14 @@ qla2x00_issue_iocb(scsi_qla_host_t *ha, void*  buffer, dma_addr_t phys_addr,
 	return rval;
 	return rval;
 }
 }
 
 
+int
+qla2x00_issue_iocb(scsi_qla_host_t *ha, void *buffer, dma_addr_t phys_addr,
+    size_t size)
+{
+	return qla2x00_issue_iocb_timeout(ha, buffer, phys_addr, size,
+	    MBX_TOV_SECONDS);
+}
+
 /*
 /*
  * qla2x00_abort_command
  * qla2x00_abort_command
  *	Abort command aborts a specified IOCB.
  *	Abort command aborts a specified IOCB.
@@ -760,7 +776,7 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp)
 	mcp->mb[6] = (uint16_t)sp->cmd->device->lun;
 	mcp->mb[6] = (uint16_t)sp->cmd->device->lun;
 	mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->out_mb = MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_0;
 	mcp->in_mb = MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -776,36 +792,20 @@ qla2x00_abort_command(scsi_qla_host_t *ha, srb_t *sp)
 	return rval;
 	return rval;
 }
 }
 
 
-#if USE_ABORT_TGT
-/*
- * qla2x00_abort_target
- *	Issue abort target mailbox command.
- *
- * Input:
- *	ha = adapter block pointer.
- *
- * Returns:
- *	qla2x00 local function return status code.
- *
- * Context:
- *	Kernel context.
- */
 int
 int
-qla2x00_abort_target(fc_port_t *fcport)
+qla2x00_abort_target(struct fc_port *fcport, unsigned int l)
 {
 {
-	int        rval;
+	int rval, rval2;
 	mbx_cmd_t  mc;
 	mbx_cmd_t  mc;
 	mbx_cmd_t  *mcp = &mc;
 	mbx_cmd_t  *mcp = &mc;
 	scsi_qla_host_t *ha;
 	scsi_qla_host_t *ha;
 
 
-	if (fcport == NULL)
-		return 0;
-
 	DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no));
 	DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no));
 
 
+	l = l;
 	ha = fcport->ha;
 	ha = fcport->ha;
 	mcp->mb[0] = MBC_ABORT_TARGET;
 	mcp->mb[0] = MBC_ABORT_TARGET;
-	mcp->out_mb = MBX_2|MBX_1|MBX_0;
+	mcp->out_mb = MBX_9|MBX_2|MBX_1|MBX_0;
 	if (HAS_EXTENDED_IDS(ha)) {
 	if (HAS_EXTENDED_IDS(ha)) {
 		mcp->mb[1] = fcport->loop_id;
 		mcp->mb[1] = fcport->loop_id;
 		mcp->mb[10] = 0;
 		mcp->mb[10] = 0;
@@ -814,27 +814,70 @@ qla2x00_abort_target(fc_port_t *fcport)
 		mcp->mb[1] = fcport->loop_id << 8;
 		mcp->mb[1] = fcport->loop_id << 8;
 	}
 	}
 	mcp->mb[2] = ha->loop_reset_delay;
 	mcp->mb[2] = ha->loop_reset_delay;
+	mcp->mb[9] = ha->vp_idx;
 
 
 	mcp->in_mb = MBX_0;
 	mcp->in_mb = MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
+	if (rval != QLA_SUCCESS) {
+		DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
+		    ha->host_no, rval));
+	}
 
 
-	/* Issue marker command. */
-	ha->marker_needed = 1;
+	/* Issue marker IOCB. */
+	rval2 = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID);
+	if (rval2 != QLA_SUCCESS) {
+		DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
+		    "(%x).\n", __func__, ha->host_no, rval2));
+	} else {
+		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
+	}
+
+	return rval;
+}
+
+int
+qla2x00_lun_reset(struct fc_port *fcport, unsigned int l)
+{
+	int rval, rval2;
+	mbx_cmd_t  mc;
+	mbx_cmd_t  *mcp = &mc;
+	scsi_qla_host_t *ha;
+
+	DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no));
+
+	ha = fcport->ha;
+	mcp->mb[0] = MBC_LUN_RESET;
+	mcp->out_mb = MBX_9|MBX_3|MBX_2|MBX_1|MBX_0;
+	if (HAS_EXTENDED_IDS(ha))
+		mcp->mb[1] = fcport->loop_id;
+	else
+		mcp->mb[1] = fcport->loop_id << 8;
+	mcp->mb[2] = l;
+	mcp->mb[3] = 0;
+	mcp->mb[9] = ha->vp_idx;
 
 
+	mcp->in_mb = MBX_0;
+	mcp->tov = MBX_TOV_SECONDS;
+	mcp->flags = 0;
+	rval = qla2x00_mailbox_command(ha, mcp);
 	if (rval != QLA_SUCCESS) {
 	if (rval != QLA_SUCCESS) {
-		DEBUG2_3_11(printk("qla2x00_abort_target(%ld): failed=%x.\n",
+		DEBUG2_3_11(printk("%s(%ld): failed=%x.\n", __func__,
 		    ha->host_no, rval));
 		    ha->host_no, rval));
+	}
+
+	/* Issue marker IOCB. */
+	rval2 = qla2x00_marker(ha, fcport->loop_id, l, MK_SYNC_ID_LUN);
+	if (rval2 != QLA_SUCCESS) {
+		DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
+		    "(%x).\n", __func__, ha->host_no, rval2));
 	} else {
 	} else {
-		/*EMPTY*/
-		DEBUG11(printk("qla2x00_abort_target(%ld): done.\n",
-		    ha->host_no));
+		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
 	}
 	}
 
 
 	return rval;
 	return rval;
 }
 }
-#endif
 
 
 /*
 /*
  * qla2x00_get_adapter_id
  * qla2x00_get_adapter_id
@@ -871,7 +914,7 @@ qla2x00_get_adapter_id(scsi_qla_host_t *ha, uint16_t *id, uint8_t *al_pa,
 	mcp->mb[9] = ha->vp_idx;
 	mcp->mb[9] = ha->vp_idx;
 	mcp->out_mb = MBX_9|MBX_0;
 	mcp->out_mb = MBX_9|MBX_0;
 	mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_9|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 	if (mcp->mb[0] == MBS_COMMAND_ERROR)
 	if (mcp->mb[0] == MBS_COMMAND_ERROR)
@@ -928,7 +971,7 @@ qla2x00_get_retry_cnt(scsi_qla_host_t *ha, uint8_t *retry_cnt, uint8_t *tov,
 	mcp->mb[0] = MBC_GET_RETRY_COUNT;
 	mcp->mb[0] = MBC_GET_RETRY_COUNT;
 	mcp->out_mb = MBX_0;
 	mcp->out_mb = MBX_0;
 	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -995,7 +1038,7 @@ qla2x00_init_firmware(scsi_qla_host_t *ha, uint16_t size)
 	mcp->in_mb = MBX_5|MBX_4|MBX_0;
 	mcp->in_mb = MBX_5|MBX_4|MBX_0;
 	mcp->buf_size = size;
 	mcp->buf_size = size;
 	mcp->flags = MBX_DMA_OUT;
 	mcp->flags = MBX_DMA_OUT;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
 	if (rval != QLA_SUCCESS) {
 	if (rval != QLA_SUCCESS) {
@@ -1173,7 +1216,7 @@ gpd_error_out:
  *	Kernel context.
  *	Kernel context.
  */
  */
 int
 int
-qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr)
+qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *states)
 {
 {
 	int rval;
 	int rval;
 	mbx_cmd_t mc;
 	mbx_cmd_t mc;
@@ -1184,13 +1227,15 @@ qla2x00_get_firmware_state(scsi_qla_host_t *ha, uint16_t *dptr)
 
 
 	mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
 	mcp->mb[0] = MBC_GET_FIRMWARE_STATE;
 	mcp->out_mb = MBX_0;
 	mcp->out_mb = MBX_0;
-	mcp->in_mb = MBX_2|MBX_1|MBX_0;
-	mcp->tov = 30;
+	mcp->in_mb = MBX_3|MBX_2|MBX_1|MBX_0;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
-	/* Return firmware state. */
-	*dptr = mcp->mb[1];
+	/* Return firmware states. */
+	states[0] = mcp->mb[1];
+	states[1] = mcp->mb[2];
+	states[2] = mcp->mb[3];
 
 
 	if (rval != QLA_SUCCESS) {
 	if (rval != QLA_SUCCESS) {
 		/*EMPTY*/
 		/*EMPTY*/
@@ -1246,7 +1291,7 @@ qla2x00_get_port_name(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t *name,
 	}
 	}
 
 
 	mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -1318,7 +1363,7 @@ qla2x00_lip_reset(scsi_qla_host_t *ha)
 		mcp->mb[3] = 0;
 		mcp->mb[3] = 0;
 	}
 	}
 	mcp->in_mb = MBX_0;
 	mcp->in_mb = MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -1743,7 +1788,7 @@ qla2x00_fabric_logout(scsi_qla_host_t *ha, uint16_t loop_id, uint8_t domain,
 	}
 	}
 
 
 	mcp->in_mb = MBX_1|MBX_0;
 	mcp->in_mb = MBX_1|MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -1791,7 +1836,7 @@ qla2x00_full_login_lip(scsi_qla_host_t *ha)
 	mcp->mb[3] = 0;
 	mcp->mb[3] = 0;
 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->out_mb = MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_0;
 	mcp->in_mb = MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -1852,7 +1897,7 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma,
 		mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
 		mcp->out_mb |= MBX_6|MBX_3|MBX_2|MBX_1;
 	}
 	}
 	mcp->in_mb = MBX_1|MBX_0;
 	mcp->in_mb = MBX_1|MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -1896,7 +1941,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt,
 	mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
 	mcp->mb[0] = MBC_GET_RESOURCE_COUNTS;
 	mcp->out_mb = MBX_0;
 	mcp->out_mb = MBX_0;
 	mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -2036,7 +2081,7 @@ qla2x00_get_link_status(scsi_qla_host_t *ha, uint16_t loop_id,
 		mcp->mb[1] = loop_id << 8;
 		mcp->mb[1] = loop_id << 8;
 		mcp->out_mb |= MBX_1;
 		mcp->out_mb |= MBX_1;
 	}
 	}
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = IOCTL_CMD;
 	mcp->flags = IOCTL_CMD;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -2082,7 +2127,7 @@ qla24xx_get_isp_stats(scsi_qla_host_t *ha, struct link_statistics *stats,
 	mcp->mb[10] = 0;
 	mcp->mb[10] = 0;
 	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
 	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_0;
 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_2|MBX_1|MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = IOCTL_CMD;
 	mcp->flags = IOCTL_CMD;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -2180,17 +2225,15 @@ struct tsk_mgmt_cmd {
 	} p;
 	} p;
 };
 };
 
 
-int
-qla24xx_abort_target(fc_port_t *fcport)
+static int
+__qla24xx_issue_tmf(char *name, uint32_t type, struct fc_port *fcport,
+    unsigned int l)
 {
 {
-	int		rval;
+	int		rval, rval2;
 	struct tsk_mgmt_cmd *tsk;
 	struct tsk_mgmt_cmd *tsk;
 	dma_addr_t	tsk_dma;
 	dma_addr_t	tsk_dma;
 	scsi_qla_host_t *ha, *pha;
 	scsi_qla_host_t *ha, *pha;
 
 
-	if (fcport == NULL)
-		return 0;
-
 	DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no));
 	DEBUG11(printk("%s(%ld): entered.\n", __func__, fcport->ha->host_no));
 
 
 	ha = fcport->ha;
 	ha = fcport->ha;
@@ -2207,47 +2250,61 @@ qla24xx_abort_target(fc_port_t *fcport)
 	tsk->p.tsk.entry_count = 1;
 	tsk->p.tsk.entry_count = 1;
 	tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
 	tsk->p.tsk.nport_handle = cpu_to_le16(fcport->loop_id);
 	tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
 	tsk->p.tsk.timeout = cpu_to_le16(ha->r_a_tov / 10 * 2);
-	tsk->p.tsk.control_flags = __constant_cpu_to_le32(TCF_TARGET_RESET);
+	tsk->p.tsk.control_flags = cpu_to_le32(type);
 	tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
 	tsk->p.tsk.port_id[0] = fcport->d_id.b.al_pa;
 	tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
 	tsk->p.tsk.port_id[1] = fcport->d_id.b.area;
 	tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
 	tsk->p.tsk.port_id[2] = fcport->d_id.b.domain;
 	tsk->p.tsk.vp_index = fcport->vp_idx;
 	tsk->p.tsk.vp_index = fcport->vp_idx;
+	if (type == TCF_LUN_RESET) {
+		int_to_scsilun(l, &tsk->p.tsk.lun);
+		host_to_fcp_swap((uint8_t *)&tsk->p.tsk.lun,
+		    sizeof(tsk->p.tsk.lun));
+	}
 
 
 	rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0);
 	rval = qla2x00_issue_iocb(ha, tsk, tsk_dma, 0);
 	if (rval != QLA_SUCCESS) {
 	if (rval != QLA_SUCCESS) {
-		DEBUG2_3_11(printk("%s(%ld): failed to issue Target Reset IOCB "
-		    "(%x).\n", __func__, ha->host_no, rval));
-		goto atarget_done;
+		DEBUG2_3_11(printk("%s(%ld): failed to issue %s Reset IOCB "
+		    "(%x).\n", __func__, ha->host_no, name, rval));
 	} else if (tsk->p.sts.entry_status != 0) {
 	} else if (tsk->p.sts.entry_status != 0) {
 		DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
 		DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
 		    "-- error status (%x).\n", __func__, ha->host_no,
 		    "-- error status (%x).\n", __func__, ha->host_no,
 		    tsk->p.sts.entry_status));
 		    tsk->p.sts.entry_status));
 		rval = QLA_FUNCTION_FAILED;
 		rval = QLA_FUNCTION_FAILED;
-		goto atarget_done;
 	} else if (tsk->p.sts.comp_status !=
 	} else if (tsk->p.sts.comp_status !=
 	    __constant_cpu_to_le16(CS_COMPLETE)) {
 	    __constant_cpu_to_le16(CS_COMPLETE)) {
 		DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
 		DEBUG2_3_11(printk("%s(%ld): failed to complete IOCB "
 		    "-- completion status (%x).\n", __func__,
 		    "-- completion status (%x).\n", __func__,
 		    ha->host_no, le16_to_cpu(tsk->p.sts.comp_status)));
 		    ha->host_no, le16_to_cpu(tsk->p.sts.comp_status)));
 		rval = QLA_FUNCTION_FAILED;
 		rval = QLA_FUNCTION_FAILED;
-		goto atarget_done;
 	}
 	}
 
 
 	/* Issue marker IOCB. */
 	/* Issue marker IOCB. */
-	rval = qla2x00_marker(ha, fcport->loop_id, 0, MK_SYNC_ID);
-	if (rval != QLA_SUCCESS) {
+	rval2 = qla2x00_marker(ha, fcport->loop_id, l,
+	    type == TCF_LUN_RESET ? MK_SYNC_ID_LUN: MK_SYNC_ID);
+	if (rval2 != QLA_SUCCESS) {
 		DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
 		DEBUG2_3_11(printk("%s(%ld): failed to issue Marker IOCB "
-		    "(%x).\n", __func__, ha->host_no, rval));
+		    "(%x).\n", __func__, ha->host_no, rval2));
 	} else {
 	} else {
 		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
 		DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no));
 	}
 	}
 
 
-atarget_done:
 	dma_pool_free(pha->s_dma_pool, tsk, tsk_dma);
 	dma_pool_free(pha->s_dma_pool, tsk, tsk_dma);
 
 
 	return rval;
 	return rval;
 }
 }
 
 
+int
+qla24xx_abort_target(struct fc_port *fcport, unsigned int l)
+{
+	return __qla24xx_issue_tmf("Target", TCF_TARGET_RESET, fcport, l);
+}
+
+int
+qla24xx_lun_reset(struct fc_port *fcport, unsigned int l)
+{
+	return __qla24xx_issue_tmf("Lun", TCF_LUN_RESET, fcport, l);
+}
+
 #if 0
 #if 0
 
 
 int
 int
@@ -2304,7 +2361,7 @@ qla2x00_set_serdes_params(scsi_qla_host_t *ha, uint16_t sw_em_1g,
 	mcp->mb[4] = sw_em_4g | BIT_15;
 	mcp->mb[4] = sw_em_4g | BIT_15;
 	mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->out_mb = MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_0;
 	mcp->in_mb = MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -2372,7 +2429,7 @@ qla2x00_enable_eft_trace(scsi_qla_host_t *ha, dma_addr_t eft_dma,
 	mcp->mb[7] = TC_AEN_DISABLE;
 	mcp->mb[7] = TC_AEN_DISABLE;
 	mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->out_mb = MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_1|MBX_0;
 	mcp->in_mb = MBX_1|MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 	if (rval != QLA_SUCCESS) {
 	if (rval != QLA_SUCCESS) {
@@ -2401,7 +2458,7 @@ qla2x00_disable_eft_trace(scsi_qla_host_t *ha)
 	mcp->mb[1] = TC_EFT_DISABLE;
 	mcp->mb[1] = TC_EFT_DISABLE;
 	mcp->out_mb = MBX_1|MBX_0;
 	mcp->out_mb = MBX_1|MBX_0;
 	mcp->in_mb = MBX_1|MBX_0;
 	mcp->in_mb = MBX_1|MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 	if (rval != QLA_SUCCESS) {
 	if (rval != QLA_SUCCESS) {
@@ -2441,7 +2498,7 @@ qla2x00_enable_fce_trace(scsi_qla_host_t *ha, dma_addr_t fce_dma,
 	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
 	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
 	    MBX_1|MBX_0;
 	    MBX_1|MBX_0;
 	mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 	if (rval != QLA_SUCCESS) {
 	if (rval != QLA_SUCCESS) {
@@ -2477,7 +2534,7 @@ qla2x00_disable_fce_trace(scsi_qla_host_t *ha, uint64_t *wr, uint64_t *rd)
 	mcp->out_mb = MBX_2|MBX_1|MBX_0;
 	mcp->out_mb = MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
 	mcp->in_mb = MBX_9|MBX_8|MBX_7|MBX_6|MBX_5|MBX_4|MBX_3|MBX_2|
 	    MBX_1|MBX_0;
 	    MBX_1|MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 	if (rval != QLA_SUCCESS) {
 	if (rval != QLA_SUCCESS) {
@@ -2525,7 +2582,7 @@ qla2x00_read_sfp(scsi_qla_host_t *ha, dma_addr_t sfp_dma, uint16_t addr,
 	mcp->mb[10] = 0;
 	mcp->mb[10] = 0;
 	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->out_mb = MBX_10|MBX_9|MBX_8|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_0;
 	mcp->in_mb = MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -2559,7 +2616,7 @@ qla2x00_set_idma_speed(scsi_qla_host_t *ha, uint16_t loop_id,
 	mcp->mb[4] = mcp->mb[5] = 0;
 	mcp->mb[4] = mcp->mb[5] = 0;
 	mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->out_mb = MBX_5|MBX_4|MBX_3|MBX_2|MBX_1|MBX_0;
 	mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
 	mcp->in_mb = MBX_5|MBX_4|MBX_3|MBX_1|MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -2877,7 +2934,7 @@ qla2x00_dump_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t addr,
 	}
 	}
 
 
 	mcp->in_mb = MBX_0;
 	mcp->in_mb = MBX_0;
-	mcp->tov = 30;
+	mcp->tov = MBX_TOV_SECONDS;
 	mcp->flags = 0;
 	mcp->flags = 0;
 	rval = qla2x00_mailbox_command(ha, mcp);
 	rval = qla2x00_mailbox_command(ha, mcp);
 
 
@@ -2890,3 +2947,104 @@ qla2x00_dump_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t addr,
 
 
 	return rval;
 	return rval;
 }
 }
+
+/* 84XX Support **************************************************************/
+
+struct cs84xx_mgmt_cmd {
+	union {
+		struct verify_chip_entry_84xx req;
+		struct verify_chip_rsp_84xx rsp;
+	} p;
+};
+
+int
+qla84xx_verify_chip(struct scsi_qla_host *ha, uint16_t *status)
+{
+	int rval, retry;
+	struct cs84xx_mgmt_cmd *mn;
+	dma_addr_t mn_dma;
+	uint16_t options;
+	unsigned long flags;
+
+	DEBUG16(printk("%s(%ld): entered.\n", __func__, ha->host_no));
+
+	mn = dma_pool_alloc(ha->s_dma_pool, GFP_KERNEL, &mn_dma);
+	if (mn == NULL) {
+		DEBUG2_3(printk("%s(%ld): failed to allocate Verify ISP84XX "
+		    "IOCB.\n", __func__, ha->host_no));
+		return QLA_MEMORY_ALLOC_FAILED;
+	}
+
+	/* Force Update? */
+	options = ha->cs84xx->fw_update ? VCO_FORCE_UPDATE : 0;
+	/* Diagnostic firmware? */
+	/* options |= MENLO_DIAG_FW; */
+	/* We update the firmware with only one data sequence. */
+	options |= VCO_END_OF_DATA;
+
+	retry = 0;
+	do {
+		memset(mn, 0, sizeof(*mn));
+		mn->p.req.entry_type = VERIFY_CHIP_IOCB_TYPE;
+		mn->p.req.entry_count = 1;
+		mn->p.req.options = cpu_to_le16(options);
+
+		DEBUG16(printk("%s(%ld): Dump of Verify Request.\n", __func__,
+		    ha->host_no));
+		DEBUG16(qla2x00_dump_buffer((uint8_t *)mn,
+		    sizeof(*mn)));
+
+		rval = qla2x00_issue_iocb_timeout(ha, mn, mn_dma, 0, 120);
+		if (rval != QLA_SUCCESS) {
+			DEBUG2_16(printk("%s(%ld): failed to issue Verify "
+			    "IOCB (%x).\n", __func__, ha->host_no, rval));
+			goto verify_done;
+		}
+
+		DEBUG16(printk("%s(%ld): Dump of Verify Response.\n", __func__,
+		    ha->host_no));
+		DEBUG16(qla2x00_dump_buffer((uint8_t *)mn,
+		    sizeof(*mn)));
+
+		status[0] = le16_to_cpu(mn->p.rsp.comp_status);
+		status[1] = status[0] == CS_VCS_CHIP_FAILURE ?
+		    le16_to_cpu(mn->p.rsp.failure_code) : 0;
+		DEBUG2_16(printk("%s(%ld): cs=%x fc=%x\n", __func__,
+		    ha->host_no, status[0], status[1]));
+
+		if (status[0] != CS_COMPLETE) {
+			rval = QLA_FUNCTION_FAILED;
+			if (!(options & VCO_DONT_UPDATE_FW)) {
+				DEBUG2_16(printk("%s(%ld): Firmware update "
+				    "failed. Retrying without update "
+				    "firmware.\n", __func__, ha->host_no));
+				options |= VCO_DONT_UPDATE_FW;
+				options &= ~VCO_FORCE_UPDATE;
+				retry = 1;
+			}
+		} else {
+			DEBUG2_16(printk("%s(%ld): firmware updated to %x.\n",
+			    __func__, ha->host_no,
+			    le32_to_cpu(mn->p.rsp.fw_ver)));
+
+			/* NOTE: we only update OP firmware. */
+			spin_lock_irqsave(&ha->cs84xx->access_lock, flags);
+			ha->cs84xx->op_fw_version =
+			    le32_to_cpu(mn->p.rsp.fw_ver);
+			spin_unlock_irqrestore(&ha->cs84xx->access_lock,
+			    flags);
+		}
+	} while (retry);
+
+verify_done:
+	dma_pool_free(ha->s_dma_pool, mn, mn_dma);
+
+	if (rval != QLA_SUCCESS) {
+		DEBUG2_16(printk("%s(%ld): failed=%x.\n", __func__,
+		    ha->host_no, rval));
+	} else {
+		DEBUG16(printk("%s(%ld): done.\n", __func__, ha->host_no));
+	}
+
+	return rval;
+}

+ 12 - 18
drivers/scsi/qla2xxx/qla_mid.c

@@ -1,20 +1,8 @@
 /*
 /*
- *                  QLOGIC LINUX SOFTWARE
- *
- * QLogic ISP2x00 device driver for Linux 2.6.x
- * Copyright (C) 2003-2005 QLogic Corporation
- * (www.qlogic.com)
- *
- * This program is free software; you can redistribute it and/or modify it
- * under the terms of the GNU General Public License as published by the
- * Free Software Foundation; either version 2, or (at your option) any
- * later version.
- *
- * This program is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * General Public License for more details.
+ * QLogic Fibre Channel HBA Driver
+ * Copyright (c)  2003-2008 QLogic Corporation
  *
  *
+ * See LICENSE.qla2xxx for copyright and licensing details.
  */
  */
 #include "qla_def.h"
 #include "qla_def.h"
 
 
@@ -28,8 +16,6 @@
 #include <scsi/scsicam.h>
 #include <scsi/scsicam.h>
 #include <linux/delay.h>
 #include <linux/delay.h>
 
 
-void qla2x00_vp_stop_timer(scsi_qla_host_t *);
-
 void
 void
 qla2x00_vp_stop_timer(scsi_qla_host_t *vha)
 qla2x00_vp_stop_timer(scsi_qla_host_t *vha)
 {
 {
@@ -268,9 +254,17 @@ qla2x00_vp_abort_isp(scsi_qla_host_t *vha)
 static int
 static int
 qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
 qla2x00_do_dpc_vp(scsi_qla_host_t *vha)
 {
 {
+	scsi_qla_host_t *ha = vha->parent;
+
 	if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) {
 	if (test_and_clear_bit(VP_IDX_ACQUIRED, &vha->vp_flags)) {
 		/* VP acquired. complete port configuration */
 		/* VP acquired. complete port configuration */
-		qla24xx_configure_vp(vha);
+		if (atomic_read(&ha->loop_state) == LOOP_READY) {
+			qla24xx_configure_vp(vha);
+		} else {
+			set_bit(VP_IDX_ACQUIRED, &vha->vp_flags);
+			set_bit(VP_DPC_NEEDED, &ha->dpc_flags);
+		}
+
 		return 0;
 		return 0;
 	}
 	}
 
 

+ 217 - 226
drivers/scsi/qla2xxx/qla_os.c

@@ -1,6 +1,6 @@
 /*
 /*
  * QLogic Fibre Channel HBA Driver
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2005 QLogic Corporation
+ * Copyright (c)  2003-2008 QLogic Corporation
  *
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
  */
@@ -26,9 +26,6 @@ char qla2x00_version_str[40];
  */
  */
 static struct kmem_cache *srb_cachep;
 static struct kmem_cache *srb_cachep;
 
 
-/*
- * Ioctl related information.
- */
 int num_hosts;
 int num_hosts;
 int ql2xlogintimeout = 20;
 int ql2xlogintimeout = 20;
 module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR);
 module_param(ql2xlogintimeout, int, S_IRUGO|S_IRUSR);
@@ -103,9 +100,9 @@ static int qla24xx_queuecommand(struct scsi_cmnd *cmd,
 		void (*fn)(struct scsi_cmnd *));
 		void (*fn)(struct scsi_cmnd *));
 static int qla2xxx_eh_abort(struct scsi_cmnd *);
 static int qla2xxx_eh_abort(struct scsi_cmnd *);
 static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
 static int qla2xxx_eh_device_reset(struct scsi_cmnd *);
+static int qla2xxx_eh_target_reset(struct scsi_cmnd *);
 static int qla2xxx_eh_bus_reset(struct scsi_cmnd *);
 static int qla2xxx_eh_bus_reset(struct scsi_cmnd *);
 static int qla2xxx_eh_host_reset(struct scsi_cmnd *);
 static int qla2xxx_eh_host_reset(struct scsi_cmnd *);
-static int qla2x00_device_reset(scsi_qla_host_t *, fc_port_t *);
 
 
 static int qla2x00_change_queue_depth(struct scsi_device *, int);
 static int qla2x00_change_queue_depth(struct scsi_device *, int);
 static int qla2x00_change_queue_type(struct scsi_device *, int);
 static int qla2x00_change_queue_type(struct scsi_device *, int);
@@ -117,6 +114,7 @@ static struct scsi_host_template qla2x00_driver_template = {
 
 
 	.eh_abort_handler	= qla2xxx_eh_abort,
 	.eh_abort_handler	= qla2xxx_eh_abort,
 	.eh_device_reset_handler = qla2xxx_eh_device_reset,
 	.eh_device_reset_handler = qla2xxx_eh_device_reset,
+	.eh_target_reset_handler = qla2xxx_eh_target_reset,
 	.eh_bus_reset_handler	= qla2xxx_eh_bus_reset,
 	.eh_bus_reset_handler	= qla2xxx_eh_bus_reset,
 	.eh_host_reset_handler	= qla2xxx_eh_host_reset,
 	.eh_host_reset_handler	= qla2xxx_eh_host_reset,
 
 
@@ -148,6 +146,7 @@ struct scsi_host_template qla24xx_driver_template = {
 
 
 	.eh_abort_handler	= qla2xxx_eh_abort,
 	.eh_abort_handler	= qla2xxx_eh_abort,
 	.eh_device_reset_handler = qla2xxx_eh_device_reset,
 	.eh_device_reset_handler = qla2xxx_eh_device_reset,
+	.eh_target_reset_handler = qla2xxx_eh_target_reset,
 	.eh_bus_reset_handler	= qla2xxx_eh_bus_reset,
 	.eh_bus_reset_handler	= qla2xxx_eh_bus_reset,
 	.eh_host_reset_handler	= qla2xxx_eh_host_reset,
 	.eh_host_reset_handler	= qla2xxx_eh_host_reset,
 
 
@@ -253,9 +252,9 @@ qla24xx_pci_info_str(struct scsi_qla_host *ha, char *str)
 
 
 		strcpy(str, "PCIe (");
 		strcpy(str, "PCIe (");
 		if (lspeed == 1)
 		if (lspeed == 1)
-			strcat(str, "2.5Gb/s ");
+			strcat(str, "2.5GT/s ");
 		else if (lspeed == 2)
 		else if (lspeed == 2)
-			strcat(str, "5.0Gb/s ");
+			strcat(str, "5.0GT/s ");
 		else
 		else
 			strcat(str, "<unknown> ");
 			strcat(str, "<unknown> ");
 		snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth);
 		snprintf(lwstr, sizeof(lwstr), "x%d)", lwidth);
@@ -340,6 +339,8 @@ qla24xx_fw_version_str(struct scsi_qla_host *ha, char *str)
 		strcat(str, "[T10 CRC] ");
 		strcat(str, "[T10 CRC] ");
 	if (ha->fw_attributes & BIT_5)
 	if (ha->fw_attributes & BIT_5)
 		strcat(str, "[VI] ");
 		strcat(str, "[VI] ");
+	if (ha->fw_attributes & BIT_10)
+		strcat(str, "[84XX] ");
 	if (ha->fw_attributes & BIT_13)
 	if (ha->fw_attributes & BIT_13)
 		strcat(str, "[Experimental]");
 		strcat(str, "[Experimental]");
 	return str;
 	return str;
@@ -570,8 +571,6 @@ qla2x00_wait_for_hba_online(scsi_qla_host_t *ha)
 	else
 	else
 		return_status = QLA_FUNCTION_FAILED;
 		return_status = QLA_FUNCTION_FAILED;
 
 
-	DEBUG2(printk("%s return_status=%d\n",__func__,return_status));
-
 	return (return_status);
 	return (return_status);
 }
 }
 
 
@@ -685,7 +684,6 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 
 
 		DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n",
 		DEBUG2(printk("%s(%ld): aborting sp %p from RISC. pid=%ld.\n",
 		    __func__, ha->host_no, sp, serial));
 		    __func__, ha->host_no, sp, serial));
-		DEBUG3(qla2x00_print_scsi_cmd(cmd));
 
 
 		spin_unlock_irqrestore(&pha->hardware_lock, flags);
 		spin_unlock_irqrestore(&pha->hardware_lock, flags);
 		if (ha->isp_ops->abort_command(ha, sp)) {
 		if (ha->isp_ops->abort_command(ha, sp)) {
@@ -719,190 +717,122 @@ qla2xxx_eh_abort(struct scsi_cmnd *cmd)
 	return ret;
 	return ret;
 }
 }
 
 
-/**************************************************************************
-* qla2x00_eh_wait_for_pending_target_commands
-*
-* Description:
-*    Waits for all the commands to come back from the specified target.
-*
-* Input:
-*    ha - pointer to scsi_qla_host structure.
-*    t  - target
-* Returns:
-*    Either SUCCESS or FAILED.
-*
-* Note:
-**************************************************************************/
+enum nexus_wait_type {
+	WAIT_HOST = 0,
+	WAIT_TARGET,
+	WAIT_LUN,
+};
+
 static int
 static int
-qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t)
+qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha, unsigned int t,
+    unsigned int l, enum nexus_wait_type type)
 {
 {
-	int	cnt;
-	int	status;
-	srb_t		*sp;
-	struct scsi_cmnd *cmd;
+	int cnt, match, status;
+	srb_t *sp;
 	unsigned long flags;
 	unsigned long flags;
 	scsi_qla_host_t *pha = to_qla_parent(ha);
 	scsi_qla_host_t *pha = to_qla_parent(ha);
 
 
-	status = 0;
-
-	/*
-	 * Waiting for all commands for the designated target in the active
-	 * array
-	 */
-	for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
-		spin_lock_irqsave(&pha->hardware_lock, flags);
+	status = QLA_SUCCESS;
+	spin_lock_irqsave(&pha->hardware_lock, flags);
+	for (cnt = 1; status == QLA_SUCCESS && cnt < MAX_OUTSTANDING_COMMANDS;
+	    cnt++) {
 		sp = pha->outstanding_cmds[cnt];
 		sp = pha->outstanding_cmds[cnt];
-		if (sp) {
-			cmd = sp->cmd;
-			spin_unlock_irqrestore(&pha->hardware_lock, flags);
-			if (cmd->device->id == t &&
-			    ha->vp_idx == sp->ha->vp_idx) {
-				if (!qla2x00_eh_wait_on_command(ha, cmd)) {
-					status = 1;
-					break;
-				}
-			}
-		} else {
-			spin_unlock_irqrestore(&pha->hardware_lock, flags);
+		if (!sp)
+			continue;
+		if (ha->vp_idx != sp->ha->vp_idx)
+			continue;
+		match = 0;
+		switch (type) {
+		case WAIT_HOST:
+			match = 1;
+			break;
+		case WAIT_TARGET:
+			match = sp->cmd->device->id == t;
+			break;
+		case WAIT_LUN:
+			match = (sp->cmd->device->id == t &&
+			    sp->cmd->device->lun == l);
+			break;
 		}
 		}
+		if (!match)
+			continue;
+
+		spin_unlock_irqrestore(&pha->hardware_lock, flags);
+		status = qla2x00_eh_wait_on_command(ha, sp->cmd);
+		spin_lock_irqsave(&pha->hardware_lock, flags);
 	}
 	}
-	return (status);
+	spin_unlock_irqrestore(&pha->hardware_lock, flags);
+
+	return status;
 }
 }
 
 
+static char *reset_errors[] = {
+	"HBA not online",
+	"HBA not ready",
+	"Task management failed",
+	"Waiting for command completions",
+};
 
 
-/**************************************************************************
-* qla2xxx_eh_device_reset
-*
-* Description:
-*    The device reset function will reset the target and abort any
-*    executing commands.
-*
-*    NOTE: The use of SP is undefined within this context.  Do *NOT*
-*          attempt to use this value, even if you determine it is
-*          non-null.
-*
-* Input:
-*    cmd = Linux SCSI command packet of the command that cause the
-*          bus device reset.
-*
-* Returns:
-*    SUCCESS/FAILURE (defined as macro in scsi.h).
-*
-**************************************************************************/
 static int
 static int
-qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
+__qla2xxx_eh_generic_reset(char *name, enum nexus_wait_type type,
+    struct scsi_cmnd *cmd, int (*do_reset)(struct fc_port *, unsigned int))
 {
 {
 	scsi_qla_host_t *ha = shost_priv(cmd->device->host);
 	scsi_qla_host_t *ha = shost_priv(cmd->device->host);
 	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
 	fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata;
-	int ret = FAILED;
-	unsigned int id, lun;
-	unsigned long serial;
+	int err;
 
 
 	qla2x00_block_error_handler(cmd);
 	qla2x00_block_error_handler(cmd);
 
 
-	id = cmd->device->id;
-	lun = cmd->device->lun;
-	serial = cmd->serial_number;
-
 	if (!fcport)
 	if (!fcport)
-		return ret;
+		return FAILED;
 
 
-	qla_printk(KERN_INFO, ha,
-	    "scsi(%ld:%d:%d): DEVICE RESET ISSUED.\n", ha->host_no, id, lun);
+	qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET ISSUED.\n",
+	    ha->host_no, cmd->device->id, cmd->device->lun, name);
 
 
+	err = 0;
 	if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS)
 	if (qla2x00_wait_for_hba_online(ha) != QLA_SUCCESS)
-		goto eh_dev_reset_done;
-
-	if (qla2x00_wait_for_loop_ready(ha) == QLA_SUCCESS) {
-		if (qla2x00_device_reset(ha, fcport) == 0)
-			ret = SUCCESS;
-
-#if defined(LOGOUT_AFTER_DEVICE_RESET)
-		if (ret == SUCCESS) {
-			if (fcport->flags & FC_FABRIC_DEVICE) {
-				ha->isp_ops->fabric_logout(ha, fcport->loop_id);
-				qla2x00_mark_device_lost(ha, fcport, 0, 0);
-			}
-		}
-#endif
-	} else {
-		DEBUG2(printk(KERN_INFO
-		    "%s failed: loop not ready\n",__func__));
-	}
-
-	if (ret == FAILED) {
-		DEBUG3(printk("%s(%ld): device reset failed\n",
-		    __func__, ha->host_no));
-		qla_printk(KERN_INFO, ha, "%s: device reset failed\n",
-		    __func__);
+		goto eh_reset_failed;
+	err = 1;
+	if (qla2x00_wait_for_loop_ready(ha) != QLA_SUCCESS)
+		goto eh_reset_failed;
+	err = 2;
+	if (do_reset(fcport, cmd->device->lun) != QLA_SUCCESS)
+		goto eh_reset_failed;
+	err = 3;
+	if (qla2x00_eh_wait_for_pending_commands(ha, cmd->device->id,
+	    cmd->device->lun, type) != QLA_SUCCESS)
+		goto eh_reset_failed;
+
+	qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET SUCCEEDED.\n",
+	    ha->host_no, cmd->device->id, cmd->device->lun, name);
+
+	return SUCCESS;
+
+ eh_reset_failed:
+	qla_printk(KERN_INFO, ha, "scsi(%ld:%d:%d): %s RESET FAILED: %s.\n",
+	    ha->host_no, cmd->device->id, cmd->device->lun, name,
+	    reset_errors[err]);
+	return FAILED;
+}
 
 
-		goto eh_dev_reset_done;
-	}
+static int
+qla2xxx_eh_device_reset(struct scsi_cmnd *cmd)
+{
+	scsi_qla_host_t *ha = shost_priv(cmd->device->host);
 
 
-	/* Flush outstanding commands. */
-	if (qla2x00_eh_wait_for_pending_target_commands(ha, id))
-		ret = FAILED;
-	if (ret == FAILED) {
-		DEBUG3(printk("%s(%ld): failed while waiting for commands\n",
-		    __func__, ha->host_no));
-		qla_printk(KERN_INFO, ha,
-		    "%s: failed while waiting for commands\n", __func__);
-	} else
-		qla_printk(KERN_INFO, ha,
-		    "scsi(%ld:%d:%d): DEVICE RESET SUCCEEDED.\n", ha->host_no,
-		    id, lun);
- eh_dev_reset_done:
-	return ret;
+	return __qla2xxx_eh_generic_reset("DEVICE", WAIT_LUN, cmd,
+	    ha->isp_ops->lun_reset);
 }
 }
 
 
-/**************************************************************************
-* qla2x00_eh_wait_for_pending_commands
-*
-* Description:
-*    Waits for all the commands to come back from the specified host.
-*
-* Input:
-*    ha - pointer to scsi_qla_host structure.
-*
-* Returns:
-*    1 : SUCCESS
-*    0 : FAILED
-*
-* Note:
-**************************************************************************/
 static int
 static int
-qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha)
+qla2xxx_eh_target_reset(struct scsi_cmnd *cmd)
 {
 {
-	int	cnt;
-	int	status;
-	srb_t		*sp;
-	struct scsi_cmnd *cmd;
-	unsigned long flags;
-
-	status = 1;
+	scsi_qla_host_t *ha = shost_priv(cmd->device->host);
 
 
-	/*
-	 * Waiting for all commands for the designated target in the active
-	 * array
-	 */
-	for (cnt = 1; cnt < MAX_OUTSTANDING_COMMANDS; cnt++) {
-		spin_lock_irqsave(&ha->hardware_lock, flags);
-		sp = ha->outstanding_cmds[cnt];
-		if (sp) {
-			cmd = sp->cmd;
-			spin_unlock_irqrestore(&ha->hardware_lock, flags);
-			status = qla2x00_eh_wait_on_command(ha, cmd);
-			if (status == 0)
-				break;
-		}
-		else {
-			spin_unlock_irqrestore(&ha->hardware_lock, flags);
-		}
-	}
-	return (status);
+	return __qla2xxx_eh_generic_reset("TARGET", WAIT_TARGET, cmd,
+	    ha->isp_ops->target_reset);
 }
 }
 
 
-
 /**************************************************************************
 /**************************************************************************
 * qla2xxx_eh_bus_reset
 * qla2xxx_eh_bus_reset
 *
 *
@@ -953,7 +883,8 @@ qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd)
 		goto eh_bus_reset_done;
 		goto eh_bus_reset_done;
 
 
 	/* Flush outstanding commands. */
 	/* Flush outstanding commands. */
-	if (!qla2x00_eh_wait_for_pending_commands(pha))
+	if (qla2x00_eh_wait_for_pending_commands(pha, 0, 0, WAIT_HOST) !=
+	    QLA_SUCCESS)
 		ret = FAILED;
 		ret = FAILED;
 
 
 eh_bus_reset_done:
 eh_bus_reset_done:
@@ -1024,7 +955,8 @@ qla2xxx_eh_host_reset(struct scsi_cmnd *cmd)
 	clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags);
 	clear_bit(ABORT_ISP_ACTIVE, &pha->dpc_flags);
 
 
 	/* Waiting for our command in done_queue to be returned to OS.*/
 	/* Waiting for our command in done_queue to be returned to OS.*/
-	if (qla2x00_eh_wait_for_pending_commands(pha))
+	if (qla2x00_eh_wait_for_pending_commands(pha, 0, 0, WAIT_HOST) ==
+	    QLA_SUCCESS)
 		ret = SUCCESS;
 		ret = SUCCESS;
 
 
 	if (ha->parent)
 	if (ha->parent)
@@ -1080,7 +1012,7 @@ qla2x00_loop_reset(scsi_qla_host_t *ha)
 			if (fcport->port_type != FCT_TARGET)
 			if (fcport->port_type != FCT_TARGET)
 				continue;
 				continue;
 
 
-			ret = qla2x00_device_reset(ha, fcport);
+			ret = ha->isp_ops->target_reset(fcport, 0);
 			if (ret != QLA_SUCCESS) {
 			if (ret != QLA_SUCCESS) {
 				DEBUG2_3(printk("%s(%ld): bus_reset failed: "
 				DEBUG2_3(printk("%s(%ld): bus_reset failed: "
 				    "target_reset=%d d_id=%x.\n", __func__,
 				    "target_reset=%d d_id=%x.\n", __func__,
@@ -1095,26 +1027,6 @@ qla2x00_loop_reset(scsi_qla_host_t *ha)
 	return QLA_SUCCESS;
 	return QLA_SUCCESS;
 }
 }
 
 
-/*
- * qla2x00_device_reset
- *	Issue bus device reset message to the target.
- *
- * Input:
- *	ha = adapter block pointer.
- *	t = SCSI ID.
- *	TARGET_QUEUE_LOCK must be released.
- *	ADAPTER_STATE_LOCK must be released.
- *
- * Context:
- *	Kernel context.
- */
-static int
-qla2x00_device_reset(scsi_qla_host_t *ha, fc_port_t *reset_fcport)
-{
-	/* Abort Target command will clear Reservation */
-	return ha->isp_ops->abort_target(reset_fcport);
-}
-
 void
 void
 qla2x00_abort_all_cmds(scsi_qla_host_t *ha, int res)
 qla2x00_abort_all_cmds(scsi_qla_host_t *ha, int res)
 {
 {
@@ -1292,7 +1204,8 @@ static struct isp_operations qla2100_isp_ops = {
 	.enable_intrs		= qla2x00_enable_intrs,
 	.enable_intrs		= qla2x00_enable_intrs,
 	.disable_intrs		= qla2x00_disable_intrs,
 	.disable_intrs		= qla2x00_disable_intrs,
 	.abort_command		= qla2x00_abort_command,
 	.abort_command		= qla2x00_abort_command,
-	.abort_target		= qla2x00_abort_target,
+	.target_reset		= qla2x00_abort_target,
+	.lun_reset		= qla2x00_lun_reset,
 	.fabric_login		= qla2x00_login_fabric,
 	.fabric_login		= qla2x00_login_fabric,
 	.fabric_logout		= qla2x00_fabric_logout,
 	.fabric_logout		= qla2x00_fabric_logout,
 	.calc_req_entries	= qla2x00_calc_iocbs_32,
 	.calc_req_entries	= qla2x00_calc_iocbs_32,
@@ -1325,7 +1238,8 @@ static struct isp_operations qla2300_isp_ops = {
 	.enable_intrs		= qla2x00_enable_intrs,
 	.enable_intrs		= qla2x00_enable_intrs,
 	.disable_intrs		= qla2x00_disable_intrs,
 	.disable_intrs		= qla2x00_disable_intrs,
 	.abort_command		= qla2x00_abort_command,
 	.abort_command		= qla2x00_abort_command,
-	.abort_target		= qla2x00_abort_target,
+	.target_reset		= qla2x00_abort_target,
+	.lun_reset		= qla2x00_lun_reset,
 	.fabric_login		= qla2x00_login_fabric,
 	.fabric_login		= qla2x00_login_fabric,
 	.fabric_logout		= qla2x00_fabric_logout,
 	.fabric_logout		= qla2x00_fabric_logout,
 	.calc_req_entries	= qla2x00_calc_iocbs_32,
 	.calc_req_entries	= qla2x00_calc_iocbs_32,
@@ -1358,7 +1272,8 @@ static struct isp_operations qla24xx_isp_ops = {
 	.enable_intrs		= qla24xx_enable_intrs,
 	.enable_intrs		= qla24xx_enable_intrs,
 	.disable_intrs		= qla24xx_disable_intrs,
 	.disable_intrs		= qla24xx_disable_intrs,
 	.abort_command		= qla24xx_abort_command,
 	.abort_command		= qla24xx_abort_command,
-	.abort_target		= qla24xx_abort_target,
+	.target_reset		= qla24xx_abort_target,
+	.lun_reset		= qla24xx_lun_reset,
 	.fabric_login		= qla24xx_login_fabric,
 	.fabric_login		= qla24xx_login_fabric,
 	.fabric_logout		= qla24xx_fabric_logout,
 	.fabric_logout		= qla24xx_fabric_logout,
 	.calc_req_entries	= NULL,
 	.calc_req_entries	= NULL,
@@ -1391,7 +1306,8 @@ static struct isp_operations qla25xx_isp_ops = {
 	.enable_intrs		= qla24xx_enable_intrs,
 	.enable_intrs		= qla24xx_enable_intrs,
 	.disable_intrs		= qla24xx_disable_intrs,
 	.disable_intrs		= qla24xx_disable_intrs,
 	.abort_command		= qla24xx_abort_command,
 	.abort_command		= qla24xx_abort_command,
-	.abort_target		= qla24xx_abort_target,
+	.target_reset		= qla24xx_abort_target,
+	.lun_reset		= qla24xx_lun_reset,
 	.fabric_login		= qla24xx_login_fabric,
 	.fabric_login		= qla24xx_login_fabric,
 	.fabric_logout		= qla24xx_fabric_logout,
 	.fabric_logout		= qla24xx_fabric_logout,
 	.calc_req_entries	= NULL,
 	.calc_req_entries	= NULL,
@@ -1464,6 +1380,13 @@ qla2x00_set_isp_flags(scsi_qla_host_t *ha)
 		ha->device_type |= DT_IIDMA;
 		ha->device_type |= DT_IIDMA;
 		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
 		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
 		break;
 		break;
+	case PCI_DEVICE_ID_QLOGIC_ISP8432:
+		ha->device_type |= DT_ISP8432;
+		ha->device_type |= DT_ZIO_SUPPORTED;
+		ha->device_type |= DT_FWI2;
+		ha->device_type |= DT_IIDMA;
+		ha->fw_srisc_address = RISC_START_ADDRESS_2400;
+		break;
 	case PCI_DEVICE_ID_QLOGIC_ISP5422:
 	case PCI_DEVICE_ID_QLOGIC_ISP5422:
 		ha->device_type |= DT_ISP5422;
 		ha->device_type |= DT_ISP5422;
 		ha->device_type |= DT_FWI2;
 		ha->device_type |= DT_FWI2;
@@ -1587,6 +1510,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 	sht = &qla2x00_driver_template;
 	sht = &qla2x00_driver_template;
 	if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
 	if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 ||
 	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 ||
 	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 ||
+	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP8432 ||
 	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 ||
 	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5422 ||
 	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 ||
 	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP5432 ||
 	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) {
 	    pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2532) {
@@ -1677,7 +1601,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 		if (IS_QLA2322(ha) || IS_QLA6322(ha))
 		if (IS_QLA2322(ha) || IS_QLA6322(ha))
 			ha->optrom_size = OPTROM_SIZE_2322;
 			ha->optrom_size = OPTROM_SIZE_2322;
 		ha->isp_ops = &qla2300_isp_ops;
 		ha->isp_ops = &qla2300_isp_ops;
-	} else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+	} else if (IS_QLA24XX_TYPE(ha)) {
 		host->max_id = MAX_TARGETS_2200;
 		host->max_id = MAX_TARGETS_2200;
 		ha->mbx_count = MAILBOX_REGISTER_COUNT;
 		ha->mbx_count = MAILBOX_REGISTER_COUNT;
 		ha->request_q_length = REQUEST_ENTRY_CNT_24XX;
 		ha->request_q_length = REQUEST_ENTRY_CNT_24XX;
@@ -1699,6 +1623,8 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 		ha->gid_list_info_size = 8;
 		ha->gid_list_info_size = 8;
 		ha->optrom_size = OPTROM_SIZE_25XX;
 		ha->optrom_size = OPTROM_SIZE_25XX;
 		ha->isp_ops = &qla25xx_isp_ops;
 		ha->isp_ops = &qla25xx_isp_ops;
+		ha->hw_event_start = PCI_FUNC(pdev->devfn) ?
+		    FA_HW_EVENT1_ADDR: FA_HW_EVENT0_ADDR;
 	}
 	}
 	host->can_queue = ha->request_q_length + 128;
 	host->can_queue = ha->request_q_length + 128;
 
 
@@ -1713,6 +1639,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
 	INIT_LIST_HEAD(&ha->list);
 	INIT_LIST_HEAD(&ha->list);
 	INIT_LIST_HEAD(&ha->fcports);
 	INIT_LIST_HEAD(&ha->fcports);
 	INIT_LIST_HEAD(&ha->vp_list);
 	INIT_LIST_HEAD(&ha->vp_list);
+	INIT_LIST_HEAD(&ha->work_list);
 
 
 	set_bit(0, (unsigned long *) ha->vp_idx_map);
 	set_bit(0, (unsigned long *) ha->vp_idx_map);
 
 
@@ -1819,6 +1746,8 @@ qla2x00_remove_one(struct pci_dev *pdev)
 
 
 	qla2x00_dfs_remove(ha);
 	qla2x00_dfs_remove(ha);
 
 
+	qla84xx_put_chip(ha);
+
 	qla2x00_free_sysfs_attr(ha);
 	qla2x00_free_sysfs_attr(ha);
 
 
 	fc_remove_host(ha->host);
 	fc_remove_host(ha->host);
@@ -2206,6 +2135,97 @@ qla2x00_mem_free(scsi_qla_host_t *ha)
 	kfree(ha->nvram);
 	kfree(ha->nvram);
 }
 }
 
 
+struct qla_work_evt *
+qla2x00_alloc_work(struct scsi_qla_host *ha, enum qla_work_type type,
+    int locked)
+{
+	struct qla_work_evt *e;
+
+	e = kzalloc(sizeof(struct qla_work_evt), locked ? GFP_ATOMIC:
+	    GFP_KERNEL);
+	if (!e)
+		return NULL;
+
+	INIT_LIST_HEAD(&e->list);
+	e->type = type;
+	e->flags = QLA_EVT_FLAG_FREE;
+	return e;
+}
+
+int
+qla2x00_post_work(struct scsi_qla_host *ha, struct qla_work_evt *e, int locked)
+{
+	unsigned long flags;
+
+	if (!locked)
+		spin_lock_irqsave(&ha->hardware_lock, flags);
+	list_add_tail(&e->list, &ha->work_list);
+	qla2xxx_wake_dpc(ha);
+	if (!locked)
+		spin_unlock_irqrestore(&ha->hardware_lock, flags);
+	return QLA_SUCCESS;
+}
+
+int
+qla2x00_post_aen_work(struct scsi_qla_host *ha, enum fc_host_event_code code,
+    u32 data)
+{
+	struct qla_work_evt *e;
+
+	e = qla2x00_alloc_work(ha, QLA_EVT_AEN, 1);
+	if (!e)
+		return QLA_FUNCTION_FAILED;
+
+	e->u.aen.code = code;
+	e->u.aen.data = data;
+	return qla2x00_post_work(ha, e, 1);
+}
+
+int
+qla2x00_post_hwe_work(struct scsi_qla_host *ha, uint16_t code, uint16_t d1,
+    uint16_t d2, uint16_t d3)
+{
+	struct qla_work_evt *e;
+
+	e = qla2x00_alloc_work(ha, QLA_EVT_HWE_LOG, 1);
+	if (!e)
+		return QLA_FUNCTION_FAILED;
+
+	e->u.hwe.code = code;
+	e->u.hwe.d1 = d1;
+	e->u.hwe.d2 = d2;
+	e->u.hwe.d3 = d3;
+	return qla2x00_post_work(ha, e, 1);
+}
+
+static void
+qla2x00_do_work(struct scsi_qla_host *ha)
+{
+	struct qla_work_evt *e;
+
+	spin_lock_irq(&ha->hardware_lock);
+	while (!list_empty(&ha->work_list)) {
+		e = list_entry(ha->work_list.next, struct qla_work_evt, list);
+		list_del_init(&e->list);
+		spin_unlock_irq(&ha->hardware_lock);
+
+		switch (e->type) {
+		case QLA_EVT_AEN:
+			fc_host_post_event(ha->host, fc_get_event_number(),
+			    e->u.aen.code, e->u.aen.data);
+			break;
+		case QLA_EVT_HWE_LOG:
+			qla2xxx_hw_event_log(ha, e->u.hwe.code, e->u.hwe.d1,
+			    e->u.hwe.d2, e->u.hwe.d3);
+			break;
+		}
+		if (e->flags & QLA_EVT_FLAG_FREE)
+			kfree(e);
+		spin_lock_irq(&ha->hardware_lock);
+	}
+	spin_unlock_irq(&ha->hardware_lock);
+}
+
 /**************************************************************************
 /**************************************************************************
 * qla2x00_do_dpc
 * qla2x00_do_dpc
 *   This kernel thread is a task that is schedule by the interrupt handler
 *   This kernel thread is a task that is schedule by the interrupt handler
@@ -2257,6 +2277,8 @@ qla2x00_do_dpc(void *data)
 			continue;
 			continue;
 		}
 		}
 
 
+		qla2x00_do_work(ha);
+
 		if (test_and_clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) {
 		if (test_and_clear_bit(ISP_ABORT_NEEDED, &ha->dpc_flags)) {
 
 
 			DEBUG(printk("scsi(%ld): dpc: sched "
 			DEBUG(printk("scsi(%ld): dpc: sched "
@@ -2291,12 +2313,6 @@ qla2x00_do_dpc(void *data)
 		if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags))
 		if (test_and_clear_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags))
 			qla2x00_update_fcports(ha);
 			qla2x00_update_fcports(ha);
 
 
-		if (test_and_clear_bit(LOOP_RESET_NEEDED, &ha->dpc_flags)) {
-			DEBUG(printk("scsi(%ld): dpc: sched loop_reset()\n",
-			    ha->host_no));
-			qla2x00_loop_reset(ha);
-		}
-
 		if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) &&
 		if (test_and_clear_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) &&
 		    (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) {
 		    (!(test_and_set_bit(RESET_ACTIVE, &ha->dpc_flags)))) {
 
 
@@ -2367,19 +2383,6 @@ qla2x00_do_dpc(void *data)
 			    ha->host_no));
 			    ha->host_no));
 		}
 		}
 
 
-		if ((test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags)) &&
-		    atomic_read(&ha->loop_state) != LOOP_DOWN) {
-
-			clear_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags);
-			DEBUG(printk("scsi(%ld): qla2x00_login_retry()\n",
-			    ha->host_no));
-
-			set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags);
-
-			DEBUG(printk("scsi(%ld): qla2x00_login_retry - end\n",
-			    ha->host_no));
-		}
-
 		if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) {
 		if (test_and_clear_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) {
 
 
 			DEBUG(printk("scsi(%ld): qla2x00_loop_resync()\n",
 			DEBUG(printk("scsi(%ld): qla2x00_loop_resync()\n",
@@ -2397,18 +2400,6 @@ qla2x00_do_dpc(void *data)
 			    ha->host_no));
 			    ha->host_no));
 		}
 		}
 
 
-		if (test_and_clear_bit(FCPORT_RESCAN_NEEDED, &ha->dpc_flags)) {
-
-			DEBUG(printk("scsi(%ld): Rescan flagged fcports...\n",
-			    ha->host_no));
-
-			qla2x00_rescan_fcports(ha);
-
-			DEBUG(printk("scsi(%ld): Rescan flagged fcports..."
-			    "end.\n",
-			    ha->host_no));
-		}
-
 		if (!ha->interrupts_on)
 		if (!ha->interrupts_on)
 			ha->isp_ops->enable_intrs(ha);
 			ha->isp_ops->enable_intrs(ha);
 
 
@@ -2586,7 +2577,8 @@ qla2x00_timer(scsi_qla_host_t *ha)
 			set_bit(RESTART_QUEUES_NEEDED, &ha->dpc_flags);
 			set_bit(RESTART_QUEUES_NEEDED, &ha->dpc_flags);
 			start_dpc++;
 			start_dpc++;
 
 
-			if (!(ha->device_flags & DFLG_NO_CABLE)) {
+			if (!(ha->device_flags & DFLG_NO_CABLE) &&
+			    !ha->parent) {
 				DEBUG(printk("scsi(%ld): Loop down - "
 				DEBUG(printk("scsi(%ld): Loop down - "
 				    "aborting ISP.\n",
 				    "aborting ISP.\n",
 				    ha->host_no));
 				    ha->host_no));
@@ -2610,10 +2602,8 @@ qla2x00_timer(scsi_qla_host_t *ha)
 	/* Schedule the DPC routine if needed */
 	/* Schedule the DPC routine if needed */
 	if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
 	if ((test_bit(ISP_ABORT_NEEDED, &ha->dpc_flags) ||
 	    test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) ||
 	    test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) ||
-	    test_bit(LOOP_RESET_NEEDED, &ha->dpc_flags) ||
 	    test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) ||
 	    test_bit(FCPORT_UPDATE_NEEDED, &ha->dpc_flags) ||
 	    start_dpc ||
 	    start_dpc ||
-	    test_bit(LOGIN_RETRY_NEEDED, &ha->dpc_flags) ||
 	    test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
 	    test_bit(RESET_MARKER_NEEDED, &ha->dpc_flags) ||
 	    test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) ||
 	    test_bit(BEACON_BLINK_NEEDED, &ha->dpc_flags) ||
 	    test_bit(VP_DPC_NEEDED, &ha->dpc_flags) ||
 	    test_bit(VP_DPC_NEEDED, &ha->dpc_flags) ||
@@ -2665,7 +2655,7 @@ qla2x00_request_firmware(scsi_qla_host_t *ha)
 		blob = &qla_fw_blobs[FW_ISP2300];
 		blob = &qla_fw_blobs[FW_ISP2300];
 	} else if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
 	} else if (IS_QLA2322(ha) || IS_QLA6322(ha)) {
 		blob = &qla_fw_blobs[FW_ISP2322];
 		blob = &qla_fw_blobs[FW_ISP2322];
-	} else if (IS_QLA24XX(ha) || IS_QLA54XX(ha)) {
+	} else if (IS_QLA24XX_TYPE(ha)) {
 		blob = &qla_fw_blobs[FW_ISP24XX];
 		blob = &qla_fw_blobs[FW_ISP24XX];
 	} else if (IS_QLA25XX(ha)) {
 	} else if (IS_QLA25XX(ha)) {
 		blob = &qla_fw_blobs[FW_ISP25XX];
 		blob = &qla_fw_blobs[FW_ISP25XX];
@@ -2815,6 +2805,7 @@ static struct pci_device_id qla2xxx_pci_tbl[] = {
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP6322) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2422) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2432) },
+	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP8432) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5422) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP5432) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) },
 	{ PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2532) },

+ 1 - 15
drivers/scsi/qla2xxx/qla_settings.h

@@ -1,26 +1,12 @@
 /*
 /*
  * QLogic Fibre Channel HBA Driver
  * QLogic Fibre Channel HBA Driver
- * Copyright (c)  2003-2005 QLogic Corporation
+ * Copyright (c)  2003-2008 QLogic Corporation
  *
  *
  * See LICENSE.qla2xxx for copyright and licensing details.
  * See LICENSE.qla2xxx for copyright and licensing details.
  */
  */
-/*
- * Compile time Options:
- *     0 - Disable and 1 - Enable
- */
-#define DEBUG_QLA2100		0	/* For Debug of qla2x00 */
-
-#define USE_ABORT_TGT		1	/* Use Abort Target mbx cmd */
-
 #define MAX_RETRIES_OF_ISP_ABORT	5
 #define MAX_RETRIES_OF_ISP_ABORT	5
 
 
 /* Max time to wait for the loop to be in LOOP_READY state */
 /* Max time to wait for the loop to be in LOOP_READY state */
 #define MAX_LOOP_TIMEOUT	(60 * 5)
 #define MAX_LOOP_TIMEOUT	(60 * 5)
 
 
-/*
- * Some vendor subsystems do not recover properly after a device reset.  Define
- * the following to force a logout after a successful device reset.
- */
-#undef LOGOUT_AFTER_DEVICE_RESET
-
 #include "qla_version.h"
 #include "qla_version.h"

Một số tệp đã không được hiển thị bởi vì quá nhiều tập tin thay đổi trong này khác