linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH 1/6] scsi: megaraid_sas - add hibernation support
@ 2007-11-07 17:09 bo yang
  2007-11-16 21:31 ` Yang, Bo
  0 siblings, 1 reply; 40+ messages in thread
From: bo yang @ 2007-11-07 17:09 UTC (permalink / raw)
  To: linux-scsi; +Cc: James.Bottomley, akpm, linux-kernel, bo.yang, sumant.patro

Adding hibernation support. suspend, resume routine implemented.

Signed-off-by: Bo Yang <bo.yang@lsi.com>

---
 drivers/scsi/megaraid/megaraid_sas.c |  302 +++++++++++++++++++------
 drivers/scsi/megaraid/megaraid_sas.h |    1
 2 files changed, 233 insertions(+), 70 deletions(-)

diff -rupN linux-2.6.22_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.22_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.22_orig/drivers/scsi/megaraid/megaraid_sas.c	2007-11-07 01:37:18.129310512 -0500
+++ linux-2.6.22_new/drivers/scsi/megaraid/megaraid_sas.c	2007-11-07 01:36:25.261347664 -0500
@@ -1803,6 +1803,81 @@ static void megasas_complete_cmd_dpc(uns
 }
 
 /**
+ * megasas_issue_init_mfi -	Initializes the FW
+ * @instance:		Adapter soft state
+ *
+ * Issues the INIT MFI cmd
+ */
+static int
+megasas_issue_init_mfi(struct megasas_instance *instance)
+{
+	u32 context;
+
+	struct megasas_cmd *cmd;
+
+	struct megasas_init_frame *init_frame;
+	struct megasas_init_queue_info *initq_info;
+	dma_addr_t init_frame_h;
+	dma_addr_t initq_info_h;
+
+	/*
+	 * Prepare a init frame. Note the init frame points to queue info
+	 * structure. Each frame has SGL allocated after first 64 bytes. For
+	 * this frame - since we don't need any SGL - we use SGL's space as
+	 * queue info structure
+	 *
+	 * We will not get a NULL command below. We just created the pool.
+	 */
+	cmd = megasas_get_cmd(instance);
+
+	init_frame = (struct megasas_init_frame *)cmd->frame;
+	initq_info = (struct megasas_init_queue_info *)
+		((unsigned long)init_frame + 64);
+
+	init_frame_h = cmd->frame_phys_addr;
+	initq_info_h = init_frame_h + 64;
+
+	context = init_frame->context;
+	memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
+	memset(initq_info, 0, sizeof(struct megasas_init_queue_info));
+	init_frame->context = context;
+
+	initq_info->reply_queue_entries = instance->max_fw_cmds + 1;
+	initq_info->reply_queue_start_phys_addr_lo = instance->reply_queue_h;
+
+	initq_info->producer_index_phys_addr_lo = instance->producer_h;
+	initq_info->consumer_index_phys_addr_lo = instance->consumer_h;
+
+	init_frame->cmd = MFI_CMD_INIT;
+	init_frame->cmd_status = 0xFF;
+	init_frame->queue_info_new_phys_addr_lo = initq_info_h;
+
+	init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info);
+
+	/*
+	 * disable the intr before firing the init frame to FW
+	 */
+	instance->instancet->disable_intr(instance->reg_set);
+
+	/*
+	 * Issue the init frame in polled mode
+	 */
+
+	if (megasas_issue_polled(instance, cmd)) {
+		printk(KERN_ERR "megasas: Failed to init firmware\n");
+		megasas_return_cmd(instance, cmd);
+		goto fail_fw_init;
+	}
+
+	megasas_return_cmd(instance, cmd);
+
+	return 0;
+
+fail_fw_init:
+	return -EINVAL;
+}
+
+/**
  * megasas_init_mfi -	Initializes the FW
  * @instance:		Adapter soft state
  *
@@ -1815,15 +1890,7 @@ static int megasas_init_mfi(struct megas
 	u32 max_sectors_1;
 	u32 max_sectors_2;
 	struct megasas_register_set __iomem *reg_set;
-
-	struct megasas_cmd *cmd;
 	struct megasas_ctrl_info *ctrl_info;
-
-	struct megasas_init_frame *init_frame;
-	struct megasas_init_queue_info *initq_info;
-	dma_addr_t init_frame_h;
-	dma_addr_t initq_info_h;
-
 	/*
 	 * Map the message registers
 	 */
@@ -1900,52 +1967,8 @@ static int megasas_init_mfi(struct megas
 		goto fail_reply_queue;
 	}
 
-	/*
-	 * Prepare a init frame. Note the init frame points to queue info
-	 * structure. Each frame has SGL allocated after first 64 bytes. For
-	 * this frame - since we don't need any SGL - we use SGL's space as
-	 * queue info structure
-	 *
-	 * We will not get a NULL command below. We just created the pool.
-	 */
-	cmd = megasas_get_cmd(instance);
-
-	init_frame = (struct megasas_init_frame *)cmd->frame;
-	initq_info = (struct megasas_init_queue_info *)
-	    ((unsigned long)init_frame + 64);
-
-	init_frame_h = cmd->frame_phys_addr;
-	initq_info_h = init_frame_h + 64;
-
-	memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
-	memset(initq_info, 0, sizeof(struct megasas_init_queue_info));
-
-	initq_info->reply_queue_entries = instance->max_fw_cmds + 1;
-	initq_info->reply_queue_start_phys_addr_lo = instance->reply_queue_h;
-
-	initq_info->producer_index_phys_addr_lo = instance->producer_h;
-	initq_info->consumer_index_phys_addr_lo = instance->consumer_h;
-
-	init_frame->cmd = MFI_CMD_INIT;
-	init_frame->cmd_status = 0xFF;
-	init_frame->queue_info_new_phys_addr_lo = initq_info_h;
-
-	init_frame->data_xfer_len = sizeof(struct megasas_init_queue_info);
-
-	/*
-	 * disable the intr before firing the init frame to FW
-	 */
-	instance->instancet->disable_intr(instance->reg_set);
-
-	/*
-	 * Issue the init frame in polled mode
-	 */
-	if (megasas_issue_polled(instance, cmd)) {
-		printk(KERN_DEBUG "megasas: Failed to init firmware\n");
+	if (megasas_issue_init_mfi(instance))
 		goto fail_fw_init;
-	}
-
-	megasas_return_cmd(instance, cmd);
 
 	ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);
 
@@ -1981,7 +2004,6 @@ static int megasas_init_mfi(struct megas
 	return 0;
 
       fail_fw_init:
-	megasas_return_cmd(instance, cmd);
 
 	pci_free_consistent(instance->pdev, reply_q_sz,
 			    instance->reply_queue, instance->reply_queue_h);
@@ -2263,6 +2285,28 @@ static int megasas_io_attach(struct mega
 	return 0;
 }
 
+static int
+megasas_set_dma_mask(struct pci_dev *pdev)
+{
+	/*
+	 * All our contollers are capable of performing 64-bit DMA
+	 */
+	if (IS_DMA64) {
+		if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
+
+			if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)
+				goto fail_set_dma_mask;
+		}
+	} else {
+		if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)
+			goto fail_set_dma_mask;
+	}
+	return 0;
+
+fail_set_dma_mask:
+	return 1;
+}
+
 /**
  * megasas_probe_one -	PCI hotplug entry point
  * @pdev:		PCI device structure
@@ -2296,19 +2340,8 @@ megasas_probe_one(struct pci_dev *pdev, 
 
 	pci_set_master(pdev);
 
-	/*
-	 * All our contollers are capable of performing 64-bit DMA
-	 */
-	if (IS_DMA64) {
-		if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
-
-			if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)
-				goto fail_set_dma_mask;
-		}
-	} else {
-		if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)
-			goto fail_set_dma_mask;
-	}
+	if (megasas_set_dma_mask(pdev))
+		goto fail_set_dma_mask;
 
 	host = scsi_host_alloc(&megasas_template,
 			       sizeof(struct megasas_instance));
@@ -2490,8 +2523,10 @@ static void megasas_flush_cache(struct m
 /**
  * megasas_shutdown_controller -	Instructs FW to shutdown the controller
  * @instance:				Adapter soft state
+ * @opcode:				Shutdown/Hibernate
  */
-static void megasas_shutdown_controller(struct megasas_instance *instance)
+static void megasas_shutdown_controller(struct megasas_instance *instance,
+					u32 opcode)
 {
 	struct megasas_cmd *cmd;
 	struct megasas_dcmd_frame *dcmd;
@@ -2514,7 +2549,7 @@ static void megasas_shutdown_controller(
 	dcmd->flags = MFI_FRAME_DIR_NONE;
 	dcmd->timeout = 0;
 	dcmd->data_xfer_len = 0;
-	dcmd->opcode = MR_DCMD_CTRL_SHUTDOWN;
+	dcmd->opcode = opcode;
 
 	megasas_issue_blocked_cmd(instance, cmd);
 
@@ -2524,6 +2559,131 @@ static void megasas_shutdown_controller(
 }
 
 /**
+ * megasas_suspend -    driver suspend entry point
+ * @pdev:               PCI device structure
+ * @state:		PCI power state to suspend routine
+ */
+static int __devinit
+megasas_suspend(struct pci_dev *pdev, pm_message_t state)
+{
+	struct Scsi_Host *host;
+	struct megasas_instance *instance;
+
+	instance = pci_get_drvdata(pdev);
+	host = instance->host;
+
+	megasas_flush_cache(instance);
+	megasas_shutdown_controller(instance, MR_DCMD_HIBERNATE_SHUTDOWN);
+	tasklet_kill(&instance->isr_tasklet);
+
+	pci_set_drvdata(instance->pdev, instance);
+	instance->instancet->disable_intr(instance->reg_set);
+	free_irq(instance->pdev->irq, instance);
+
+	pci_save_state(pdev);
+	pci_disable_device(pdev);
+
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+	return 0;
+}
+
+/**
+ * megasas_resume-      driver resume entry point
+ * @pdev:               PCI device structure
+ */
+static int __devinit
+megasas_resume(struct pci_dev *pdev)
+{
+	int rval;
+	struct Scsi_Host *host;
+	struct megasas_instance *instance;
+
+	instance = pci_get_drvdata(pdev);
+	host = instance->host;
+	pci_set_power_state(pdev, PCI_D0);
+	pci_enable_wake(pdev, PCI_D0, 0);
+	pci_restore_state(pdev);
+
+	/*
+	 * PCI prepping: enable device set bus mastering and dma mask
+	 */
+	rval = pci_enable_device(pdev);
+
+	if (rval) {
+		printk(KERN_ERR "megasas: Enable device failed\n");
+		return rval;
+	}
+
+	pci_set_master(pdev);
+
+	if (megasas_set_dma_mask(pdev))
+		goto fail_set_dma_mask;
+
+	/*
+	 * Initialize MFI Firmware
+	 */
+
+	*instance->producer = 0;
+	*instance->consumer = 0;
+
+	atomic_set(&instance->fw_outstanding, 0);
+
+	/*
+	 * We expect the FW state to be READY
+	 */
+	if (megasas_transition_to_ready(instance))
+		goto fail_ready_state;
+
+	if (megasas_issue_init_mfi(instance))
+		goto fail_init_mfi;
+
+	tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,
+			(unsigned long)instance);
+
+	/*
+	 * Register IRQ
+	 */
+	if (request_irq(pdev->irq, megasas_isr, IRQF_SHARED,
+		"megasas", instance)) {
+		printk(KERN_ERR "megasas: Failed to register IRQ\n");
+		goto fail_irq;
+	}
+
+	instance->instancet->enable_intr(instance->reg_set);
+
+	/*
+	 * Initiate AEN (Asynchronous Event Notification)
+	 */
+	if (megasas_start_aen(instance))
+		printk(KERN_ERR "megasas: Start AEN failed\n");
+
+	return 0;
+
+fail_irq:
+fail_init_mfi:
+	if (instance->evt_detail)
+		pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
+				instance->evt_detail,
+				instance->evt_detail_h);
+
+	if (instance->producer)
+		pci_free_consistent(pdev, sizeof(u32), instance->producer,
+				instance->producer_h);
+	if (instance->consumer)
+		pci_free_consistent(pdev, sizeof(u32), instance->consumer,
+				instance->consumer_h);
+	scsi_host_put(host);
+
+fail_set_dma_mask:
+fail_ready_state:
+
+	pci_disable_device(pdev);
+
+	return -ENODEV;
+}
+
+/**
  * megasas_detach_one -	PCI hot"un"plug entry point
  * @pdev:		PCI device structure
  */
@@ -2538,7 +2698,7 @@ static void megasas_detach_one(struct pc
 
 	scsi_remove_host(instance->host);
 	megasas_flush_cache(instance);
-	megasas_shutdown_controller(instance);
+	megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
 	tasklet_kill(&instance->isr_tasklet);
 
 	/*
@@ -2977,6 +3137,8 @@ static struct pci_driver megasas_pci_dri
 	.id_table = megasas_pci_table,
 	.probe = megasas_probe_one,
 	.remove = __devexit_p(megasas_detach_one),
+	.suspend = megasas_suspend,
+	.resume = megasas_resume,
 	.shutdown = megasas_shutdown,
 };
 
diff -rupN linux-2.6.22_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.22_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.22_orig/drivers/scsi/megaraid/megaraid_sas.h	2007-11-07 01:31:40.236678000 -0500
+++ linux-2.6.22_new/drivers/scsi/megaraid/megaraid_sas.h	2007-11-07 01:34:31.530637360 -0500
@@ -117,6 +117,7 @@
 #define MR_FLUSH_DISK_CACHE			0x02
 
 #define MR_DCMD_CTRL_SHUTDOWN			0x01050000
+#define MR_DCMD_HIBERNATE_SHUTDOWN		0x01060000
 #define MR_ENABLE_DRIVE_SPINDOWN		0x01
 
 #define MR_DCMD_CTRL_EVENT_GET_INFO		0x01040100


^ permalink raw reply	[flat|nested] 40+ messages in thread

* RE: [PATCH 1/6] scsi: megaraid_sas - add hibernation support
  2007-11-07 17:09 [PATCH 1/6] scsi: megaraid_sas - add hibernation support bo yang
@ 2007-11-16 21:31 ` Yang, Bo
  2007-11-16 22:18   ` James Bottomley
  0 siblings, 1 reply; 40+ messages in thread
From: Yang, Bo @ 2007-11-16 21:31 UTC (permalink / raw)
  To: Yang, Bo, linux-scsi; +Cc: James.Bottomley, akpm, linux-kernel, Patro, Sumant


James,

Do you have get any feedback for those patches?  Based on those patches
be added to the scsi_misc tree, we have more patches need to submit.
Please let me know.

Thanks.

Bo Yang 


-----Original Message-----
From: Yang, Bo 
Sent: Friday, November 09, 2007 3:54 PM
To: linux-scsi@vger.kernel.org
Cc: James.Bottomley@SteelEye.com; akpm@osdl.org;
linux-kernel@vger.kernel.org; Yang, Bo; Patro, Sumant
Subject: [PATCH 1/6] scsi: megaraid_sas - add hibernation support

Adding hibernation support. suspend, resume routine implemented.

Signed-off-by: Bo Yang <bo.yang@lsi.com>

---
 drivers/scsi/megaraid/megaraid_sas.c |  302 +++++++++++++++++++------
 drivers/scsi/megaraid/megaraid_sas.h |    1
 2 files changed, 233 insertions(+), 70 deletions(-)

diff -rupN linux-2.6.22_orig/drivers/scsi/megaraid/megaraid_sas.c
linux-2.6.22_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.22_orig/drivers/scsi/megaraid/megaraid_sas.c
2007-11-07 01:37:18.129310512 -0500
+++ linux-2.6.22_new/drivers/scsi/megaraid/megaraid_sas.c
2007-11-07 01:36:25.261347664 -0500
@@ -1803,6 +1803,81 @@ static void megasas_complete_cmd_dpc(uns  }
 
 /**
+ * megasas_issue_init_mfi -	Initializes the FW
+ * @instance:		Adapter soft state
+ *
+ * Issues the INIT MFI cmd
+ */
+static int
+megasas_issue_init_mfi(struct megasas_instance *instance) {
+	u32 context;
+
+	struct megasas_cmd *cmd;
+
+	struct megasas_init_frame *init_frame;
+	struct megasas_init_queue_info *initq_info;
+	dma_addr_t init_frame_h;
+	dma_addr_t initq_info_h;
+
+	/*
+	 * Prepare a init frame. Note the init frame points to queue
info
+	 * structure. Each frame has SGL allocated after first 64 bytes.
For
+	 * this frame - since we don't need any SGL - we use SGL's space
as
+	 * queue info structure
+	 *
+	 * We will not get a NULL command below. We just created the
pool.
+	 */
+	cmd = megasas_get_cmd(instance);
+
+	init_frame = (struct megasas_init_frame *)cmd->frame;
+	initq_info = (struct megasas_init_queue_info *)
+		((unsigned long)init_frame + 64);
+
+	init_frame_h = cmd->frame_phys_addr;
+	initq_info_h = init_frame_h + 64;
+
+	context = init_frame->context;
+	memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
+	memset(initq_info, 0, sizeof(struct megasas_init_queue_info));
+	init_frame->context = context;
+
+	initq_info->reply_queue_entries = instance->max_fw_cmds + 1;
+	initq_info->reply_queue_start_phys_addr_lo =
instance->reply_queue_h;
+
+	initq_info->producer_index_phys_addr_lo = instance->producer_h;
+	initq_info->consumer_index_phys_addr_lo = instance->consumer_h;
+
+	init_frame->cmd = MFI_CMD_INIT;
+	init_frame->cmd_status = 0xFF;
+	init_frame->queue_info_new_phys_addr_lo = initq_info_h;
+
+	init_frame->data_xfer_len = sizeof(struct
megasas_init_queue_info);
+
+	/*
+	 * disable the intr before firing the init frame to FW
+	 */
+	instance->instancet->disable_intr(instance->reg_set);
+
+	/*
+	 * Issue the init frame in polled mode
+	 */
+
+	if (megasas_issue_polled(instance, cmd)) {
+		printk(KERN_ERR "megasas: Failed to init firmware\n");
+		megasas_return_cmd(instance, cmd);
+		goto fail_fw_init;
+	}
+
+	megasas_return_cmd(instance, cmd);
+
+	return 0;
+
+fail_fw_init:
+	return -EINVAL;
+}
+
+/**
  * megasas_init_mfi -	Initializes the FW
  * @instance:		Adapter soft state
  *
@@ -1815,15 +1890,7 @@ static int megasas_init_mfi(struct megas
 	u32 max_sectors_1;
 	u32 max_sectors_2;
 	struct megasas_register_set __iomem *reg_set;
-
-	struct megasas_cmd *cmd;
 	struct megasas_ctrl_info *ctrl_info;
-
-	struct megasas_init_frame *init_frame;
-	struct megasas_init_queue_info *initq_info;
-	dma_addr_t init_frame_h;
-	dma_addr_t initq_info_h;
-
 	/*
 	 * Map the message registers
 	 */
@@ -1900,52 +1967,8 @@ static int megasas_init_mfi(struct megas
 		goto fail_reply_queue;
 	}
 
-	/*
-	 * Prepare a init frame. Note the init frame points to queue
info
-	 * structure. Each frame has SGL allocated after first 64 bytes.
For
-	 * this frame - since we don't need any SGL - we use SGL's space
as
-	 * queue info structure
-	 *
-	 * We will not get a NULL command below. We just created the
pool.
-	 */
-	cmd = megasas_get_cmd(instance);
-
-	init_frame = (struct megasas_init_frame *)cmd->frame;
-	initq_info = (struct megasas_init_queue_info *)
-	    ((unsigned long)init_frame + 64);
-
-	init_frame_h = cmd->frame_phys_addr;
-	initq_info_h = init_frame_h + 64;
-
-	memset(init_frame, 0, MEGAMFI_FRAME_SIZE);
-	memset(initq_info, 0, sizeof(struct megasas_init_queue_info));
-
-	initq_info->reply_queue_entries = instance->max_fw_cmds + 1;
-	initq_info->reply_queue_start_phys_addr_lo =
instance->reply_queue_h;
-
-	initq_info->producer_index_phys_addr_lo = instance->producer_h;
-	initq_info->consumer_index_phys_addr_lo = instance->consumer_h;
-
-	init_frame->cmd = MFI_CMD_INIT;
-	init_frame->cmd_status = 0xFF;
-	init_frame->queue_info_new_phys_addr_lo = initq_info_h;
-
-	init_frame->data_xfer_len = sizeof(struct
megasas_init_queue_info);
-
-	/*
-	 * disable the intr before firing the init frame to FW
-	 */
-	instance->instancet->disable_intr(instance->reg_set);
-
-	/*
-	 * Issue the init frame in polled mode
-	 */
-	if (megasas_issue_polled(instance, cmd)) {
-		printk(KERN_DEBUG "megasas: Failed to init firmware\n");
+	if (megasas_issue_init_mfi(instance))
 		goto fail_fw_init;
-	}
-
-	megasas_return_cmd(instance, cmd);
 
 	ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info),
GFP_KERNEL);
 
@@ -1981,7 +2004,6 @@ static int megasas_init_mfi(struct megas
 	return 0;
 
       fail_fw_init:
-	megasas_return_cmd(instance, cmd);
 
 	pci_free_consistent(instance->pdev, reply_q_sz,
 			    instance->reply_queue,
instance->reply_queue_h); @@ -2263,6 +2285,28 @@ static int
megasas_io_attach(struct mega
 	return 0;
 }
 
+static int
+megasas_set_dma_mask(struct pci_dev *pdev) {
+	/*
+	 * All our contollers are capable of performing 64-bit DMA
+	 */
+	if (IS_DMA64) {
+		if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
+
+			if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)
+				goto fail_set_dma_mask;
+		}
+	} else {
+		if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)
+			goto fail_set_dma_mask;
+	}
+	return 0;
+
+fail_set_dma_mask:
+	return 1;
+}
+
 /**
  * megasas_probe_one -	PCI hotplug entry point
  * @pdev:		PCI device structure
@@ -2296,19 +2340,8 @@ megasas_probe_one(struct pci_dev *pdev, 
 
 	pci_set_master(pdev);
 
-	/*
-	 * All our contollers are capable of performing 64-bit DMA
-	 */
-	if (IS_DMA64) {
-		if (pci_set_dma_mask(pdev, DMA_64BIT_MASK) != 0) {
-
-			if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)
-				goto fail_set_dma_mask;
-		}
-	} else {
-		if (pci_set_dma_mask(pdev, DMA_32BIT_MASK) != 0)
-			goto fail_set_dma_mask;
-	}
+	if (megasas_set_dma_mask(pdev))
+		goto fail_set_dma_mask;
 
 	host = scsi_host_alloc(&megasas_template,
 			       sizeof(struct megasas_instance)); @@
-2490,8 +2523,10 @@ static void megasas_flush_cache(struct m
 /**
  * megasas_shutdown_controller -	Instructs FW to shutdown the
controller
  * @instance:				Adapter soft state
+ * @opcode:				Shutdown/Hibernate
  */
-static void megasas_shutdown_controller(struct megasas_instance
*instance)
+static void megasas_shutdown_controller(struct megasas_instance
*instance,
+					u32 opcode)
 {
 	struct megasas_cmd *cmd;
 	struct megasas_dcmd_frame *dcmd;
@@ -2514,7 +2549,7 @@ static void megasas_shutdown_controller(
 	dcmd->flags = MFI_FRAME_DIR_NONE;
 	dcmd->timeout = 0;
 	dcmd->data_xfer_len = 0;
-	dcmd->opcode = MR_DCMD_CTRL_SHUTDOWN;
+	dcmd->opcode = opcode;
 
 	megasas_issue_blocked_cmd(instance, cmd);
 
@@ -2524,6 +2559,131 @@ static void megasas_shutdown_controller(  }
 
 /**
+ * megasas_suspend -    driver suspend entry point
+ * @pdev:               PCI device structure
+ * @state:		PCI power state to suspend routine
+ */
+static int __devinit
+megasas_suspend(struct pci_dev *pdev, pm_message_t state) {
+	struct Scsi_Host *host;
+	struct megasas_instance *instance;
+
+	instance = pci_get_drvdata(pdev);
+	host = instance->host;
+
+	megasas_flush_cache(instance);
+	megasas_shutdown_controller(instance,
MR_DCMD_HIBERNATE_SHUTDOWN);
+	tasklet_kill(&instance->isr_tasklet);
+
+	pci_set_drvdata(instance->pdev, instance);
+	instance->instancet->disable_intr(instance->reg_set);
+	free_irq(instance->pdev->irq, instance);
+
+	pci_save_state(pdev);
+	pci_disable_device(pdev);
+
+	pci_set_power_state(pdev, pci_choose_state(pdev, state));
+
+	return 0;
+}
+
+/**
+ * megasas_resume-      driver resume entry point
+ * @pdev:               PCI device structure
+ */
+static int __devinit
+megasas_resume(struct pci_dev *pdev)
+{
+	int rval;
+	struct Scsi_Host *host;
+	struct megasas_instance *instance;
+
+	instance = pci_get_drvdata(pdev);
+	host = instance->host;
+	pci_set_power_state(pdev, PCI_D0);
+	pci_enable_wake(pdev, PCI_D0, 0);
+	pci_restore_state(pdev);
+
+	/*
+	 * PCI prepping: enable device set bus mastering and dma mask
+	 */
+	rval = pci_enable_device(pdev);
+
+	if (rval) {
+		printk(KERN_ERR "megasas: Enable device failed\n");
+		return rval;
+	}
+
+	pci_set_master(pdev);
+
+	if (megasas_set_dma_mask(pdev))
+		goto fail_set_dma_mask;
+
+	/*
+	 * Initialize MFI Firmware
+	 */
+
+	*instance->producer = 0;
+	*instance->consumer = 0;
+
+	atomic_set(&instance->fw_outstanding, 0);
+
+	/*
+	 * We expect the FW state to be READY
+	 */
+	if (megasas_transition_to_ready(instance))
+		goto fail_ready_state;
+
+	if (megasas_issue_init_mfi(instance))
+		goto fail_init_mfi;
+
+	tasklet_init(&instance->isr_tasklet, megasas_complete_cmd_dpc,
+			(unsigned long)instance);
+
+	/*
+	 * Register IRQ
+	 */
+	if (request_irq(pdev->irq, megasas_isr, IRQF_SHARED,
+		"megasas", instance)) {
+		printk(KERN_ERR "megasas: Failed to register IRQ\n");
+		goto fail_irq;
+	}
+
+	instance->instancet->enable_intr(instance->reg_set);
+
+	/*
+	 * Initiate AEN (Asynchronous Event Notification)
+	 */
+	if (megasas_start_aen(instance))
+		printk(KERN_ERR "megasas: Start AEN failed\n");
+
+	return 0;
+
+fail_irq:
+fail_init_mfi:
+	if (instance->evt_detail)
+		pci_free_consistent(pdev, sizeof(struct
megasas_evt_detail),
+				instance->evt_detail,
+				instance->evt_detail_h);
+
+	if (instance->producer)
+		pci_free_consistent(pdev, sizeof(u32),
instance->producer,
+				instance->producer_h);
+	if (instance->consumer)
+		pci_free_consistent(pdev, sizeof(u32),
instance->consumer,
+				instance->consumer_h);
+	scsi_host_put(host);
+
+fail_set_dma_mask:
+fail_ready_state:
+
+	pci_disable_device(pdev);
+
+	return -ENODEV;
+}
+
+/**
  * megasas_detach_one -	PCI hot"un"plug entry point
  * @pdev:		PCI device structure
  */
@@ -2538,7 +2698,7 @@ static void megasas_detach_one(struct pc
 
 	scsi_remove_host(instance->host);
 	megasas_flush_cache(instance);
-	megasas_shutdown_controller(instance);
+	megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
 	tasklet_kill(&instance->isr_tasklet);
 
 	/*
@@ -2977,6 +3137,8 @@ static struct pci_driver megasas_pci_dri
 	.id_table = megasas_pci_table,
 	.probe = megasas_probe_one,
 	.remove = __devexit_p(megasas_detach_one),
+	.suspend = megasas_suspend,
+	.resume = megasas_resume,
 	.shutdown = megasas_shutdown,
 };
 
diff -rupN linux-2.6.22_orig/drivers/scsi/megaraid/megaraid_sas.h
linux-2.6.22_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.22_orig/drivers/scsi/megaraid/megaraid_sas.h
2007-11-07 01:31:40.236678000 -0500
+++ linux-2.6.22_new/drivers/scsi/megaraid/megaraid_sas.h
2007-11-07 01:34:31.530637360 -0500
@@ -117,6 +117,7 @@
 #define MR_FLUSH_DISK_CACHE			0x02
 
 #define MR_DCMD_CTRL_SHUTDOWN			0x01050000
+#define MR_DCMD_HIBERNATE_SHUTDOWN		0x01060000
 #define MR_ENABLE_DRIVE_SPINDOWN		0x01
 
 #define MR_DCMD_CTRL_EVENT_GET_INFO		0x01040100


^ permalink raw reply	[flat|nested] 40+ messages in thread

* RE: [PATCH 1/6] scsi: megaraid_sas - add hibernation support
  2007-11-16 21:31 ` Yang, Bo
@ 2007-11-16 22:18   ` James Bottomley
       [not found]     ` <9738BCBE884FDB42801FAD8A7769C26501C9A4AF@NAMAIL1.ad.lsil.com>
  0 siblings, 1 reply; 40+ messages in thread
From: James Bottomley @ 2007-11-16 22:18 UTC (permalink / raw)
  To: Yang, Bo; +Cc: linux-scsi, akpm, linux-kernel, Patro, Sumant

On Fri, 2007-11-16 at 14:31 -0700, Yang, Bo wrote:
> James,
> 
> Do you have get any feedback for those patches?  Based on those patches
> be added to the scsi_misc tree, we have more patches need to submit.
> Please let me know.

Well, the last one had a large amount of whitespace cleanup to do:

Warning: trailing whitespace in lines
4,9,15,29,34,38,40,46,58,64,77,83,104,108,113,121,125,128,134,137,138 of
Documentation/scsi/ChangeLog.megaraid_sas

So it took me a while to clean it up.

James



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 2/4] scsi: megaraid_sas - Fix the frame count calculation
  2008-03-18  7:13       ` [PATCH 1/4] scsi: megaraid_sas - Rollback the sense info implementation bo yang
@ 2008-03-17  7:36         ` bo yang
  2008-03-17  8:13         ` [PATCH 3/4] scsi: megaraid_sas - Add the new controller Support to Driver bo yang
  2008-03-17  8:18         ` [PATCH 4/4] scsi: megaraid_sas - Update the Version and Changelog bo yang
  2 siblings, 0 replies; 40+ messages in thread
From: bo yang @ 2008-03-17  7:36 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Patro, Sumant, neela.kolli

Driver sent the wrong frame count to firmware.  This patch fixed the frame count calculation.
  
Signed-off-by Bo Yang<bo.yang@lsi.com>

---
 drivers/scsi/megaraid/megaraid_sas.c |   31 ++++++++++++++++---------
 drivers/scsi/megaraid/megaraid_sas.h |    4 +++
 2 files changed, 25 insertions(+), 10 deletions(-)

diff -rupN linux-2.6.24_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.24_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.24_orig/drivers/scsi/megaraid/megaraid_sas.c	2008-03-17 13:51:18.000000000 -0400
+++ linux-2.6.24_new/drivers/scsi/megaraid/megaraid_sas.c	2008-03-17 13:50:39.000000000 -0400
@@ -488,12 +488,13 @@ megasas_make_sgl64(struct megasas_instan
 
  /**
  * megasas_get_frame_count - Computes the number of frames
+ * @frame_type		: type of frame- io or pthru frame
  * @sge_count		: number of sg elements
  *
  * 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 sge_bytes;
@@ -504,13 +505,22 @@ static u32 megasas_get_frame_count(u8 sg
 	    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){
 		sge_bytes = sge_sz * num_cnt;
@@ -592,7 +602,8 @@ megasas_build_dcdb(struct megasas_instan
 	 * Compute the total number of frames this command consumes. FW uses
 	 * 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;
 }
@@ -709,7 +720,7 @@ megasas_build_ldio(struct megasas_instan
 	 * Compute the total number of frames this command consumes. FW uses
 	 * 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;
 }
diff -rupN linux-2.6.24_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.24_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.24_orig/drivers/scsi/megaraid/megaraid_sas.h	2008-03-07 13:45:43.000000000 -0500
+++ linux-2.6.24_new/drivers/scsi/megaraid/megaraid_sas.h	2008-03-07 14:03:41.000000000 -0500
@@ -542,6 +542,10 @@ struct megasas_ctrl_info {
 
 #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
  * MEGASAS_RESET_WAIT_TIME seconds for all outstanding IO to complete. Note



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 3/4] scsi: megaraid_sas - Add the new controller Support to Driver
  2008-03-18  7:13       ` [PATCH 1/4] scsi: megaraid_sas - Rollback the sense info implementation bo yang
  2008-03-17  7:36         ` [PATCH 2/4] scsi: megaraid_sas - Fix the frame count calculation bo yang
@ 2008-03-17  8:13         ` bo yang
  2008-08-01 16:48           ` [PATCH 2/4] scsi: megaraid_sas - Add the shutdown DCMD cmd to driver shutdown routine Yang, Bo
  2008-03-17  8:18         ` [PATCH 4/4] scsi: megaraid_sas - Update the Version and Changelog bo yang
  2 siblings, 1 reply; 40+ messages in thread
From: bo yang @ 2008-03-17  8:13 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Patro, Sumant, neela.kolli, bo.yang

Add the new Controller (ID: 007C) support to driver.

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
 drivers/scsi/megaraid/megaraid_sas.c |    7 +++++--
 drivers/scsi/megaraid/megaraid_sas.h |    1 +
 2 files changed, 6 insertions(+), 2 deletions(-)

diff -rupN linux-2.6.24_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.24_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.24_orig/drivers/scsi/megaraid/megaraid_sas.c	2008-03-17 13:53:49.000000000 -0400
+++ linux-2.6.24_new/drivers/scsi/megaraid/megaraid_sas.c	2008-03-17 13:53:10.000000000 -0400
@@ -68,6 +68,8 @@ static struct pci_device_id megasas_pci_
 	/* xscale IOP */
 	{PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS1078R)},
 	/* 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)},
 	/* xscale IOP, vega */
 	{PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
@@ -1471,7 +1473,7 @@ megasas_transition_to_ready(struct megas
 			instance->instancet->disable_intr(instance->reg_set);
 			writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell);
 
-			max_wait = 10;
+			max_wait = 60;
 			cur_state = MFI_STATE_OPERATIONAL;
 			break;
 
@@ -1991,7 +1993,8 @@ static int megasas_init_mfi(struct megas
 
 	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;
 			break;
 		case PCI_DEVICE_ID_LSI_SAS1064R:
diff -rupN linux-2.6.24_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.24_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.24_orig/drivers/scsi/megaraid/megaraid_sas.h	2008-03-07 14:29:14.000000000 -0500
+++ linux-2.6.24_new/drivers/scsi/megaraid/megaraid_sas.h	2008-03-07 14:10:12.000000000 -0500
@@ -26,6 +26,7 @@
  * Device IDs
  */
 #define	PCI_DEVICE_ID_LSI_SAS1078R		0x0060
+#define	PCI_DEVICE_ID_LSI_SAS1078DE		0x007C
 #define	PCI_DEVICE_ID_LSI_VERDE_ZCR		0x0413
 
 /*


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 4/4] scsi: megaraid_sas - Update the Version and Changelog
  2008-03-18  7:13       ` [PATCH 1/4] scsi: megaraid_sas - Rollback the sense info implementation bo yang
  2008-03-17  7:36         ` [PATCH 2/4] scsi: megaraid_sas - Fix the frame count calculation bo yang
  2008-03-17  8:13         ` [PATCH 3/4] scsi: megaraid_sas - Add the new controller Support to Driver bo yang
@ 2008-03-17  8:18         ` bo yang
  2008-03-17 20:54           ` James Bottomley
  2 siblings, 1 reply; 40+ messages in thread
From: bo yang @ 2008-03-17  8:18 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Patro, Sumant, neela.kolli, bo.yang

Update the Version and ChangeLog

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
 Documentation/scsi/ChangeLog.megaraid_sas |   22 ++++++++++++++++++++
 drivers/scsi/megaraid/megaraid_sas.c      |    2 -
 drivers/scsi/megaraid/megaraid_sas.h      |    6 ++---
 3 files changed, 26 insertions(+), 4 deletions(-)

diff -rupN linux-2.6.24_orig/Documentation/scsi/ChangeLog.megaraid_sas linux-2.6.24_new/Documentation/scsi/ChangeLog.megaraid_sas
--- linux-2.6.24_orig/Documentation/scsi/ChangeLog.megaraid_sas	2008-03-10 10:17:25.000000000 -0400
+++ linux-2.6.24_new/Documentation/scsi/ChangeLog.megaraid_sas	2008-03-10 10:41:39.000000000 -0400
@@ -3,6 +3,28 @@
 			Sumant Patro
 			Bo Yang
 
+2 Current Version : 00.00.03.20
+3 Older Version   : 00.00.03.16
+
+1. Sense buffer ptr data type in the ioctl path is reverted  back to
+	u32 * as in previous versions of driver.
+
+2. Fixed the driver frame count.
+	When Driver sent wrong frame count to firmware.  As this particular
+	command is sent to drive, FW is seeing continuous chip resets and so
+	the command will timeout.
+
+3. Add the new controller(1078DE) support to the driver.
+
+4. Increase the max_wait to 60 from 10 in the controller operational status.
+	With this max_wait increase, driver will make sure the FW will finish
+	the pending cmd for KDUMP case.   
+
+1 Release Date    : Thur. Nov. 07 16:30:43 PST 2007 -
+			(emaild-id:megaraidlinux@lsi.com)
+			Sumant Patro
+			Bo Yang
+
 2 Current Version : 00.00.03.16
 3 Older Version   : 00.00.03.15
 
diff -rupN linux-2.6.24_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.24_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.24_orig/drivers/scsi/megaraid/megaraid_sas.c	2008-03-17 13:54:59.000000000 -0400
+++ linux-2.6.24_new/drivers/scsi/megaraid/megaraid_sas.c	2008-03-17 13:55:30.000000000 -0400
@@ -10,7 +10,7 @@
  *	   2 of the License, or (at your option) any later version.
  *
  * FILE		: megaraid_sas.c
- * Version	: v00.00.03.16-rc1
+ * Version	: v00.00.03.20-rc1
  *
  * Authors:
  *	(email-id : megaraidlinux@lsi.com)
diff -rupN linux-2.6.24_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.24_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.24_orig/drivers/scsi/megaraid/megaraid_sas.h	2008-03-10 10:17:25.000000000 -0400
+++ linux-2.6.24_new/drivers/scsi/megaraid/megaraid_sas.h	2008-03-10 10:51:02.000000000 -0400
@@ -18,9 +18,9 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION				"00.00.03.16-rc1"
-#define MEGASAS_RELDATE				"Nov. 07, 2007"
-#define MEGASAS_EXT_VERSION			"Thu. Nov. 07 10:09:32 PDT 2007"
+#define MEGASAS_VERSION			"00.00.03.20-rc1"
+#define MEGASAS_RELDATE			"March 10, 2008"
+#define MEGASAS_EXT_VERSION		"Mon. March 10 11:02:31 PDT 2008"
 
 /*
  * Device IDs


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 4/4] scsi: megaraid_sas - Update the Version and Changelog
  2008-03-17  8:18         ` [PATCH 4/4] scsi: megaraid_sas - Update the Version and Changelog bo yang
@ 2008-03-17 20:54           ` James Bottomley
  2008-03-17 21:00             ` [PATCH 4/4] scsi: megaraid_sas - Update the Version andChangelog Yang, Bo
  2009-02-17 14:44             ` [PATCH 1/9] scsi: megaraid_sas - Fix the tape drive support Yang, Bo
  0 siblings, 2 replies; 40+ messages in thread
From: James Bottomley @ 2008-03-17 20:54 UTC (permalink / raw)
  To: bo yang; +Cc: linux-scsi, akpm, linux-kernel, Patro, Sumant, neela.kolli

On Mon, 2008-03-17 at 04:18 -0400, bo yang wrote:
> Update the Version and ChangeLog
> 
> Signed-off-by Bo Yang<bo.yang@lsi.com>
> 
> ---
>  Documentation/scsi/ChangeLog.megaraid_sas |   22 ++++++++++++++++++++
>  drivers/scsi/megaraid/megaraid_sas.c      |    2 -
>  drivers/scsi/megaraid/megaraid_sas.h      |    6 ++---
>  3 files changed, 26 insertions(+), 4 deletions(-)
> 
> diff -rupN linux-2.6.24_orig/Documentation/scsi/ChangeLog.megaraid_sas linux-2.6.24_new/Documentation/scsi/ChangeLog.megaraid_sas
> --- linux-2.6.24_orig/Documentation/scsi/ChangeLog.megaraid_sas	2008-03-10 10:17:25.000000000 -0400
> +++ linux-2.6.24_new/Documentation/scsi/ChangeLog.megaraid_sas	2008-03-10 10:41:39.000000000 -0400
> @@ -3,6 +3,28 @@
>  			Sumant Patro
>  			Bo Yang
>  
> +2 Current Version : 00.00.03.20
> +3 Older Version   : 00.00.03.16
> +
> +1. Sense buffer ptr data type in the ioctl path is reverted  back to
> +	u32 * as in previous versions of driver.
> +
> +2. Fixed the driver frame count.
> +	When Driver sent wrong frame count to firmware.  As this particular
> +	command is sent to drive, FW is seeing continuous chip resets and so
> +	the command will timeout.
> +
> +3. Add the new controller(1078DE) support to the driver.

It would be nice if the git change log were this detailed, as well
please.

> +4. Increase the max_wait to 60 from 10 in the controller operational status.
> +	With this max_wait increase, driver will make sure the FW will finish
> +	the pending cmd for KDUMP case.   

Where did this change come from?  It's not in any of this change set
that I can see.

James



^ permalink raw reply	[flat|nested] 40+ messages in thread

* RE: [PATCH 4/4] scsi: megaraid_sas - Update the Version andChangelog
  2008-03-17 20:54           ` James Bottomley
@ 2008-03-17 21:00             ` Yang, Bo
  2009-02-17 14:44             ` [PATCH 1/9] scsi: megaraid_sas - Fix the tape drive support Yang, Bo
  1 sibling, 0 replies; 40+ messages in thread
From: Yang, Bo @ 2008-03-17 21:00 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Patro, Sumant, Kolli, Neela

James,

Sure I will send more details.

Thanks.

Bo Yang 

-----Original Message-----
From: James Bottomley [mailto:James.Bottomley@HansenPartnership.com] 
Sent: Monday, March 17, 2008 4:55 PM
To: Yang, Bo
Cc: linux-scsi@vger.kernel.org; akpm@osdl.org;
linux-kernel@vger.kernel.org; Patro, Sumant; Kolli, Neela
Subject: Re: [PATCH 4/4] scsi: megaraid_sas - Update the Version
andChangelog

On Mon, 2008-03-17 at 04:18 -0400, bo yang wrote:
> Update the Version and ChangeLog
> 
> Signed-off-by Bo Yang<bo.yang@lsi.com>
> 
> ---
>  Documentation/scsi/ChangeLog.megaraid_sas |   22 ++++++++++++++++++++
>  drivers/scsi/megaraid/megaraid_sas.c      |    2 -
>  drivers/scsi/megaraid/megaraid_sas.h      |    6 ++---
>  3 files changed, 26 insertions(+), 4 deletions(-)
> 
> diff -rupN linux-2.6.24_orig/Documentation/scsi/ChangeLog.megaraid_sas
linux-2.6.24_new/Documentation/scsi/ChangeLog.megaraid_sas
> --- linux-2.6.24_orig/Documentation/scsi/ChangeLog.megaraid_sas
2008-03-10 10:17:25.000000000 -0400
> +++ linux-2.6.24_new/Documentation/scsi/ChangeLog.megaraid_sas
2008-03-10 10:41:39.000000000 -0400
> @@ -3,6 +3,28 @@
>  			Sumant Patro
>  			Bo Yang
>  
> +2 Current Version : 00.00.03.20
> +3 Older Version   : 00.00.03.16
> +
> +1. Sense buffer ptr data type in the ioctl path is reverted  back to
> +	u32 * as in previous versions of driver.
> +
> +2. Fixed the driver frame count.
> +	When Driver sent wrong frame count to firmware.  As this
particular
> +	command is sent to drive, FW is seeing continuous chip resets
and so
> +	the command will timeout.
> +
> +3. Add the new controller(1078DE) support to the driver.

It would be nice if the git change log were this detailed, as well
please.

> +4. Increase the max_wait to 60 from 10 in the controller operational
status.
> +	With this max_wait increase, driver will make sure the FW will
finish
> +	the pending cmd for KDUMP case.   

Where did this change come from?  It's not in any of this change set
that I can see.

James



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 1/4] scsi: megaraid_sas - Rollback the sense info implementation
       [not found]     ` <9738BCBE884FDB42801FAD8A7769C26501C9A4AF@NAMAIL1.ad.lsil.com>
@ 2008-03-18  7:13       ` bo yang
  2008-03-17  7:36         ` [PATCH 2/4] scsi: megaraid_sas - Fix the frame count calculation bo yang
                           ` (2 more replies)
  0 siblings, 3 replies; 40+ messages in thread
From: bo yang @ 2008-03-18  7:13 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Patro, Sumant, nella.kolli, bo.yang

Rollback the sense info implementation

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
 drivers/scsi/megaraid/megaraid_sas.c |   11 +++++------
 1 files changed, 5 insertions(+), 6 deletions(-)

diff -rupN linux-2.6.24_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.24_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.24_orig/drivers/scsi/megaraid/megaraid_sas.c	2008-03-07 10:59:53.000000000 -0500
+++ linux-2.6.24_new/drivers/scsi/megaraid/megaraid_sas.c	2008-03-17 13:47:08.000000000 -0400
@@ -2909,7 +2909,6 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
 	void *sense = NULL;
 	dma_addr_t sense_handle;
 	u32 *sense_ptr;
-	unsigned long *sense_buff;
 
 	memset(kbuff_arr, 0, sizeof(kbuff_arr));
 
@@ -3014,14 +3013,14 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
 	 */
 	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_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 "
 					"sense data\n");
 			error = -EFAULT;


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 2/4] scsi: megaraid_sas - Add the shutdown DCMD cmd to driver shutdown routine
  2008-03-17  8:13         ` [PATCH 3/4] scsi: megaraid_sas - Add the new controller Support to Driver bo yang
@ 2008-08-01 16:48           ` Yang, Bo
  2008-08-01 21:17             ` [PATCH 3/4] scsi: megaraid_sas - Add the new controllers support Yang, Bo
  0 siblings, 1 reply; 40+ messages in thread
From: Yang, Bo @ 2008-08-01 16:48 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Patro, Sumant, poswald, Austria, Winston

Add the shutdown DCMD cmd to driver shutdown routine to make megaraid sas FW shutdown proper.

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
 drivers/scsi/megaraid/megaraid_sas.c |    1 +
 1 files changed, 1 insertion(+)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2008-07-31 12:51:06.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2008-07-31 12:54:09.000000000 -0400
@@ -2863,6 +2863,7 @@ static void megasas_shutdown(struct pci_
 {
        struct megasas_instance *instance = pci_get_drvdata(pdev);
        megasas_flush_cache(instance);
+       megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
 }

 /**

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 3/4] scsi: megaraid_sas - Add the new controllers support
  2008-08-01 16:48           ` [PATCH 2/4] scsi: megaraid_sas - Add the shutdown DCMD cmd to driver shutdown routine Yang, Bo
@ 2008-08-01 21:17             ` Yang, Bo
  2008-08-01 21:25               ` [PATCH 4/4] scsi: megaraid_sas - Version and Documentation Update Yang, Bo
  0 siblings, 1 reply; 40+ messages in thread
From: Yang, Bo @ 2008-08-01 21:17 UTC (permalink / raw)
  To: James.Bottomley, Yang, Bo, James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Patro, Sumant, poswald, Austria, Winston

Add the new controllers (0x78 0x79) support to the driver.  Those controllers are LSI's next generation (gen2) SAS controllers.

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
 drivers/scsi/megaraid/megaraid_sas.c |  111 ++++++++++++++++++++++++++++++++++-
 drivers/scsi/megaraid/megaraid_sas.h |    4 +
 2 files changed, 113 insertions(+), 2 deletions(-)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2008-07-31 12:56:07.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2008-07-31 13:32:02.000000000 -0400
@@ -10,7 +10,7 @@
  *        2 of the License, or (at your option) any later version.
  *
  * FILE                : megaraid_sas.c
- * Version     : v00.00.03.20-rc1
+ * Version     : v00.00.04.01-rc1
  *
  * Authors:
  *     (email-id : megaraidlinux@lsi.com)
@@ -71,6 +71,10 @@ static struct pci_device_id megasas_pci_
        /* 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_SAS1078GEN2)},
+       /* gen2*/
+       {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)},
+       /* gen2*/
        {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
        /* xscale IOP, vega */
        {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
@@ -324,6 +328,100 @@ static struct megasas_instance_template
 };

 /**
+*      The following functions are defined for gen2 (deviceid : 0x78 0x79)
+*      controllers
+*/
+
+/**
+ * megasas_enable_intr_gen2 -  Enables interrupts
+ * @regs:                      MFI register set
+ */
+static inline void
+megasas_enable_intr_gen2(struct megasas_register_set __iomem *regs)
+{
+       writel(0xFFFFFFFF, &(regs)->outbound_doorbell_clear);
+
+       /* write ~0x00000005 (4 & 1) to the intr mask*/
+       writel(~MFI_GEN2_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
+
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_disable_intr_gen2 - Disables interrupt
+ * @regs:                      MFI register set
+ */
+static inline void
+megasas_disable_intr_gen2(struct megasas_register_set __iomem *regs)
+{
+       u32 mask = 0xFFFFFFFF;
+       writel(mask, &regs->outbound_intr_mask);
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_read_fw_status_reg_gen2 - returns the current FW status value
+ * @regs:                      MFI register set
+ */
+static u32
+megasas_read_fw_status_reg_gen2(struct megasas_register_set __iomem *regs)
+{
+       return readl(&(regs)->outbound_scratch_pad);
+}
+
+/**
+ * megasas_clear_interrupt_gen2 -      Check & clear interrupt
+ * @regs:                              MFI register set
+ */
+static int
+megasas_clear_intr_gen2(struct megasas_register_set __iomem *regs)
+{
+       u32 status;
+       /*
+        * Check if it is our interrupt
+        */
+       status = readl(&regs->outbound_intr_status);
+
+       if (!(status & MFI_GEN2_ENABLE_INTERRUPT_MASK)) {
+               return 1;
+       }
+
+       /*
+        * Clear the interrupt by writing back the same value
+        */
+       writel(status, &regs->outbound_doorbell_clear);
+
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_status);
+
+       return 0;
+}
+/**
+ * megasas_fire_cmd_gen2 -     Sends command to the FW
+ * @frame_phys_addr :          Physical address of cmd
+ * @frame_count :              Number of frames for the command
+ * @regs :                     MFI register set
+ */
+static inline void
+megasas_fire_cmd_gen2(dma_addr_t frame_phys_addr, u32 frame_count,
+                       struct megasas_register_set __iomem *regs)
+{
+       writel((frame_phys_addr | (frame_count<<1))|1,
+                       &(regs)->inbound_queue_port);
+}
+
+static struct megasas_instance_template megasas_instance_template_gen2 = {
+
+       .fire_cmd = megasas_fire_cmd_gen2,
+       .enable_intr = megasas_enable_intr_gen2,
+       .disable_intr = megasas_disable_intr_gen2,
+       .clear_intr = megasas_clear_intr_gen2,
+       .read_fw_status_reg = megasas_read_fw_status_reg_gen2,
+};
+
+/**
 *      This is the end of set of functions & definitions
 *      specific to ppc (deviceid : 0x60) controllers
 */
@@ -1982,7 +2080,12 @@ static int megasas_init_mfi(struct megas
        /*
         * Map the message registers
         */
-       instance->base_addr = pci_resource_start(instance->pdev, 0);
+       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
+               (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0079GEN2)) {
+               instance->base_addr = pci_resource_start(instance->pdev, 1);
+       } else {
+               instance->base_addr = pci_resource_start(instance->pdev, 0);
+       }

        if (pci_request_regions(instance->pdev, "megasas: LSI")) {
                printk(KERN_DEBUG "megasas: IO memory region busy!\n");
@@ -2004,6 +2107,10 @@ static int megasas_init_mfi(struct megas
                case PCI_DEVICE_ID_LSI_SAS1078DE:
                        instance->instancet = &megasas_instance_template_ppc;
                        break;
+               case PCI_DEVICE_ID_LSI_SAS1078GEN2:
+               case PCI_DEVICE_ID_LSI_SAS0079GEN2:
+                       instance->instancet = &megasas_instance_template_gen2;
+                       break;
                case PCI_DEVICE_ID_LSI_SAS1064R:
                case PCI_DEVICE_ID_DELL_PERC5:
                default:
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2008-07-31 12:50:41.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2008-07-31 12:50:41.000000000 -0400
@@ -28,6 +28,8 @@
 #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_SAS1078GEN2           0x0078
+#define        PCI_DEVICE_ID_LSI_SAS0079GEN2           0x0079

 /*
  * =====================================
@@ -580,6 +582,8 @@ struct megasas_ctrl_info {
 #define MEGASAS_COMPLETION_TIMER_INTERVAL      (HZ/10)

 #define MFI_REPLY_1078_MESSAGE_INTERRUPT       0x80000000
+#define MFI_REPLY_GEN2_MESSAGE_INTERRUPT       0x00000001
+#define MFI_GEN2_ENABLE_INTERRUPT_MASK         0x00000001 | 0x00000004

 /*
 * register set for both 1068 and 1078 controllers

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 4/4] scsi: megaraid_sas - Version and Documentation Update
  2008-08-01 21:17             ` [PATCH 3/4] scsi: megaraid_sas - Add the new controllers support Yang, Bo
@ 2008-08-01 21:25               ` Yang, Bo
  0 siblings, 0 replies; 40+ messages in thread
From: Yang, Bo @ 2008-08-01 21:25 UTC (permalink / raw)
  To: Yang, Bo, James.Bottomley, James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Patro, Sumant, poswald, Austria, Winston

Update the Version and Documentation.

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
 Documentation/scsi/ChangeLog.megaraid_sas |   23 +++++++++++++++++++++++
 drivers/scsi/megaraid/megaraid_sas.h      |    6 +++---
 2 files changed, 26 insertions(+), 3 deletions(-)

diff -rupN linux-2.6.28_orig/Documentation/scsi/ChangeLog.megaraid_sas linux-2.6.28_new/Documentation/scsi/ChangeLog.megaraid_sas
--- linux-2.6.28_orig/Documentation/scsi/ChangeLog.megaraid_sas 2008-07-31 13:34:16.000000000 -0400
+++ linux-2.6.28_new/Documentation/scsi/ChangeLog.megaraid_sas  2008-07-31 14:18:36.000000000 -0400
@@ -1,3 +1,26 @@
+
+1 Release Date    : Thur.July. 24 11:41:51 PST 2008 -
+                       (emaild-id:megaraidlinux@lsi.com)
+                       Sumant Patro
+                       Bo Yang
+
+2 Current Version : 00.00.04.01
+3 Older Version   : 00.00.03.22
+
+1. Add the new controller (0078, 0079) support to the driver
+       Those controllers are LSI's next generatation(gen2) SAS controllers.
+
+1 Release Date    : Mon.June. 23 10:12:45 PST 2008 -
+                       (emaild-id:megaraidlinux@lsi.com)
+                       Sumant Patro
+                       Bo Yang
+
+2 Current Version : 00.00.03.22
+3 Older Version   : 00.00.03.20
+
+1. Add shutdown DCMD cmd to the shutdown routine to make FW shutdown proper.
+2. Unexpected interrupt occurs in HWR Linux driver, add the dumy readl pci flush will fix this issue.
+
 1 Release Date    : Mon. March 10 11:02:31 PDT 2008 -
                        (emaild-id:megaraidlinux@lsi.com)
                        Sumant Patro
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2008-07-31 13:34:16.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2008-07-31 13:41:56.000000000 -0400
@@ -18,9 +18,9 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION                        "00.00.03.20-rc1"
-#define MEGASAS_RELDATE                        "March 10, 2008"
-#define MEGASAS_EXT_VERSION            "Mon. March 10 11:02:31 PDT 2008"
+#define MEGASAS_VERSION                                "00.00.04.01"
+#define MEGASAS_RELDATE                                "July 24, 2008"
+#define MEGASAS_EXT_VERSION                    "Thu July 24 11:41:51 PST 2008"

 /*
  * Device IDs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 1/9] scsi: megaraid_sas - Fix the tape drive support
  2008-03-17 20:54           ` James Bottomley
  2008-03-17 21:00             ` [PATCH 4/4] scsi: megaraid_sas - Update the Version andChangelog Yang, Bo
@ 2009-02-17 14:44             ` Yang, Bo
  2009-02-17 15:25               ` [PATCH 2/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - I Yang, Bo
  2009-05-05 23:55               ` [PATCH 1/10] scsi: megaraid_sas - tape drive support fix Yang, Bo
  1 sibling, 2 replies; 40+ messages in thread
From: Yang, Bo @ 2009-02-17 14:44 UTC (permalink / raw)
  To: James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Austria, Winston, Yang, Bo

Add the Tape drive fix to the megaraid_sas driver: If the command is for the tape device, set the FW pthru timeout to the os layer timeout value.

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
drivers/scsi/megaraid/megaraid_sas.c |   11 +++++++++++
 1 file changed, 11 insertions(+)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-02-12 15:24:58.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-02-12 15:33:57.000000000 -0500
@@ -687,6 +687,17 @@ megasas_build_dcdb(struct megasas_instan
        memcpy(pthru->cdb, scp->cmnd, scp->cmd_len);

        /*
+       * If the command is for the tape device, set the
+       * pthru timeout to the os layer timeout value.
+       */
+       if (scp->device->type == TYPE_TAPE) {
+               if ((scp->request->timeout / HZ) > 0xFFFF)
+                       pthru->timeout = 0xFFFF;
+               else
+                       pthru->timeout = scp->request->timeout / HZ;
+       }
+
+       /*
         * Construct SGL
         */
        if (IS_DMA64) {

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 2/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - I
  2009-02-17 14:44             ` [PATCH 1/9] scsi: megaraid_sas - Fix the tape drive support Yang, Bo
@ 2009-02-17 15:25               ` Yang, Bo
  2009-02-17 15:36                 ` [PATCH 3/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - II Yang, Bo
  2009-02-19  0:21                 ` [PATCH 2/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - I Andrew Morton
  2009-05-05 23:55               ` [PATCH 1/10] scsi: megaraid_sas - tape drive support fix Yang, Bo
  1 sibling, 2 replies; 40+ messages in thread
From: Yang, Bo @ 2009-02-17 15:25 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley, linux-scsi, akpm, linux-kernel
  Cc: Austria, Winston

Add Poll_wait mechanism to Gen-2 MegaRAID SAS Linux driver.  In the aen handler, driver needs to wakeup poll handler similar to the way it raises SIGIO.  Driver needs to reregister for AEN with the FW when it receives AEN.

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
drivers/scsi/megaraid/megaraid_sas.c |  133 ++++++++++++++++++++++++++++++++++-
 drivers/scsi/megaraid/megaraid_sas.h |   15 +++
 2 files changed, 147 insertions(+), 1 deletion(-)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-02-12 15:36:36.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-02-12 15:39:26.000000000 -0500
@@ -40,6 +40,7 @@
 #include <linux/compat.h>
 #include <linux/blkdev.h>
 #include <linux/mutex.h>
+#include <linux/poll.h>

 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -89,6 +90,11 @@ static struct megasas_mgmt_info megasas_
 static struct fasync_struct *megasas_async_queue;
 static DEFINE_MUTEX(megasas_async_queue_mutex);

+static int megasas_poll_wait_aen;
+static DECLARE_WAIT_QUEUE_HEAD (megasas_poll_wait);
+extern void
+poll_wait(struct file *filp, wait_queue_head_t *q, poll_table *token);
+
 static u32 megasas_dbg_lvl;

 static void
@@ -1277,6 +1283,8 @@ megasas_bios_param(struct scsi_device *s
        return 0;
 }

+static void megasas_aen_polling(void *arg);
+
 /**
  * megasas_service_aen -       Processes an event notification
  * @instance:                  Adapter soft state
@@ -1295,8 +1303,20 @@ megasas_service_aen(struct megasas_insta
        /*
         * Don't signal app if it is just an aborted previously registered aen
         */
-       if (!cmd->abort_aen)
+       if ((!cmd->abort_aen) && (instance->unload == 0)) {
+               struct megasas_aen_event *ev;
+               ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
+               if (!ev) {
+                       printk(KERN_ERR "%s: out of memory\n", __FUNCTION__);
+               } else {
+                       ev->instance = instance;
+                       INIT_WORK(&ev->hotplug_work, megasas_aen_polling);
+                       schedule_delayed_work(&ev->hotplug_work, 0);
+               }
+               megasas_poll_wait_aen = 1;
+               wake_up(&megasas_poll_wait);
                kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
+       }
        else
                cmd->abort_aen = 0;

@@ -2621,6 +2641,7 @@ megasas_probe_one(struct pci_dev *pdev,

        megasas_dbg_lvl = 0;
        instance->flag = 0;
+       instance->unload = 0;
        instance->last_time = 0;

        /*
@@ -2924,6 +2945,7 @@ static void __devexit megasas_detach_one
        struct megasas_instance *instance;

        instance = pci_get_drvdata(pdev);
+       instance->unload = 1;
        host = instance->host;

        if (poll_mode_io)
@@ -3027,6 +3049,21 @@ static int megasas_mgmt_fasync(int fd, s
 }

 /**
+ * megasas_mgmt_poll -  char node "poll" entry point
+ * */
+static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
+{
+       unsigned int mask = 0;
+       poll_wait(file, &megasas_poll_wait, wait);
+
+       if (megasas_poll_wait_aen) {
+               mask |=   (POLLIN | POLLRDNORM);
+               megasas_poll_wait_aen = 0;
+       }
+       return mask;
+}
+
+/**
  * megasas_mgmt_fw_ioctl -     Issues management ioctls to FW
  * @instance:                  Adapter soft state
  * @argp:                      User's ioctl packet
@@ -3348,6 +3385,7 @@ static const struct file_operations mega
        .open = megasas_mgmt_open,
        .fasync = megasas_mgmt_fasync,
        .unlocked_ioctl = megasas_mgmt_ioctl,
+       .poll = megasas_mgmt_poll,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = megasas_mgmt_compat_ioctl,
 #endif
@@ -3462,6 +3500,99 @@ out:
        return retval;
 }

+
+static void
+megasas_aen_polling(struct work_struct *work)
+{
+       struct megasas_aen_event *ev =
+               container_of(work, struct megasas_aen_event, hotplug_work);
+       struct megasas_instance *instance = ev->instance;
+       struct megasas_evt_log_info eli;
+       union megasas_evt_class_locale class_locale;
+       int doscan = 0;
+       u32 seq_num;
+       int error;
+
+       if (!instance) {
+               printk(KERN_ERR "%s: invalid instance!\n", __FUNCTION__);
+               kfree(ev);
+               return;
+       }
+
+       if (instance->evt_detail) {
+               printk(KERN_INFO "%s[%d]: event code 0x%04x\n", __FUNCTION__,
+                       instance->host->host_no, instance->evt_detail->code);
+
+               switch (instance->evt_detail->code) {
+
+               case MR_EVT_LD_CREATED:
+               case MR_EVT_PD_INSERTED:
+               case MR_EVT_LD_DELETED:
+               case MR_EVT_LD_OFFLINE:
+               case MR_EVT_CFG_CLEARED:
+               case MR_EVT_PD_REMOVED:
+               case MR_EVT_FOREIGN_CFG_IMPORTED:
+               case MR_EVT_LD_STATE_CHANGE:
+                       doscan = 1;
+                       break;
+               default:
+                       doscan = 0;
+                       break;
+               }
+       } else {
+               printk(KERN_ERR "%s[%d]: invalid evt_detail!\n",
+                       __FUNCTION__, instance->host->host_no);
+               kfree(ev);
+               return;
+       }
+
+       if (doscan) {
+               printk(KERN_INFO "%s[%d]: scanning ...\n",
+                       __FUNCTION__, instance->host->host_no);
+               scsi_scan_host(instance->host);
+               msleep(1000);
+       }
+
+       kfree(ev);
+       /**
+       * Get the latest sequence number from FW
+       **/
+
+       memset(&eli, 0, sizeof(eli));
+
+       if (megasas_get_seq_num(instance, &eli)) {
+               printk(KERN_ERR "%s[%d]: failed to get seq_num\n",
+                       __FUNCTION__, instance->host->host_no);
+               return;
+       }
+
+       seq_num = instance->evt_detail->seq_num + 1;
+
+       /**
+       * Register AEN with FW for latest sequence number plus 1
+       **/
+
+       class_locale.members.reserved = 0;
+       class_locale.members.locale = MR_EVT_LOCALE_ALL;
+       class_locale.members.class = MR_EVT_CLASS_DEBUG;
+
+       down(&instance->aen_mutex);
+
+       error = megasas_register_aen(instance, seq_num,
+                               class_locale.word);
+
+       up(&instance->aen_mutex);
+
+       if (error)
+               printk(KERN_ERR "%s[%d]: register aen failed error %x\n",
+                        __FUNCTION__, instance->host->host_no, error);
+       else
+               printk(KERN_INFO "%s[%d]: aen registered\n",
+                       __FUNCTION__, instance->host->host_no);
+
+}
+
+
 static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUGO,
                megasas_sysfs_show_poll_mode_io,
                megasas_sysfs_set_poll_mode_io);
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-02-12 15:36:37.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-02-12 15:24:58.000000000 -0500
@@ -132,6 +132,16 @@
 #define MR_DCMD_CLUSTER_RESET_ALL              0x08010100
 #define MR_DCMD_CLUSTER_RESET_LD               0x08010200

+#define MR_EVT_CFG_CLEARED                     0x0004
+
+#define MR_EVT_LD_STATE_CHANGE                 0x0051
+#define MR_EVT_PD_INSERTED                     0x005b
+#define MR_EVT_PD_REMOVED                      0x0070
+#define MR_EVT_LD_CREATED                      0x008a
+#define MR_EVT_LD_DELETED                      0x008b
+#define MR_EVT_FOREIGN_CFG_IMPORTED            0x00db
+#define MR_EVT_LD_OFFLINE                      0x00fc
+
 /*
  * MFI command completion codes
  */
@@ -1072,6 +1082,11 @@ struct megasas_evt_detail {
        u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *);
  };

+struct megasas_aen_event {
+       struct work_struct hotplug_work;
+       struct megasas_instance *instance;
+};
+
 struct megasas_instance {

        u32 *producer;

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 3/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - II
  2009-02-17 15:25               ` [PATCH 2/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - I Yang, Bo
@ 2009-02-17 15:36                 ` Yang, Bo
  2009-02-17 15:51                   ` [PATCH 4/9] scsi: megaraid_sas - Add new controller 0x73(new SAS2) support to the driver Yang, Bo
  2009-02-19  0:21                 ` [PATCH 2/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - I Andrew Morton
  1 sibling, 1 reply; 40+ messages in thread
From: Yang, Bo @ 2009-02-17 15:36 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley, linux-scsi, akpm, linux-kernel
  Cc: Austria, Winston

Add poll wait support to megaraid sas driver - II, Add Poll_wait mechanism to Gen-2 Linux driver.  Avoid the depending upon storelib to continue events.

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
drivers/scsi/megaraid/megaraid_sas.c |   25 +++++++++++++++++++++++++
 drivers/scsi/megaraid/megaraid_sas.h |    1 +
 2 files changed, 26 insertions(+)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-02-12 15:44:26.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-02-12 15:47:21.000000000 -0500
@@ -95,6 +95,8 @@ static DECLARE_WAIT_QUEUE_HEAD (megasas_
 extern void
 poll_wait(struct file *filp, wait_queue_head_t *q, poll_table *token);

+static u32 support_poll_for_event;
+
 static u32 megasas_dbg_lvl;

 static void
@@ -3427,6 +3429,15 @@ static DRIVER_ATTR(release_date, S_IRUGO
                   NULL);

 static ssize_t
+megasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf)
+{
+       return sprintf(buf, "%u\n", support_poll_for_event);
+}
+
+static DRIVER_ATTR(support_poll_for_event, S_IRUGO,
+                       megasas_sysfs_show_support_poll_for_event, NULL);
+
+static ssize_t
 megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf)
 {
        return sprintf(buf, "%u\n", megasas_dbg_lvl);
@@ -3610,6 +3621,8 @@ static int __init megasas_init(void)
        printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION,
               MEGASAS_EXT_VERSION);

+       support_poll_for_event = 1;
+
        memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info));

        /*
@@ -3642,6 +3655,12 @@ static int __init megasas_init(void)
                                  &driver_attr_release_date);
        if (rval)
                goto err_dcf_rel_date;
+
+       rval = driver_create_file(&megasas_pci_driver.driver,
+                               &driver_attr_support_poll_for_event);
+       if (rval)
+               goto err_dcf_support_poll_for_event;
+
        rval = driver_create_file(&megasas_pci_driver.driver,
                                  &driver_attr_dbg_lvl);
        if (rval)
@@ -3659,6 +3678,10 @@ err_dcf_poll_mode_io:
 err_dcf_dbg_lvl:
        driver_remove_file(&megasas_pci_driver.driver,
                           &driver_attr_release_date);
+err_dcf_support_poll_for_event:
+       driver_remove_file(&megasas_pci_driver.driver,
+                       &driver_attr_support_poll_for_event);
+
 err_dcf_rel_date:
        driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
 err_dcf_attr_ver:
@@ -3678,6 +3701,8 @@ static void __exit megasas_exit(void)
        driver_remove_file(&megasas_pci_driver.driver,
                           &driver_attr_dbg_lvl);
        driver_remove_file(&megasas_pci_driver.driver,
+                       &driver_attr_support_poll_for_event);
+       driver_remove_file(&megasas_pci_driver.driver,
                           &driver_attr_release_date);
        driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-02-12 15:44:27.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-02-12 15:24:58.000000000 -0500
@@ -1135,6 +1135,7 @@ struct megasas_instance {
        struct tasklet_struct isr_tasklet;

        u8 flag;
+       u8 unload;
        unsigned long last_time;

        struct timer_list io_completion_timer;

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 4/9] scsi: megaraid_sas - Add new controller 0x73(new SAS2) support to the driver
  2009-02-17 15:36                 ` [PATCH 3/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - II Yang, Bo
@ 2009-02-17 15:51                   ` Yang, Bo
  2009-02-17 16:37                     ` [PATCH 5/9] scsi: megaraid_sas - Add memory support required by 0x73 controller Yang, Bo
  0 siblings, 1 reply; 40+ messages in thread
From: Yang, Bo @ 2009-02-17 15:51 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley, linux-scsi, akpm, linux-kernel
  Cc: Austria, Winston

Add new controller 0x73(new SAS2) support to the MegaRAID SAS driver.

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
drivers/scsi/megaraid/megaraid_sas.c |  145 +++++++++++++++++++++++++++++++++--
 drivers/scsi/megaraid/megaraid_sas.h |    5 +
 2 files changed, 144 insertions(+), 6 deletions(-)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-02-12 15:52:27.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-02-12 15:54:41.000000000 -0500
@@ -76,6 +76,10 @@ static struct pci_device_id megasas_pci_
        /* gen2*/
        {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)},
        /* gen2*/
+       {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0073SKINNY)},
+       /* skinny*/
+       {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0071SKINNY)},
+       /* skinny*/
        {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
        /* xscale IOP, vega */
        {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
@@ -336,6 +340,100 @@ static struct megasas_instance_template
 };

 /**
+ * megasas_enable_intr_skinny -        Enables interrupts
+ * @regs:                      MFI register set
+ */
+static inline void
+megasas_enable_intr_skinny(struct megasas_register_set __iomem *regs)
+{
+       writel(0xFFFFFFFF, &(regs)->outbound_intr_mask);
+
+       /* write ~0x00000005 (4 & 1) to the intr mask*/
+       writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
+
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_disable_intr_skinny -       Disables interrupt
+ * @regs:                      MFI register set
+ */
+static inline void
+megasas_disable_intr_skinny(struct megasas_register_set __iomem *regs)
+{
+       u32 mask = 0xFFFFFFFF;
+       writel(mask, &regs->outbound_intr_mask);
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_read_fw_status_reg_skinny - returns the current FW status value
+ * @regs:                      MFI register set
+ */
+static u32
+megasas_read_fw_status_reg_skinny(struct megasas_register_set __iomem *regs)
+{
+       return readl(&(regs)->outbound_scratch_pad);
+}
+
+/**
+ * megasas_clear_interrupt_skinny -    Check & clear interrupt
+ * @regs:                              MFI register set
+ */
+static int
+megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs)
+{
+       u32 status;
+       /*
+        * Check if it is our interrupt
+        */
+       status = readl(&regs->outbound_intr_status);
+
+       if (!(status & MFI_SKINNY_ENABLE_INTERRUPT_MASK)) {
+               return 1;
+       }
+
+       /*
+        * Clear the interrupt by writing back the same value
+        */
+       writel(status, &regs->outbound_intr_status);
+
+       /*
+       * dummy read to flush PCI
+       */
+       readl(&regs->outbound_intr_status);
+
+       return 0;
+}
+
+/**
+ * megasas_fire_cmd_skinny -   Sends command to the FW
+ * @frame_phys_addr :          Physical address of cmd
+ * @frame_count :              Number of frames for the command
+ * @regs :                     MFI register set
+ */
+static inline void
+megasas_fire_cmd_skinny(dma_addr_t frame_phys_addr, u32 frame_count,
+                       struct megasas_register_set __iomem *regs)
+{
+       writel(0, &(regs)->inbound_high_queue_port);
+       writel((frame_phys_addr | (frame_count<<1))|1,
+                       &(regs)->inbound_low_queue_port);
+       /*msleep(5);*/
+}
+
+static struct megasas_instance_template megasas_instance_template_skinny = {
+
+       .fire_cmd = megasas_fire_cmd_skinny,
+       .enable_intr = megasas_enable_intr_skinny,
+       .disable_intr = megasas_disable_intr_skinny,
+       .clear_intr = megasas_clear_intr_skinny,
+       .read_fw_status_reg = megasas_read_fw_status_reg_skinny,
+};
+
+/**
 *      The following functions are defined for gen2 (deviceid : 0x78 0x79)
 *      controllers
 */
@@ -1322,7 +1420,6 @@ megasas_service_aen(struct megasas_insta
        else
                cmd->abort_aen = 0;

-       instance->aen_cmd = NULL;
        megasas_return_cmd(instance, cmd);
 }

@@ -1589,16 +1686,34 @@ megasas_transition_to_ready(struct megas
                        /*
                         * Set the CLR bit in inbound doorbell
                         */
-                       writel(MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
-                               &instance->reg_set->inbound_doorbell);
+                       if ((instance->pdev->device == \
+                               PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+                               (instance->pdev->device ==
+                               PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+
+                               writel(
+                                 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
+                                 &instance->reg_set->outbound_scratch_pad);
+                       } else {
+                               writel(
+                                   MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
+                                       &instance->reg_set->inbound_doorbell);
+                       }

                        max_wait = 2;
                        cur_state = MFI_STATE_WAIT_HANDSHAKE;
                        break;

                case MFI_STATE_BOOT_MESSAGE_PENDING:
-                       writel(MFI_INIT_HOTPLUG,
-                               &instance->reg_set->inbound_doorbell);
+                       if ((instance->pdev->device ==
+                               PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+                       (instance->pdev->device ==
+                               PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+                               writel(MFI_INIT_HOTPLUG,
+                               &instance->reg_set->outbound_scratch_pad);
+                       } else
+                               writel(MFI_INIT_HOTPLUG,
+                                       &instance->reg_set->inbound_doorbell);

                        max_wait = 10;
                        cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
@@ -1609,7 +1724,15 @@ megasas_transition_to_ready(struct megas
                         * Bring it to READY state; assuming max wait 10 secs
                         */
                        instance->instancet->disable_intr(instance->reg_set);
-                       writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell);
+                       if ((instance->pdev->device ==
+                               PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+                               (instance->pdev->device ==
+                               PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+                               writel(MFI_RESET_FLAGS,
+                               &instance->reg_set->outbound_scratch_pad);
+                       } else
+                               writel(MFI_RESET_FLAGS,
+                               &instance->reg_set->inbound_doorbell);

                        max_wait = 60;
                        cur_state = MFI_STATE_OPERATIONAL;
@@ -2114,6 +2237,8 @@ static int megasas_init_mfi(struct megas
         * Map the message registers
         */
        if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
+               (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
+               (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
                (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0079GEN2)) {
                instance->base_addr = pci_resource_start(instance->pdev, 1);
        } else {
@@ -2144,6 +2269,10 @@ static int megasas_init_mfi(struct megas
                case PCI_DEVICE_ID_LSI_SAS0079GEN2:
                        instance->instancet = &megasas_instance_template_gen2;
                        break;
+               case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
+               case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
+                       instance->instancet = &megasas_instance_template_skinny;
+                       break;
                case PCI_DEVICE_ID_LSI_SAS1064R:
                case PCI_DEVICE_ID_DELL_PERC5:
                default:
@@ -2413,6 +2542,10 @@ megasas_register_aen(struct megasas_inst
                                       "previous AEN command\n");
                                return ret_val;
                        }
+                       /**
+                       * set the AEN to NULL after abort AEN
+                       **/
+                       instance->aen_cmd = NULL;
                }
        }

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-02-12 15:52:28.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-02-12 15:24:58.000000000 -0500
@@ -30,6 +30,8 @@
 #define        PCI_DEVICE_ID_LSI_VERDE_ZCR             0x0413
 #define        PCI_DEVICE_ID_LSI_SAS1078GEN2           0x0078
 #define        PCI_DEVICE_ID_LSI_SAS0079GEN2           0x0079
+#define        PCI_DEVICE_ID_LSI_SAS0073SKINNY         0x0073
+#define        PCI_DEVICE_ID_LSI_SAS0071SKINNY         0x0071

 /*
  * =====================================
@@ -594,6 +596,9 @@ struct megasas_ctrl_info {
 #define MFI_REPLY_1078_MESSAGE_INTERRUPT       0x80000000
 #define MFI_REPLY_GEN2_MESSAGE_INTERRUPT       0x00000001
 #define MFI_GEN2_ENABLE_INTERRUPT_MASK         (0x00000001 | 0x00000004)
+#define MFI_REPLY_SKINNY_MESSAGE_INTERRUPT     0x40000000
+#define MFI_SKINNY_ENABLE_INTERRUPT_MASK       (0x00000001 | 0x00000008)
+

 /*
 * register set for both 1068 and 1078 controllers

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 5/9] scsi: megaraid_sas - Add memory support required by 0x73 controller
  2009-02-17 15:51                   ` [PATCH 4/9] scsi: megaraid_sas - Add new controller 0x73(new SAS2) support to the driver Yang, Bo
@ 2009-02-17 16:37                     ` Yang, Bo
  2009-02-17 17:09                       ` [PATCH 6/9] scsi: megaraid_sas - Report the unconfigured PD (system PD) to OS Yang, Bo
  2009-02-19  0:30                       ` [PATCH 5/9] scsi: megaraid_sas - Add memory support required by 0x73 controller Andrew Morton
  0 siblings, 2 replies; 40+ messages in thread
From: Yang, Bo @ 2009-02-17 16:37 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley, linux-scsi, akpm, linux-kernel
  Cc: Austria, Winston

Add memory support required by 0x73 controller

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
drivers/scsi/megaraid/megaraid_sas.c |  164 +++++++++++++++++++++++++++++++++++
 drivers/scsi/megaraid/megaraid_sas.h |   19 ++++
 2 files changed, 183 insertions(+)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-02-12 16:05:07.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-02-12 16:12:54.000000000 -0500
@@ -2039,6 +2039,144 @@ static int megasas_alloc_cmds(struct meg
 }

 /**
+ * megasas_skinny_mem_alloc:   allocation memory for 0x73 and 0x71 controller
+ * @instance:                  Adapter soft state
+ *
+ * this function will allocate the memory for 0.73 comtroller.
+ */
+static int
+megasas_skinny_mem_alloc(struct megasas_instance *instance)
+{
+       u8              i = 0, mem_alloc_done = 0;
+       u32             *virt, ind, num_bk = 0;
+       dma_addr_t      paddr;
+       u32              mem_alloc_size = MEGASAS_SKINNY_SZ_MEM_BK * 256;
+       u32             *mem_tb = instance->skinny_mm_tb;
+
+       instance->skinny_mm_tb = pci_alloc_consistent(instance->pdev,
+                                MEGASAS_SKINNY_MAX_NUM_MEM_BK*sizeof(u32),
+                                &instance->skinny_mm_tb_h);
+
+       memset(instance->skinny_mm_tb, 0,
+               MEGASAS_SKINNY_MAX_NUM_MEM_BK * sizeof(u32));
+
+       instance->skinny_mm_alloc_ind = 0;
+
+       while (!mem_alloc_done) {
+
+                       virt = pci_alloc_consistent(instance->pdev,
+                                                        mem_alloc_size,
+                                                        &paddr);
+                       if (virt) {
+                               num_bk = (mem_alloc_size/
+                                               MEGASAS_SKINNY_SZ_MEM_BK);
+
+                               for (ind = 0; ind < num_bk; ind++) {
+                                       if (instance->skinny_mm_alloc_ind <
+                                               MEGASAS_SKINNY_MAX_NUM_MEM_BK) {
+                                               *mem_tb = (u32)(paddr+
+                                               (MEGASAS_SKINNY_SZ_MEM_BK*ind));
+                                               mem_tb++;
+                                               instance->skinny_mm_alloc_ind++;
+                                       } else {
+                                               mem_alloc_done = 1;
+                                       }
+                               }
+
+                               instance->skinny_mm_bk[i].vir   = virt;
+                               instance->skinny_mm_bk[i].paddr = paddr;
+                               instance->skinny_mm_bk[i].sz = mem_alloc_size;
+                       } else {
+                               if (mem_alloc_size > MEGASAS_SKINNY_SZ_MEM_BK)
+                                       mem_alloc_size = mem_alloc_size / 2;
+                       }
+       }
+
+       if (instance->skinny_mm_alloc_ind == 0)
+               return -1;
+
+       return 0;
+}
+
+/**
+ * megasas_skinny_mem_alloc:   de-allocate memory for 0x73 and 0x71 controller
+ * @instance:                  Adapter soft state
+ *
+ * this function will de-allocate the memory for 0.73 comtroller.
+ */
+static void
+megasas_skinny_mem_dealloc(struct megasas_instance *instance)
+{
+       int i = 0;
+
+       for (i = 0; i < MEGASAS_SKINNY_MAX_NUM_MEM_BK; i++) {
+               if (instance->skinny_mm_bk[i].vir) {
+                       pci_free_consistent(instance->pdev,
+                               instance->skinny_mm_bk[i].sz,
+                               instance->skinny_mm_bk[i].vir,
+                               instance->skinny_mm_bk[i].paddr);
+               }
+       }
+
+       if (instance->skinny_mm_tb)
+               pci_free_consistent(instance->pdev,
+                       MEGASAS_SKINNY_MAX_NUM_MEM_BK * sizeof(u32),
+                       instance->skinny_mm_tb,
+                       instance->skinny_mm_tb_h);
+
+}
+
+/**
+ * megasas_mem_to_fw - Send requested memory to FW
+ * @instance:          Adapter soft state
+ *
+ * Issues an internal command (DCMD) to get the FW's controller structure.
+ * This information is mainly used to send out the memory table  to FW
+ */
+static int
+megasas_mem_to_fw(struct megasas_instance *instance)
+{
+       int ret = 0;
+       struct megasas_cmd *cmd;
+       struct megasas_dcmd_frame *dcmd;
+
+       cmd = megasas_get_cmd(instance);
+
+       if (!cmd) {
+               printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
+               return -ENOMEM;
+       }
+
+       dcmd = &cmd->frame->dcmd;
+
+       memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+       dcmd->mbox.s[0] = instance->skinny_mm_alloc_ind;
+       dcmd->mbox.s[2] = MEGASAS_SKINNY_SZ_MEM_BK / 1024;
+
+       dcmd->cmd = MFI_CMD_DCMD;
+       dcmd->cmd_status = 0xFF;
+       dcmd->sge_count = 1;
+       dcmd->flags = MFI_FRAME_DIR_READ;
+       dcmd->timeout = 0;
+       dcmd->data_xfer_len = sizeof(u32) * MEGASAS_SKINNY_MAX_NUM_MEM_BK;
+       dcmd->opcode = MR_DCMD_CTRL_MFI_HOST_MEM_ALLOC;
+       dcmd->sgl.sge32[0].phys_addr = instance->skinny_mm_tb_h;
+       dcmd->sgl.sge32[0].length = sizeof(u32) * MEGASAS_SKINNY_MAX_NUM_MEM_BK;
+
+       if (!megasas_issue_polled(instance, cmd)) {
+               ret = 0;
+
+       } else {
+               ret = -1;
+       }
+
+       megasas_return_cmd(instance, cmd);
+
+       return ret;
+}
+
+/**
  * megasas_get_controller_info -       Returns FW's controller structure
  * @instance:                          Adapter soft state
  * @ctrl_info:                         Controller information structure
@@ -2290,6 +2428,9 @@ static int megasas_init_mfi(struct megas
         * Get various operational parameters from status register
         */
        instance->max_fw_cmds = instance->instancet->read_fw_status_reg(reg_set) & 0x00FFFF;
+       instance->memory_need =
+               instance->instancet->read_fw_status_reg(reg_set) & 0x08000000;
+
        /*
         * Reduce the max supported cmds by 1. This is to ensure that the
         * reply_q_sz (1 more than the max cmd that driver may send)
@@ -2325,6 +2466,25 @@ static int megasas_init_mfi(struct megas
                goto fail_reply_queue;
        }

+       if (instance->memory_need) {
+               if ((instance->pdev->device ==
+                       PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+                       (instance->pdev->device ==
+                       PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+
+                       if (megasas_skinny_mem_alloc(instance)) {
+                               printk(KERN_DEBUG "megasas: failed "
+                                               "allocate mem\n");
+                               megasas_skinny_mem_dealloc(instance);
+                       }
+
+                       if (megasas_mem_to_fw(instance)) {
+                               printk(KERN_DEBUG "megasas: fail to "
+                                       "dcmd cmd to pass mem to fw\n");
+                       }
+               }
+       }
+
        if (megasas_issue_init_mfi(instance))
                goto fail_fw_init;

@@ -3110,6 +3270,10 @@ static void __devexit megasas_detach_one

        free_irq(instance->pdev->irq, instance);

+       if (instance->memory_need) {
+               megasas_skinny_mem_dealloc(instance);
+       }
+
        megasas_release_mfi(instance);

        pci_free_consistent(pdev, sizeof(struct megasas_evt_detail),
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-02-12 16:05:08.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-02-12 15:24:58.000000000 -0500
@@ -1092,6 +1092,16 @@ struct megasas_aen_event {
        struct megasas_instance *instance;
 };

+#define MR_DCMD_CTRL_MFI_HOST_MEM_ALLOC                0x0100e100
+#define MEGASAS_SKINNY_SZ_MEM_BK               (64*1024)
+#define MEGASAS_SKINNY_MAX_NUM_MEM_BK          512
+
+struct megasas_skinny_mm_bk {
+       u32                     vir;
+       u32                     sz;
+       dma_addr_t              paddr;
+};
+
 struct megasas_instance {

        u32 *producer;
@@ -1105,6 +1115,15 @@ struct megasas_instance {
        unsigned long base_addr;
        struct megasas_register_set __iomem *reg_set;

+       u32 *skinny_mm_tb;
+       dma_addr_t skinny_mm_tb_h;
+
+       struct megasas_skinny_mm_bk skinny_mm_bk[MEGASAS_SKINNY_MAX_NUM_MEM_BK];
+
+       u32 skinny_mm_alloc_ind;
+       struct megasas_pd_list pd_list[MEGASAS_MAX_PD];
+
+       u8 memory_need;
        s8 init_id;

        u16 max_num_sge;

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 6/9] scsi: megaraid_sas - Report the unconfigured PD (system PD) to OS
  2009-02-17 16:37                     ` [PATCH 5/9] scsi: megaraid_sas - Add memory support required by 0x73 controller Yang, Bo
@ 2009-02-17 17:09                       ` Yang, Bo
  2009-02-17 17:21                         ` [PATCH 7/9] scsi: megaraid_sas - Resign the Application cmds to 0x73 (new SAS2) controller Yang, Bo
  2009-02-19  0:30                       ` [PATCH 5/9] scsi: megaraid_sas - Add memory support required by 0x73 controller Andrew Morton
  1 sibling, 1 reply; 40+ messages in thread
From: Yang, Bo @ 2009-02-17 17:09 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley, linux-scsi, akpm, linux-kernel
  Cc: Austria, Winston

Add the support for reporting the unconfigured PD (system PD) to OS in MegaRAID SAS driver

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
drivers/scsi/megaraid/megaraid_sas.c |  148 ++++++++++++++++++++++++++++++++++-
 drivers/scsi/megaraid/megaraid_sas.h |   92 +++++++++++++++++++++
 2 files changed, 237 insertions(+), 3 deletions(-)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-02-12 16:16:42.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-02-12 16:24:41.000000000 -0500
@@ -1119,6 +1119,11 @@ megasas_queue_command(struct scsi_cmnd *

 static int megasas_slave_configure(struct scsi_device *sdev)
 {
+       u16             pd_index = 0;
+       struct  megasas_instance *instance ;
+
+       instance = megasas_lookup_instance(sdev->host->host_no);
+
        /*
         * Don't export physical disk devices to the disk driver.
         *
@@ -1126,7 +1131,17 @@ static int megasas_slave_configure(struc
         *        That will be fixed once LSI engineers have audited the
         *        firmware for possible issues.
         */
-       if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && sdev->type == TYPE_DISK)
+       if (sdev->channel < MEGASAS_MAX_PD_CHANNELS &&
+                               sdev->type == TYPE_DISK) {
+               pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
+                               sdev->id;
+
+               if (instance->pd_list[pd_index].driveState ==
+                               MR_PD_STATE_SYSTEM) {
+                       sdev->timeout = 90 * HZ;
+                       return 0;
+               }
+
                return -ENXIO;

        /*
@@ -1423,6 +1438,29 @@ megasas_service_aen(struct megasas_insta
        megasas_return_cmd(instance, cmd);
 }

+static int megasas_slave_alloc(struct scsi_device *sdev)
+{
+       u16             pd_index = 0;
+       struct megasas_instance *instance ;
+       instance = megasas_lookup_instance(sdev->host->host_no);
+
+       if (sdev->channel < MEGASAS_MAX_PD_CHANNELS) {
+               /*
+                * Open the OS scan to the SYSTEM PD
+                */
+               pd_index =
+                   (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) + sdev->id;
+               if ((instance->pd_list[pd_index].driveState ==
+                       MR_PD_STATE_SYSTEM) &&
+                       (instance->pd_list[pd_index].driveType ==
+                       TYPE_DISK)) {
+                       return 0;
+               }
+
+               return -ENXIO;
+       }
+       return 0;
+}
 /*
  * Scsi host template for megaraid_sas driver
  */
@@ -1432,6 +1470,7 @@ static struct scsi_host_template megasas
        .name = "LSI SAS based MegaRAID driver",
        .proc_name = "megaraid_sas",
        .slave_configure = megasas_slave_configure,
+       .slave_alloc = megasas_slave_alloc,
        .queuecommand = megasas_queue_command,
        .eh_device_reset_handler = megasas_reset_device,
        .eh_bus_reset_handler = megasas_reset_bus_host,
@@ -2143,7 +2182,7 @@ megasas_mem_to_fw(struct megasas_instanc
        cmd = megasas_get_cmd(instance);

        if (!cmd) {
-               printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
+               printk(KERN_DEBUG "megasas (mem_to_fw): Failed to get cmd\n");
                return -ENOMEM;
        }

@@ -2152,7 +2191,7 @@ megasas_mem_to_fw(struct megasas_instanc
        memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);

        dcmd->mbox.s[0] = instance->skinny_mm_alloc_ind;
-       dcmd->mbox.s[2] = MEGASAS_SKINNY_SZ_MEM_BK / 1024;
+       dcmd->mbox.s[2] = MEGASAS_SKINNY_SZ_MEM_BK/1024;

        dcmd->cmd = MFI_CMD_DCMD;
        dcmd->cmd_status = 0xFF;
@@ -2177,6 +2216,100 @@ megasas_mem_to_fw(struct megasas_instanc
 }

 /**
+ * megasas_get_pd_list_info -  Returns FW's pd_list structure
+ * @instance:                          Adapter soft state
+ * @pd_list:                           pd_list structure
+ *
+ * Issues an internal command (DCMD) to get the FW's controller PD
+ * list structure.  This information is mainly used to find out SYSTEM
+ * supported by the FW.
+ */
+static int
+megasas_get_pd_list(struct megasas_instance *instance)
+{
+       int ret = 0, pd_index = 0;
+       struct megasas_cmd *cmd;
+       struct megasas_dcmd_frame *dcmd;
+       struct MR_PD_LIST *ci;
+       struct MR_PD_ADDRESS *pd_addr;
+       dma_addr_t ci_h = 0;
+
+       cmd = megasas_get_cmd(instance);
+
+       if (!cmd) {
+               printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
+               return -ENOMEM;
+       }
+
+       dcmd = &cmd->frame->dcmd;
+
+       ci = pci_alloc_consistent(instance->pdev,
+                 MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h);
+
+       if (!ci) {
+               printk(KERN_DEBUG "Failed to alloc mem for pd_list\n");
+               megasas_return_cmd(instance, cmd);
+               return -ENOMEM;
+       }
+
+       memset(ci, 0, sizeof(*ci));
+       memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+       dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
+       dcmd->mbox.b[1] = 0;
+       dcmd->cmd = MFI_CMD_DCMD;
+       dcmd->cmd_status = 0xFF;
+       dcmd->sge_count = 1;
+       dcmd->flags = MFI_FRAME_DIR_READ;
+       dcmd->timeout = 0;
+       dcmd->data_xfer_len = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
+       dcmd->opcode = MR_DCMD_PD_LIST_QUERY;
+       dcmd->sgl.sge32[0].phys_addr = ci_h;
+       dcmd->sgl.sge32[0].length = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
+
+       if (!megasas_issue_polled(instance, cmd)) {
+               ret = 0;
+
+       } else {
+               ret = -1;
+       }
+
+       /*
+       * the following function will get the instance PD LIST.
+       */
+
+       pd_addr = ci->addr;
+
+       if ( ret == 0 &&
+               (ci->count <
+                 (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) {
+
+               memset(instance->pd_list, 0,
+                       MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
+
+               for (pd_index = 0; pd_index < ci->count; pd_index++) {
+
+                       instance->pd_list[pd_addr->deviceId].tid        =
+                                                       pd_addr->deviceId;
+                       instance->pd_list[pd_addr->deviceId].driveType  =
+                                                       pd_addr->scsiDevType;
+                       instance->pd_list[pd_addr->deviceId].driveState =
+                                                       MR_PD_STATE_SYSTEM;
+
+                       pd_addr++;
+               }
+
+       }
+
+       pci_free_consistent(instance->pdev, sizeof(struct megasas_ctrl_info),
+                           ci, ci_h);
+
+       megasas_return_cmd(instance, cmd);
+
+       return ret;
+}
+
+/**
  * megasas_get_controller_info -       Returns FW's controller structure
  * @instance:                          Adapter soft state
  * @ctrl_info:                         Controller information structure
@@ -2488,6 +2621,15 @@ static int megasas_init_mfi(struct megas
        if (megasas_issue_init_mfi(instance))
                goto fail_fw_init;

+       /**
+       * for passthrough
+       * the following function will get the PD LIST.
+       **/
+
+       memset(instance->pd_list, 0,
+               MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
+       megasas_get_pd_list(instance);
+
        ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);

        /*
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-02-12 16:16:43.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-02-12 15:24:58.000000000 -0500
@@ -133,6 +133,7 @@
 #define MR_DCMD_CLUSTER                                0x08000000
 #define MR_DCMD_CLUSTER_RESET_ALL              0x08010100
 #define MR_DCMD_CLUSTER_RESET_LD               0x08010200
+#define MR_DCMD_PD_LIST_QUERY                  0x02010100

 #define MR_EVT_CFG_CLEARED                     0x0004

@@ -263,9 +264,98 @@ enum MR_EVT_ARGS {
        MR_EVT_ARGS_STR,
        MR_EVT_ARGS_TIME,
        MR_EVT_ARGS_ECC,
+       MR_EVT_ARGS_LD_PROP,
+       MR_EVT_ARGS_PD_SPARE,
+       MR_EVT_ARGS_PD_INDEX,
+       MR_EVT_ARGS_DIAG_PASS,
+       MR_EVT_ARGS_DIAG_FAIL,
+       MR_EVT_ARGS_PD_LBA_LBA,
+       MR_EVT_ARGS_PORT_PHY,
+       MR_EVT_ARGS_PD_MISSING,
+       MR_EVT_ARGS_PD_ADDRESS,
+       MR_EVT_ARGS_BITMAP,
+       MR_EVT_ARGS_CONNECTOR,
+       MR_EVT_ARGS_PD_PD,
+       MR_EVT_ARGS_PD_FRU,
+       MR_EVT_ARGS_PD_PATHINFO,
+       MR_EVT_ARGS_PD_POWER_STATE,
+       MR_EVT_ARGS_GENERIC,
+};

+/*
+ * define constants for device list query options
+ */
+enum MR_PD_QUERY_TYPE {
+    MR_PD_QUERY_TYPE_ALL                = 0,
+    MR_PD_QUERY_TYPE_STATE              = 1,
+    MR_PD_QUERY_TYPE_POWER_STATE        = 2,
+    MR_PD_QUERY_TYPE_MEDIA_TYPE         = 3,
+    MR_PD_QUERY_TYPE_SPEED              = 4,
+    MR_PD_QUERY_TYPE_EXPOSED_TO_HOST    = 5,
+} __attribute__ ((packed));
+
+#define MR_EVT_CFG_CLEARED                             0x0004
+#define MR_EVT_LD_STATE_CHANGE                         0x0051
+#define MR_EVT_PD_INSERTED                             0x005b
+#define MR_EVT_PD_REMOVED                              0x0070
+#define MR_EVT_LD_CREATED                              0x008a
+#define MR_EVT_LD_DELETED                              0x008b
+#define MR_EVT_FOREIGN_CFG_IMPORTED                    0x00db
+#define MR_EVT_LD_OFFLINE                              0x00fc
+#define MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED            0x0152
+
+
+enum MR_PD_STATE {
+    MR_PD_STATE_UNCONFIGURED_GOOD   = 0x00,
+    MR_PD_STATE_UNCONFIGURED_BAD    = 0x01,
+    MR_PD_STATE_HOT_SPARE           = 0x02,
+    MR_PD_STATE_OFFLINE             = 0x10,
+    MR_PD_STATE_FAILED              = 0x11,
+    MR_PD_STATE_REBUILD             = 0x14,
+    MR_PD_STATE_ONLINE              = 0x18,
+    MR_PD_STATE_COPYBACK            = 0x20,
+    MR_PD_STATE_SYSTEM              = 0x40,
 };

+ /*
+ * defines the physical drive address structure
+ */
+struct MR_PD_ADDRESS {
+       u16     deviceId;
+       u16     enclDeviceId;
+       union {
+               struct {
+                       u8  enclIndex;
+                       u8  slotNumber;
+               } mrPdAddress;
+               struct {
+                       u8  enclPosition;
+                       u8  enclConnectorIndex;
+               } mrEnclAddress;
+       };
+       u8      scsiDevType;
+       union {
+               u8      connectedPortBitmap;
+               u8      connectedPortNumbers;
+       };
+       u64     sasAddr[2];
+} __attribute__ ((packed));
+
+/*
+ * defines the physical drive list structure
+ */
+struct MR_PD_LIST {
+    u32             size;
+    u32             count;
+    struct MR_PD_ADDRESS   addr[1];
+} __attribute__ ((packed));
+
+struct megasas_pd_list {
+    u16             tid;
+    u8             driveType;
+    u8             driveState;
+} __attribute__ ((packed));
+
 /*
  * SAS controller properties
  */
@@ -552,6 +642,8 @@ struct megasas_ctrl_info {
 #define MEGASAS_DEFAULT_INIT_ID                        -1
 #define MEGASAS_MAX_LUN                                8
 #define MEGASAS_MAX_LD                         64
+#define MEGASAS_MAX_PD                         (MEGASAS_MAX_PD_CHANNELS * \
+                                               MEGASAS_MAX_DEV_PER_CHANNEL)

 #define MEGASAS_DBG_LVL                                1

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 7/9] scsi: megaraid_sas - Resign the Application cmds to 0x73 (new SAS2) controller
  2009-02-17 17:09                       ` [PATCH 6/9] scsi: megaraid_sas - Report the unconfigured PD (system PD) to OS Yang, Bo
@ 2009-02-17 17:21                         ` Yang, Bo
  2009-02-17 17:31                           ` [PATCH 8/9] scsi: megaraid_sas - Add the IEEE SGL support to the driver Yang, Bo
  0 siblings, 1 reply; 40+ messages in thread
From: Yang, Bo @ 2009-02-17 17:21 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley, linux-scsi, akpm, linux-kernel
  Cc: Austria, Winston

Resign the Application cmds to new SAS2 controller

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
drivers/scsi/megaraid/megaraid_sas.c |   23 ++++++++++++++++++++---
 drivers/scsi/megaraid/megaraid_sas.h |    1 +
 2 files changed, 21 insertions(+), 3 deletions(-)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-02-12 16:27:20.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-02-12 16:32:34.000000000 -0500
@@ -1204,7 +1204,14 @@ static void megasas_complete_cmd_dpc(uns

                spin_lock_irqsave(instance->host->host_lock, flags);
                instance->flag &= ~MEGASAS_FW_BUSY;
-               instance->host->can_queue =
+               if ((instance->pdev->device ==
+                       PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+                       (instance->pdev->device ==
+                       PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+                       instance->host->can_queue =
+                               instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
+               } else
+                       instance->host->can_queue =
                                instance->max_fw_cmds - MEGASAS_INT_CMDS;

                spin_unlock_irqrestore(instance->host->host_lock, flags);
@@ -2933,7 +2940,13 @@ static int megasas_io_attach(struct mega
         */
        host->irq = instance->pdev->irq;
        host->unique_id = instance->unique_id;
-       host->can_queue = instance->max_fw_cmds - MEGASAS_INT_CMDS;
+       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+               (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+               host->can_queue =
+                       instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
+       } else
+               host->can_queue =
+                       instance->max_fw_cmds - MEGASAS_INT_CMDS;
        host->this_id = instance->init_id;
        host->sg_tablesize = instance->max_num_sge;
        host->max_sectors = instance->max_sectors_per_req;
@@ -3066,7 +3079,11 @@ megasas_probe_one(struct pci_dev *pdev,
        spin_lock_init(&instance->completion_lock);

        mutex_init(&instance->aen_mutex);
-       sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
+       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+               (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+               sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
+       } else
+               sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);

        /*
         * Initialize PCI related and misc parameters
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-02-12 16:27:21.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-02-12 15:24:58.000000000 -0500
@@ -674,6 +674,7 @@ struct megasas_ctrl_info {
  * is shown below
  */
 #define MEGASAS_INT_CMDS                       32
+#define MEGASAS_SKINNY_INT_CMDS                        5

 /*
  * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 8/9] scsi: megaraid_sas - Add the IEEE SGL support to the driver
  2009-02-17 17:21                         ` [PATCH 7/9] scsi: megaraid_sas - Resign the Application cmds to 0x73 (new SAS2) controller Yang, Bo
@ 2009-02-17 17:31                           ` Yang, Bo
  2009-02-17 17:50                             ` [PATCH 9/9] scsi: megaraid_sas - Update the Version and ChangeLog Yang, Bo
  2009-02-19  0:38                             ` [PATCH 8/9] scsi: megaraid_sas - Add the IEEE SGL support to the driver Andrew Morton
  0 siblings, 2 replies; 40+ messages in thread
From: Yang, Bo @ 2009-02-17 17:31 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley, linux-scsi, akpm, linux-kernel
  Cc: Austria, Winston

Add the IEEE SGL support to MegaRAID SAS driver

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
drivers/scsi/megaraid/megaraid_sas.c |  125 ++++++++++++++++++++++++++---------
 drivers/scsi/megaraid/megaraid_sas.h |   13 +++
 2 files changed, 107 insertions(+), 31 deletions(-)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-02-12 16:36:41.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-02-12 17:24:26.000000000 -0500
@@ -698,6 +698,35 @@ megasas_make_sgl64(struct megasas_instan
        return sge_count;
 }

+/**
+ * megasas_make_sgl64 -        Prepares 64-bit SGL
+ * @instance:          Adapter soft state
+ * @scp:               SCSI command from the mid-layer
+ * @mfi_sgl:           SGL to be filled in
+ *
+ * If successful, this function returns the number of SG elements. Otherwise,
+ * it returnes -1.
+ */
+static int
+megasas_make_sgl_skinny(struct megasas_instance *instance,
+               struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl)
+{
+       int i;
+       int sge_count;
+       struct scatterlist *os_sgl;
+
+       sge_count = scsi_dma_map(scp);
+       BUG_ON(sge_count < 0);
+
+       if (sge_count) {
+               scsi_for_each_sg(scp, os_sgl, sge_count, i) {
+                 mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl);
+                 mfi_sgl->sge_skinny[i].phys_addr = sg_dma_address(os_sgl);
+               }
+       }
+       return sge_count;
+}
+
  /**
  * megasas_get_frame_count - Computes the number of frames
  * @frame_type         : type of frame- io or pthru frame
@@ -706,7 +735,8 @@ megasas_make_sgl64(struct megasas_instan
  * Returns the number of frames required for numnber of sge's (sge_count)
  */

-static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type)
+static u32 megasas_get_frame_count(struct megasas_instance *instance,
+                       u8 sge_count, u8 frame_type)
 {
        int num_cnt;
        int sge_bytes;
@@ -716,6 +746,10 @@ static u32 megasas_get_frame_count(u8 sg
        sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
            sizeof(struct megasas_sge32);

+       if (instance->flag_ieee) {
+               sge_sz = sizeof(struct megasas_sge_skinny);
+       }
+
        /*
         * Main frame can contain 2 SGEs for 64-bit SGLs and
         * 3 SGEs for 32-bit SGLs for ldio &
@@ -723,12 +757,16 @@ static u32 megasas_get_frame_count(u8 sg
         * 2 SGEs for 32-bit SGLs for pthru frame
         */
        if (unlikely(frame_type == PTHRU_FRAME)) {
-               if (IS_DMA64)
+               if (instance->flag_ieee == 1) {
+                       num_cnt = sge_count - 1;
+               } else if (IS_DMA64)
                        num_cnt = sge_count - 1;
                else
                        num_cnt = sge_count - 2;
        } else {
-               if (IS_DMA64)
+               if (instance->flag_ieee == 1) {
+                       num_cnt = sge_count - 1;
+               } else if (IS_DMA64)
                        num_cnt = sge_count - 2;
                else
                        num_cnt = sge_count - 3;
@@ -777,6 +815,10 @@ megasas_build_dcdb(struct megasas_instan
        else if (scp->sc_data_direction == PCI_DMA_NONE)
                flags = MFI_FRAME_DIR_NONE;

+       if (instance->flag_ieee == 1) {
+               flags = MFI_FRAME_IEEE;
+       }
+
        /*
         * Prepare the DCDB frame
         */
@@ -806,7 +848,12 @@ megasas_build_dcdb(struct megasas_instan
        /*
         * Construct SGL
         */
-       if (IS_DMA64) {
+       if (instance->flag_ieee == 1) {
+               pthru->flags |= MFI_FRAME_SGL64;
+               pthru->sge_count = megasas_make_sgl_skinny(instance, scp,
+                                                     &pthru->sgl);
+
+       } else if (IS_DMA64) {
                pthru->flags |= MFI_FRAME_SGL64;
                pthru->sge_count = megasas_make_sgl64(instance, scp,
                                                      &pthru->sgl);
@@ -825,7 +872,7 @@ megasas_build_dcdb(struct megasas_instan
         * Compute the total number of frames this command consumes. FW uses
         * 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(instance, pthru->sge_count,
                                                        PTHRU_FRAME);

        return cmd->frame_count;
@@ -856,6 +903,10 @@ megasas_build_ldio(struct megasas_instan
        else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
                flags = MFI_FRAME_DIR_READ;

+       if (instance->flag_ieee == 1) {
+               flags = MFI_FRAME_IEEE;
+       }
+
        /*
         * Prepare the Logical IO frame: 2nd bit is zero for all read cmds
         */
@@ -926,7 +977,11 @@ megasas_build_ldio(struct megasas_instan
        /*
         * Construct SGL
         */
-       if (IS_DMA64) {
+       if (instance->flag_ieee) {
+               ldio->flags |= MFI_FRAME_SGL64;
+               ldio->sge_count = megasas_make_sgl_skinny(instance, scp,
+                                             &ldio->sgl);
+       } else if (IS_DMA64) {
                ldio->flags |= MFI_FRAME_SGL64;
                ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
        } else
@@ -943,7 +998,8 @@ megasas_build_ldio(struct megasas_instan
         * Compute the total number of frames this command consumes. FW uses
         * this number to pull sufficient number of frames from host memory.
         */
-       cmd->frame_count = megasas_get_frame_count(ldio->sge_count, IO_FRAME);
+       cmd->frame_count = megasas_get_frame_count(instance,
+                       ldio->sge_count, IO_FRAME);

        return cmd->frame_count;
 }
@@ -1117,6 +1173,20 @@ megasas_queue_command(struct scsi_cmnd *
        return 0;
 }

+static struct megasas_instance *megasas_lookup_instance(u16 host_no)
+{
+       int i;
+
+       for (i = 0; i < megasas_mgmt_info.max_index; i++) {
+
+               if ((megasas_mgmt_info.instance[i]) &&
+                   (megasas_mgmt_info.instance[i]->host->host_no == host_no))
+                       return megasas_mgmt_info.instance[i];
+       }
+
+       return NULL;
+}
+
 static int megasas_slave_configure(struct scsi_device *sdev)
 {
        u16             pd_index = 0;
@@ -1143,6 +1213,7 @@ static int megasas_slave_configure(struc
                }

                return -ENXIO;
+       }

        /*
         * The RAID firmware may require extended timeouts.
@@ -1405,7 +1476,7 @@ megasas_bios_param(struct scsi_device *s
        return 0;
 }

-static void megasas_aen_polling(void *arg);
+static void megasas_aen_polling(struct work_struct *work);

 /**
  * megasas_service_aen -       Processes an event notification
@@ -1433,7 +1504,8 @@ megasas_service_aen(struct megasas_insta
                } else {
                        ev->instance = instance;
                        INIT_WORK(&ev->hotplug_work, megasas_aen_polling);
-                       schedule_delayed_work(&ev->hotplug_work, 0);
+                       schedule_delayed_work(
+                               (struct delayed_work *)&ev->hotplug_work, 0);
                }
                megasas_poll_wait_aen = 1;
                wake_up(&megasas_poll_wait);
@@ -1917,6 +1989,10 @@ static int megasas_create_frame_pool(str
        sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
            sizeof(struct megasas_sge32);

+       if (instance->flag_ieee) {
+               sge_sz = sizeof(struct megasas_sge_skinny);
+       }
+
        /*
         * Calculated the number of 64byte frames required for SGL
         */
@@ -3053,6 +3129,7 @@ megasas_probe_one(struct pci_dev *pdev,

        *instance->producer = 0;
        *instance->consumer = 0;
+       instance->flag_ieee = 0;

        instance->evt_detail = pci_alloc_consistent(pdev,
                                                    sizeof(struct
@@ -3079,11 +3156,6 @@ megasas_probe_one(struct pci_dev *pdev,
        spin_lock_init(&instance->completion_lock);

        mutex_init(&instance->aen_mutex);
-       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
-               (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
-               sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
-       } else
-               sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);

        /*
         * Initialize PCI related and misc parameters
@@ -3093,6 +3165,13 @@ megasas_probe_one(struct pci_dev *pdev,
        instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
        instance->init_id = MEGASAS_DEFAULT_INIT_ID;

+       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+               (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+               instance->flag_ieee = 1;
+               sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
+       } else
+               sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
+
        megasas_dbg_lvl = 0;
        instance->flag = 0;
        instance->unload = 0;
@@ -3683,20 +3762,6 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
        return error;
 }

-static struct megasas_instance *megasas_lookup_instance(u16 host_no)
-{
-       int i;
-
-       for (i = 0; i < megasas_mgmt_info.max_index; i++) {
-
-               if ((megasas_mgmt_info.instance[i]) &&
-                   (megasas_mgmt_info.instance[i]->host->host_no == host_no))
-                       return megasas_mgmt_info.instance[i];
-       }
-
-       return NULL;
-}
-
 static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
 {
        struct megasas_iocpacket __user *user_ioc =
@@ -4043,12 +4108,12 @@ megasas_aen_polling(struct work_struct *
        class_locale.members.locale = MR_EVT_LOCALE_ALL;
        class_locale.members.class = MR_EVT_CLASS_DEBUG;

-       down(&instance->aen_mutex);
+       mutex_lock(&instance->aen_mutex);

        error = megasas_register_aen(instance, seq_num,
                                class_locale.word);

-       up(&instance->aen_mutex);
+       mutex_unlock(&instance->aen_mutex);

        if (error)
                printk(KERN_ERR "%s[%d]: register aen failed error %x\n",
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-02-12 16:36:42.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-02-12 16:53:50.000000000 -0500
@@ -96,6 +96,7 @@
 #define MFI_FRAME_DIR_WRITE                    0x0008
 #define MFI_FRAME_DIR_READ                     0x0010
 #define MFI_FRAME_DIR_BOTH                     0x0018
+#define MFI_FRAME_IEEE                         0x0020

 /*
  * Definition for cmd_status
@@ -752,10 +753,19 @@ struct megasas_sge64 {

 } __attribute__ ((packed));

+struct megasas_sge_skinny {
+
+       u64 phys_addr;
+       u32 length;
+       u32 flag;
+
+} __attribute__ ((packed));
+
 union megasas_sgl {

        struct megasas_sge32 sge32[1];
        struct megasas_sge64 sge64[1];
+       struct megasas_sge64 sge_skinny[1];

 } __attribute__ ((packed));

@@ -1190,7 +1200,7 @@ struct megasas_aen_event {
 #define MEGASAS_SKINNY_MAX_NUM_MEM_BK          512

 struct megasas_skinny_mm_bk {
-       u32                     vir;
+       u32                     *vir;
        u32                     sz;
        dma_addr_t              paddr;
 };
@@ -1253,6 +1263,7 @@ struct megasas_instance {

        u8 flag;
        u8 unload;
+       u8 flag_ieee;
        unsigned long last_time;

        struct timer_list io_completion_timer;

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 9/9] scsi: megaraid_sas - Update the Version and ChangeLog
  2009-02-17 17:31                           ` [PATCH 8/9] scsi: megaraid_sas - Add the IEEE SGL support to the driver Yang, Bo
@ 2009-02-17 17:50                             ` Yang, Bo
  2009-02-19  0:38                             ` [PATCH 8/9] scsi: megaraid_sas - Add the IEEE SGL support to the driver Andrew Morton
  1 sibling, 0 replies; 40+ messages in thread
From: Yang, Bo @ 2009-02-17 17:50 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley, linux-scsi, akpm, linux-kernel
  Cc: Austria, Winston

Update the Version and ChangeLog

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
Documentation/scsi/ChangeLog.megaraid_sas |   25 +++++++++++++++++++++++++
 drivers/scsi/megaraid/megaraid_sas.c      |    2 +-
 drivers/scsi/megaraid/megaraid_sas.h      |    6 +++---
 3 files changed, 29 insertions(+), 4 deletions(-)

diff -rupN linux-2.6.28_orig/Documentation/scsi/ChangeLog.megaraid_sas linux-2.6.28_new/Documentation/scsi/ChangeLog.megaraid_sas
--- linux-2.6.28_orig/Documentation/scsi/ChangeLog.megaraid_sas 2009-02-12 17:30:44.000000000 -0500
+++ linux-2.6.28_new/Documentation/scsi/ChangeLog.megaraid_sas  2009-02-12 15:24:58.000000000 -0500
@@ -1,4 +1,29 @@

+1 Release Date    : Tues. Feb. 10, 2009 10:12:45 PST 2009 -
+                        (emaild-id:megaraidlinux@lsi.com)
+                        Bo Yang
+
+2 Current Version : 00.00.04.03
+3 Older Version   : 00.00.04.01
+
+1.     Add the Tape drive fix to the driver: If the command is for the tape device, set the
+       pthru timeout to the os layer timeout value.
+
+2.     Add Poll_wait mechanism to Gen-2 Linux driv.
+               In the aen handler, driver needs to wakeup poll handler similar to the way it raises SIGIO.
+               Driver needs to reregister for AEN with the FW when it receives AEN. This will ensure AEN
+               continuity and avoid depending upon storelib to continue events.
+
+3.     Add new controller 0x73(new SAS2)  support to the driver.
+
+4.     Add memory support required by 0x73 controller.
+
+5.     Report the unconfigured PD (system PD) to OS.
+
+6.     Add the IEEE SGL support to the driver
+
+7.     Reasign the Application cmds to 0x73 controller
+
 1 Release Date    : Thur.July. 24 11:41:51 PST 2008 -
                        (emaild-id:megaraidlinux@lsi.com)
                        Sumant Patro
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-02-12 17:30:45.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-02-12 17:31:58.000000000 -0500
@@ -10,7 +10,7 @@
  *        2 of the License, or (at your option) any later version.
  *
  * FILE                : megaraid_sas.c
- * Version     : v00.00.04.01-rc1
+ * Version     : v00.00.04.03-rc1
  *
  * Authors:
  *     (email-id : megaraidlinux@lsi.com)
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-02-12 17:30:47.000000000 -0500
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-02-12 17:32:44.000000000 -0500
@@ -18,9 +18,9 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION                                "00.00.04.01"
-#define MEGASAS_RELDATE                                "July 24, 2008"
-#define MEGASAS_EXT_VERSION                    "Thu July 24 11:41:51 PST 2008"
+#define MEGASAS_VERSION                                "00.00.04.03-rc1"
+#define MEGASAS_RELDATE                                "Feb. 10, 2009"
+#define MEGASAS_EXT_VERSION                    "Tues Feb. 10 11:41:51 PST 2009"

 /*
  * Device IDs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - I
  2009-02-17 15:25               ` [PATCH 2/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - I Yang, Bo
  2009-02-17 15:36                 ` [PATCH 3/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - II Yang, Bo
@ 2009-02-19  0:21                 ` Andrew Morton
  2009-02-19 13:55                   ` Yang, Bo
  1 sibling, 1 reply; 40+ messages in thread
From: Andrew Morton @ 2009-02-19  0:21 UTC (permalink / raw)
  To: Yang, Bo
  Cc: Bo.Yang, James.Bottomley, linux-scsi, linux-kernel, Winston.Austria

On Tue, 17 Feb 2009 08:25:07 -0700
"Yang, Bo" <Bo.Yang@lsi.com> wrote:

> Add Poll_wait mechanism to Gen-2 MegaRAID SAS Linux driver.  In the aen handler, driver needs to wakeup poll handler similar to the way it raises SIGIO.  Driver needs to reregister for AEN with the FW when it receives AEN.

Please try to keep the text to less than 80 columns.


> Signed-off-by Bo Yang<bo.yang@lsi.com>

"Signed-off-by:"

> ---
> drivers/scsi/megaraid/megaraid_sas.c |  133 ++++++++++++++++++++++++++++++++++-
>  drivers/scsi/megaraid/megaraid_sas.h |   15 +++
>  2 files changed, 147 insertions(+), 1 deletion(-)

Please use scripts/checkpatch.pl?  This patch adds a tremendous number
of coding-style errors.  checkpatch detects other problems too.

> diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
> --- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-02-12 15:36:36.000000000 -0500
> +++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-02-12 15:39:26.000000000 -0500
> @@ -40,6 +40,7 @@
>  #include <linux/compat.h>
>  #include <linux/blkdev.h>
>  #include <linux/mutex.h>
> +#include <linux/poll.h>
> 
>  #include <scsi/scsi.h>
>  #include <scsi/scsi_cmnd.h>
> @@ -89,6 +90,11 @@ static struct megasas_mgmt_info megasas_
>  static struct fasync_struct *megasas_async_queue;
>  static DEFINE_MUTEX(megasas_async_queue_mutex);
> 
> +static int megasas_poll_wait_aen;
> +static DECLARE_WAIT_QUEUE_HEAD (megasas_poll_wait);

Like the undesirable space here.

> +extern void
> +poll_wait(struct file *filp, wait_queue_head_t *q, poll_table *token);

And that.

What on earth are we doing declaring a core VFS function from within a
scsi driver's .c file?

There is a definition of poll_wait() in include/linux/poll.h.

>  static u32 megasas_dbg_lvl;
> 
>  static void
> @@ -1277,6 +1283,8 @@ megasas_bios_param(struct scsi_device *s
>         return 0;
>  }
> 
> +static void megasas_aen_polling(void *arg);
> +
>  /**
>   * megasas_service_aen -       Processes an event notification
>   * @instance:                  Adapter soft state
> @@ -1295,8 +1303,20 @@ megasas_service_aen(struct megasas_insta
>         /*
>          * Don't signal app if it is just an aborted previously registered aen
>          */
> -       if (!cmd->abort_aen)
> +       if ((!cmd->abort_aen) && (instance->unload == 0)) {
> +               struct megasas_aen_event *ev;
> +               ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
> +               if (!ev) {
> +                       printk(KERN_ERR "%s: out of memory\n", __FUNCTION__);
> +               } else {
> +                       ev->instance = instance;
> +                       INIT_WORK(&ev->hotplug_work, megasas_aen_polling);
> +                       schedule_delayed_work(&ev->hotplug_work, 0);

I see a schedule_delayed_work(), but no cancel_delayed_work().

By what means does the driver ensure that there is no pending work
after device close, device suspend, module removal, etc?

> +               }
> +               megasas_poll_wait_aen = 1;
> +               wake_up(&megasas_poll_wait);
>                 kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
> +       }
>         else
>                 cmd->abort_aen = 0;
> 
> @@ -2621,6 +2641,7 @@ megasas_probe_one(struct pci_dev *pdev,
> 
>         megasas_dbg_lvl = 0;
>         instance->flag = 0;
> +       instance->unload = 0;
>         instance->last_time = 0;
> 
>         /*
> @@ -2924,6 +2945,7 @@ static void __devexit megasas_detach_one
>         struct megasas_instance *instance;
> 
>         instance = pci_get_drvdata(pdev);
> +       instance->unload = 1;
>         host = instance->host;
> 
>         if (poll_mode_io)
> @@ -3027,6 +3049,21 @@ static int megasas_mgmt_fasync(int fd, s
>  }
> 
>  /**
> + * megasas_mgmt_poll -  char node "poll" entry point
> + * */
> +static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
> +{
> +       unsigned int mask = 0;
> +       poll_wait(file, &megasas_poll_wait, wait);
> +

The blank line would typically go after end-of-locals and before
start-of-code.

> +       if (megasas_poll_wait_aen) {
> +               mask |=   (POLLIN | POLLRDNORM);
> +               megasas_poll_wait_aen = 0;
> +       }
> +       return mask;
> +}
> +
> +/**
>   * megasas_mgmt_fw_ioctl -     Issues management ioctls to FW
>   * @instance:                  Adapter soft state
>   * @argp:                      User's ioctl packet
> @@ -3348,6 +3385,7 @@ static const struct file_operations mega
>         .open = megasas_mgmt_open,
>         .fasync = megasas_mgmt_fasync,
>         .unlocked_ioctl = megasas_mgmt_ioctl,
> +       .poll = megasas_mgmt_poll,
>  #ifdef CONFIG_COMPAT
>         .compat_ioctl = megasas_mgmt_compat_ioctl,
>  #endif
> @@ -3462,6 +3500,99 @@ out:
>         return retval;
>  }
> 
> +
> +static void
> +megasas_aen_polling(struct work_struct *work)
> +{
> +       struct megasas_aen_event *ev =
> +               container_of(work, struct megasas_aen_event, hotplug_work);

Rather than playing 80-column party tricks, it's much more natural to do:

	struct megasas_aen_event *ev;

	...
	ev = container_of(work, struct megasas_aen_event, hotplug_work);


> +       struct megasas_instance *instance = ev->instance;
> +       struct megasas_evt_log_info eli;
> +       union megasas_evt_class_locale class_locale;
> +       int doscan = 0;
> +       u32 seq_num;
> +       int error;
> +
> +       if (!instance) {
> +               printk(KERN_ERR "%s: invalid instance!\n", __FUNCTION__);
> +               kfree(ev);
> +               return;
> +       }
> +
> +       if (instance->evt_detail) {
> +               printk(KERN_INFO "%s[%d]: event code 0x%04x\n", __FUNCTION__,
> +                       instance->host->host_no, instance->evt_detail->code);
> +
> +               switch (instance->evt_detail->code) {
> +
> +               case MR_EVT_LD_CREATED:
> +               case MR_EVT_PD_INSERTED:
> +               case MR_EVT_LD_DELETED:
> +               case MR_EVT_LD_OFFLINE:
> +               case MR_EVT_CFG_CLEARED:
> +               case MR_EVT_PD_REMOVED:
> +               case MR_EVT_FOREIGN_CFG_IMPORTED:
> +               case MR_EVT_LD_STATE_CHANGE:
> +                       doscan = 1;
> +                       break;
> +               default:
> +                       doscan = 0;
> +                       break;
> +               }
> +       } else {
> +               printk(KERN_ERR "%s[%d]: invalid evt_detail!\n",
> +                       __FUNCTION__, instance->host->host_no);
> +               kfree(ev);
> +               return;
> +       }
> +
> +       if (doscan) {
> +               printk(KERN_INFO "%s[%d]: scanning ...\n",
> +                       __FUNCTION__, instance->host->host_no);
> +               scsi_scan_host(instance->host);
> +               msleep(1000);

This leaves a keventd thread unavailable for use by the rest of the
kernel for an entire second.  It's a shared resource, and this is quite
rude.

It would be better to schedule another work one second hence.  And to
remember to cancel it on the close/shutdown/suspend/rmmod/etc path, of
course..

> +       }
> +
> +       kfree(ev);
> +       /**
> +       * Get the latest sequence number from FW
> +       **/

The /** token is used to introduce kerneldoc comments.  This is not a
kerneldoc comment and there is no point in avoiding standard coding
style here.


For single-line comments:

	/* Get the latest sequence number from FW */

For multi-line comments:

	/*
	 * Get the latest sequence number from FW
	 * blah blah
	 */


> +       memset(&eli, 0, sizeof(eli));
> +
> +       if (megasas_get_seq_num(instance, &eli)) {
> +               printk(KERN_ERR "%s[%d]: failed to get seq_num\n",
> +                       __FUNCTION__, instance->host->host_no);
> +               return;
> +       }
> +
> +       seq_num = instance->evt_detail->seq_num + 1;
> +
> +       /**
> +       * Register AEN with FW for latest sequence number plus 1
> +       **/
> +
> +       class_locale.members.reserved = 0;
> +       class_locale.members.locale = MR_EVT_LOCALE_ALL;
> +       class_locale.members.class = MR_EVT_CLASS_DEBUG;
> +
> +       down(&instance->aen_mutex);
> +
> +       error = megasas_register_aen(instance, seq_num,
> +                               class_locale.word);
> +
> +       up(&instance->aen_mutex);

wot? 

aen_mutex has type `struct mutex'.  down() and up() are used against
`struct semaphore'.

This code should have emitted compile warnings, and crashed at runtime.



^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 5/9] scsi: megaraid_sas - Add memory support required by 0x73 controller
  2009-02-17 16:37                     ` [PATCH 5/9] scsi: megaraid_sas - Add memory support required by 0x73 controller Yang, Bo
  2009-02-17 17:09                       ` [PATCH 6/9] scsi: megaraid_sas - Report the unconfigured PD (system PD) to OS Yang, Bo
@ 2009-02-19  0:30                       ` Andrew Morton
  1 sibling, 0 replies; 40+ messages in thread
From: Andrew Morton @ 2009-02-19  0:30 UTC (permalink / raw)
  To: Yang, Bo
  Cc: Bo.Yang, James.Bottomley, linux-scsi, linux-kernel, Winston.Austria

On Tue, 17 Feb 2009 08:37:00 -0800
"Yang, Bo" <Bo.Yang@lsi.com> wrote:

> Add memory support required by 0x73 controller
> 
> ...
> 
> +static int
> +megasas_skinny_mem_alloc(struct megasas_instance *instance)
> +{
> +       u8              i = 0, mem_alloc_done = 0;
> +       u32             *virt, ind, num_bk = 0;
> +       dma_addr_t      paddr;
> +       u32              mem_alloc_size = MEGASAS_SKINNY_SZ_MEM_BK * 256;
> +       u32             *mem_tb = instance->skinny_mm_tb;
> +
> +       instance->skinny_mm_tb = pci_alloc_consistent(instance->pdev,
> +                                MEGASAS_SKINNY_MAX_NUM_MEM_BK*sizeof(u32),
> +                                &instance->skinny_mm_tb_h);
> +
> +       memset(instance->skinny_mm_tb, 0,
> +               MEGASAS_SKINNY_MAX_NUM_MEM_BK * sizeof(u32));

This will crash the kernel if pci_alloc_consistent() failed.

> +       instance->skinny_mm_alloc_ind = 0;
> +
> +       while (!mem_alloc_done) {
> +
> +                       virt = pci_alloc_consistent(instance->pdev,
> +                                                        mem_alloc_size,
> +                                                        &paddr);

This code would be less of a mess if this block wasn't using 16-column
indenting.

Also, the entire patch appears to be using spacespacespacespace for
indenting.  Kernel code should use hard tabs.


> +                       if (virt) {
> +                               num_bk = (mem_alloc_size/
> +                                               MEGASAS_SKINNY_SZ_MEM_BK);
> +
> +                               for (ind = 0; ind < num_bk; ind++) {
> +                                       if (instance->skinny_mm_alloc_ind <
> +                                               MEGASAS_SKINNY_MAX_NUM_MEM_BK) {
> +                                               *mem_tb = (u32)(paddr+
> +                                               (MEGASAS_SKINNY_SZ_MEM_BK*ind));
> +                                               mem_tb++;
> +                                               instance->skinny_mm_alloc_ind++;

geeze that is hard to read.

> +                                       } else {
> +                                               mem_alloc_done = 1;
> +                                       }
> +                               }
> +
> +                               instance->skinny_mm_bk[i].vir   = virt;
> +                               instance->skinny_mm_bk[i].paddr = paddr;
> +                               instance->skinny_mm_bk[i].sz = mem_alloc_size;
> +                       } else {
> +                               if (mem_alloc_size > MEGASAS_SKINNY_SZ_MEM_BK)
> +                                       mem_alloc_size = mem_alloc_size / 2;
> +                       }
> +       }

The problem with this sort of decreasing-allocation-size loop is that
the earlier, large-sized allocations will generate large stack traces
from within the page allocator if they fail.

Normally we would just suppress those expected-to-happen failures with
__GFP_NOWARN.  But thanks to pci_alloc_consistent() interface
deficiencies, this cannot be done here.

> +       if (instance->skinny_mm_alloc_ind == 0)
> +               return -1;
> +
> +       return 0;
> +}
> +


^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 8/9] scsi: megaraid_sas - Add the IEEE SGL support to the driver
  2009-02-17 17:31                           ` [PATCH 8/9] scsi: megaraid_sas - Add the IEEE SGL support to the driver Yang, Bo
  2009-02-17 17:50                             ` [PATCH 9/9] scsi: megaraid_sas - Update the Version and ChangeLog Yang, Bo
@ 2009-02-19  0:38                             ` Andrew Morton
  1 sibling, 0 replies; 40+ messages in thread
From: Andrew Morton @ 2009-02-19  0:38 UTC (permalink / raw)
  To: Yang, Bo
  Cc: Bo.Yang, James.Bottomley, linux-scsi, linux-kernel, Winston.Austria

On Tue, 17 Feb 2009 10:31:10 -0700
"Yang, Bo" <Bo.Yang@lsi.com> wrote:

> Add the IEEE SGL support to MegaRAID SAS driver
> 
> Signed-off-by Bo Yang<bo.yang@lsi.com>
> 
> ---
> drivers/scsi/megaraid/megaraid_sas.c |  125 ++++++++++++++++++++++++++---------
>  drivers/scsi/megaraid/megaraid_sas.h |   13 +++
>  2 files changed, 107 insertions(+), 31 deletions(-)
> 
> diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
> --- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-02-12 16:36:41.000000000 -0500
> +++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-02-12 17:24:26.000000000 -0500
> @@ -698,6 +698,35 @@ megasas_make_sgl64(struct megasas_instan
>         return sge_count;
>  }
> 
> +/**
> + * megasas_make_sgl64 -        Prepares 64-bit SGL
> + * @instance:          Adapter soft state
> + * @scp:               SCSI command from the mid-layer
> + * @mfi_sgl:           SGL to be filled in
> + *
> + * If successful, this function returns the number of SG elements. Otherwise,
> + * it returnes -1.
> + */
> +static int
> +megasas_make_sgl_skinny(struct megasas_instance *instance,
> +               struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl)
> +{
> +       int i;
> +       int sge_count;
> +       struct scatterlist *os_sgl;
> +
> +       sge_count = scsi_dma_map(scp);
> +       BUG_ON(sge_count < 0);

Crashing the kernel if scsi_dma_map() fails seems inappropriate?

> +       if (sge_count) {
> +               scsi_for_each_sg(scp, os_sgl, sge_count, i) {
> +                 mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl);
> +                 mfi_sgl->sge_skinny[i].phys_addr = sg_dma_address(os_sgl);
> +               }
> +       }
> +       return sge_count;
> +}
>
> ...
>
> +       if (instance->flag_ieee == 1) {
> +               flags = MFI_FRAME_IEEE;
> +       }

We typically omit the unneeded brakes in this situation.  But there are
a huge number of places in this driver which ignored that convention.

>         /*
>          * The RAID firmware may require extended timeouts.
> @@ -1405,7 +1476,7 @@ megasas_bios_param(struct scsi_device *s
>         return 0;
>  }
> 
> -static void megasas_aen_polling(void *arg);
> +static void megasas_aen_polling(struct work_struct *work);
> 
>  /**
>   * megasas_service_aen -       Processes an event notification
> @@ -1433,7 +1504,8 @@ megasas_service_aen(struct megasas_insta
>                 } else {
>                         ev->instance = instance;
>                         INIT_WORK(&ev->hotplug_work, megasas_aen_polling);
> -                       schedule_delayed_work(&ev->hotplug_work, 0);
> +                       schedule_delayed_work(
> +                               (struct delayed_work *)&ev->hotplug_work, 0);

Why was this cast added?  It looks either unneeded or wrong.

> @@ -4043,12 +4108,12 @@ megasas_aen_polling(struct work_struct *
>         class_locale.members.locale = MR_EVT_LOCALE_ALL;
>         class_locale.members.class = MR_EVT_CLASS_DEBUG;
> 
> -       down(&instance->aen_mutex);
> +       mutex_lock(&instance->aen_mutex);
> 
>         error = megasas_register_aen(instance, seq_num,
>                                 class_locale.word);
> 
> -       up(&instance->aen_mutex);
> +       mutex_unlock(&instance->aen_mutex);

OK, so this fixes a bug which was added in an earlier patch.

Please just fix the original patch so that we don't introduce bisection
holes.

>         if (error)
>                 printk(KERN_ERR "%s[%d]: register aen failed error %x\n",
> diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
> --- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-02-12 16:36:42.000000000 -0500
> +++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-02-12 16:53:50.000000000 -0500
> @@ -96,6 +96,7 @@
>  #define MFI_FRAME_DIR_WRITE                    0x0008
>  #define MFI_FRAME_DIR_READ                     0x0010
>  #define MFI_FRAME_DIR_BOTH                     0x0018
> +#define MFI_FRAME_IEEE                         0x0020
> 
>  /*
>   * Definition for cmd_status
> @@ -752,10 +753,19 @@ struct megasas_sge64 {
> 
>  } __attribute__ ((packed));
> 
> +struct megasas_sge_skinny {
> +
> +       u64 phys_addr;
> +       u32 length;
> +       u32 flag;
> +
> +} __attribute__ ((packed));

Please use __packed throughout the driver.  (might be a problem if this
header is supposed to be shared with userspace?)



^ permalink raw reply	[flat|nested] 40+ messages in thread

* RE: [PATCH 2/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - I
  2009-02-19  0:21                 ` [PATCH 2/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - I Andrew Morton
@ 2009-02-19 13:55                   ` Yang, Bo
  0 siblings, 0 replies; 40+ messages in thread
From: Yang, Bo @ 2009-02-19 13:55 UTC (permalink / raw)
  To: Andrew Morton; +Cc: James.Bottomley, linux-scsi, linux-kernel, Austria, Winston

Andrew,

Thanks for the review.  I will fix them.

Bo Yang

-----Original Message-----
From: Andrew Morton [mailto:akpm@linux-foundation.org] 
Sent: Wednesday, February 18, 2009 7:21 PM
To: Yang, Bo
Cc: Yang, Bo; James.Bottomley@HansenPartnership.com; linux-scsi@vger.kernel.org; linux-kernel@vger.kernel.org; Austria, Winston
Subject: Re: [PATCH 2/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - I

On Tue, 17 Feb 2009 08:25:07 -0700
"Yang, Bo" <Bo.Yang@lsi.com> wrote:

> Add Poll_wait mechanism to Gen-2 MegaRAID SAS Linux driver.  In the aen handler, driver needs to wakeup poll handler similar to the way it raises SIGIO.  Driver needs to reregister for AEN with the FW when it receives AEN.

Please try to keep the text to less than 80 columns.


> Signed-off-by Bo Yang<bo.yang@lsi.com>

"Signed-off-by:"

> ---
> drivers/scsi/megaraid/megaraid_sas.c |  133 ++++++++++++++++++++++++++++++++++-
>  drivers/scsi/megaraid/megaraid_sas.h |   15 +++
>  2 files changed, 147 insertions(+), 1 deletion(-)

Please use scripts/checkpatch.pl?  This patch adds a tremendous number
of coding-style errors.  checkpatch detects other problems too.

> diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
> --- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-02-12 15:36:36.000000000 -0500
> +++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-02-12 15:39:26.000000000 -0500
> @@ -40,6 +40,7 @@
>  #include <linux/compat.h>
>  #include <linux/blkdev.h>
>  #include <linux/mutex.h>
> +#include <linux/poll.h>
> 
>  #include <scsi/scsi.h>
>  #include <scsi/scsi_cmnd.h>
> @@ -89,6 +90,11 @@ static struct megasas_mgmt_info megasas_
>  static struct fasync_struct *megasas_async_queue;
>  static DEFINE_MUTEX(megasas_async_queue_mutex);
> 
> +static int megasas_poll_wait_aen;
> +static DECLARE_WAIT_QUEUE_HEAD (megasas_poll_wait);

Like the undesirable space here.

> +extern void
> +poll_wait(struct file *filp, wait_queue_head_t *q, poll_table *token);

And that.

What on earth are we doing declaring a core VFS function from within a
scsi driver's .c file?

There is a definition of poll_wait() in include/linux/poll.h.

>  static u32 megasas_dbg_lvl;
> 
>  static void
> @@ -1277,6 +1283,8 @@ megasas_bios_param(struct scsi_device *s
>         return 0;
>  }
> 
> +static void megasas_aen_polling(void *arg);
> +
>  /**
>   * megasas_service_aen -       Processes an event notification
>   * @instance:                  Adapter soft state
> @@ -1295,8 +1303,20 @@ megasas_service_aen(struct megasas_insta
>         /*
>          * Don't signal app if it is just an aborted previously registered aen
>          */
> -       if (!cmd->abort_aen)
> +       if ((!cmd->abort_aen) && (instance->unload == 0)) {
> +               struct megasas_aen_event *ev;
> +               ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
> +               if (!ev) {
> +                       printk(KERN_ERR "%s: out of memory\n", __FUNCTION__);
> +               } else {
> +                       ev->instance = instance;
> +                       INIT_WORK(&ev->hotplug_work, megasas_aen_polling);
> +                       schedule_delayed_work(&ev->hotplug_work, 0);

I see a schedule_delayed_work(), but no cancel_delayed_work().

By what means does the driver ensure that there is no pending work
after device close, device suspend, module removal, etc?

> +               }
> +               megasas_poll_wait_aen = 1;
> +               wake_up(&megasas_poll_wait);
>                 kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
> +       }
>         else
>                 cmd->abort_aen = 0;
> 
> @@ -2621,6 +2641,7 @@ megasas_probe_one(struct pci_dev *pdev,
> 
>         megasas_dbg_lvl = 0;
>         instance->flag = 0;
> +       instance->unload = 0;
>         instance->last_time = 0;
> 
>         /*
> @@ -2924,6 +2945,7 @@ static void __devexit megasas_detach_one
>         struct megasas_instance *instance;
> 
>         instance = pci_get_drvdata(pdev);
> +       instance->unload = 1;
>         host = instance->host;
> 
>         if (poll_mode_io)
> @@ -3027,6 +3049,21 @@ static int megasas_mgmt_fasync(int fd, s
>  }
> 
>  /**
> + * megasas_mgmt_poll -  char node "poll" entry point
> + * */
> +static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
> +{
> +       unsigned int mask = 0;
> +       poll_wait(file, &megasas_poll_wait, wait);
> +

The blank line would typically go after end-of-locals and before
start-of-code.

> +       if (megasas_poll_wait_aen) {
> +               mask |=   (POLLIN | POLLRDNORM);
> +               megasas_poll_wait_aen = 0;
> +       }
> +       return mask;
> +}
> +
> +/**
>   * megasas_mgmt_fw_ioctl -     Issues management ioctls to FW
>   * @instance:                  Adapter soft state
>   * @argp:                      User's ioctl packet
> @@ -3348,6 +3385,7 @@ static const struct file_operations mega
>         .open = megasas_mgmt_open,
>         .fasync = megasas_mgmt_fasync,
>         .unlocked_ioctl = megasas_mgmt_ioctl,
> +       .poll = megasas_mgmt_poll,
>  #ifdef CONFIG_COMPAT
>         .compat_ioctl = megasas_mgmt_compat_ioctl,
>  #endif
> @@ -3462,6 +3500,99 @@ out:
>         return retval;
>  }
> 
> +
> +static void
> +megasas_aen_polling(struct work_struct *work)
> +{
> +       struct megasas_aen_event *ev =
> +               container_of(work, struct megasas_aen_event, hotplug_work);

Rather than playing 80-column party tricks, it's much more natural to do:

	struct megasas_aen_event *ev;

	...
	ev = container_of(work, struct megasas_aen_event, hotplug_work);


> +       struct megasas_instance *instance = ev->instance;
> +       struct megasas_evt_log_info eli;
> +       union megasas_evt_class_locale class_locale;
> +       int doscan = 0;
> +       u32 seq_num;
> +       int error;
> +
> +       if (!instance) {
> +               printk(KERN_ERR "%s: invalid instance!\n", __FUNCTION__);
> +               kfree(ev);
> +               return;
> +       }
> +
> +       if (instance->evt_detail) {
> +               printk(KERN_INFO "%s[%d]: event code 0x%04x\n", __FUNCTION__,
> +                       instance->host->host_no, instance->evt_detail->code);
> +
> +               switch (instance->evt_detail->code) {
> +
> +               case MR_EVT_LD_CREATED:
> +               case MR_EVT_PD_INSERTED:
> +               case MR_EVT_LD_DELETED:
> +               case MR_EVT_LD_OFFLINE:
> +               case MR_EVT_CFG_CLEARED:
> +               case MR_EVT_PD_REMOVED:
> +               case MR_EVT_FOREIGN_CFG_IMPORTED:
> +               case MR_EVT_LD_STATE_CHANGE:
> +                       doscan = 1;
> +                       break;
> +               default:
> +                       doscan = 0;
> +                       break;
> +               }
> +       } else {
> +               printk(KERN_ERR "%s[%d]: invalid evt_detail!\n",
> +                       __FUNCTION__, instance->host->host_no);
> +               kfree(ev);
> +               return;
> +       }
> +
> +       if (doscan) {
> +               printk(KERN_INFO "%s[%d]: scanning ...\n",
> +                       __FUNCTION__, instance->host->host_no);
> +               scsi_scan_host(instance->host);
> +               msleep(1000);

This leaves a keventd thread unavailable for use by the rest of the
kernel for an entire second.  It's a shared resource, and this is quite
rude.

It would be better to schedule another work one second hence.  And to
remember to cancel it on the close/shutdown/suspend/rmmod/etc path, of
course..

> +       }
> +
> +       kfree(ev);
> +       /**
> +       * Get the latest sequence number from FW
> +       **/

The /** token is used to introduce kerneldoc comments.  This is not a
kerneldoc comment and there is no point in avoiding standard coding
style here.


For single-line comments:

	/* Get the latest sequence number from FW */

For multi-line comments:

	/*
	 * Get the latest sequence number from FW
	 * blah blah
	 */


> +       memset(&eli, 0, sizeof(eli));
> +
> +       if (megasas_get_seq_num(instance, &eli)) {
> +               printk(KERN_ERR "%s[%d]: failed to get seq_num\n",
> +                       __FUNCTION__, instance->host->host_no);
> +               return;
> +       }
> +
> +       seq_num = instance->evt_detail->seq_num + 1;
> +
> +       /**
> +       * Register AEN with FW for latest sequence number plus 1
> +       **/
> +
> +       class_locale.members.reserved = 0;
> +       class_locale.members.locale = MR_EVT_LOCALE_ALL;
> +       class_locale.members.class = MR_EVT_CLASS_DEBUG;
> +
> +       down(&instance->aen_mutex);
> +
> +       error = megasas_register_aen(instance, seq_num,
> +                               class_locale.word);
> +
> +       up(&instance->aen_mutex);

wot? 

aen_mutex has type `struct mutex'.  down() and up() are used against
`struct semaphore'.

This code should have emitted compile warnings, and crashed at runtime.



^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 1/10] scsi: megaraid_sas - tape drive support fix
  2009-02-17 14:44             ` [PATCH 1/9] scsi: megaraid_sas - Fix the tape drive support Yang, Bo
  2009-02-17 15:25               ` [PATCH 2/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - I Yang, Bo
@ 2009-05-05 23:55               ` Yang, Bo
  2009-05-06  0:25                 ` [PATCH 2/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-I) Yang, Bo
  1 sibling, 1 reply; 40+ messages in thread
From: Yang, Bo @ 2009-05-05 23:55 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Austria, Winston

Add the Tape drive fix to the megaraid_sas driver: If the command is for the tape device, set the FW pthru timeout to the os layer timeout value.

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
drivers/scsi/megaraid/megaraid_sas.c |   11 +++++++++++
 1 file changed, 11 insertions(+)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-05-04 20:06:29.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-05-04 20:08:26.000000000 -0400
@@ -687,6 +687,17 @@ megasas_build_dcdb(struct megasas_instan
        memcpy(pthru->cdb, scp->cmnd, scp->cmd_len);

        /*
+       * If the command is for the tape device, set the
+       * pthru timeout to the os layer timeout value.
+       */
+       if (scp->device->type == TYPE_TAPE) {
+               if ((scp->request->timeout / HZ) > 0xFFFF)
+                       pthru->timeout = 0xFFFF;
+               else
+                       pthru->timeout = scp->request->timeout / HZ;
+       }
+
+       /*
         * Construct SGL
         */
        if (IS_DMA64) {

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 2/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-I)
  2009-05-05 23:55               ` [PATCH 1/10] scsi: megaraid_sas - tape drive support fix Yang, Bo
@ 2009-05-06  0:25                 ` Yang, Bo
  2009-05-06  0:41                   ` [PATCH 3/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-II) Yang, Bo
  2009-05-06 21:17                   ` [PATCH 2/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-I) Andrew Morton
  0 siblings, 2 replies; 40+ messages in thread
From: Yang, Bo @ 2009-05-06  0:25 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Austria, Winston

Add Poll_wait mechanism to SAS-2 MegaRAID SAS Linux driver. Driver will wakeup poll after the driver get event from MegaRAID SAS FW.  Driver also reregisters for Event with the FW when it receives AEN.

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
drivers/scsi/megaraid/megaraid_sas.c |  136 ++++++++++++++++++++++++++++++++++-
 drivers/scsi/megaraid/megaraid_sas.h |   18 ++++
 2 files changed, 153 insertions(+), 1 deletion(-)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-05-04 20:10:20.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-05-04 20:11:52.000000000 -0400
@@ -40,6 +40,7 @@
 #include <linux/compat.h>
 #include <linux/blkdev.h>
 #include <linux/mutex.h>
+#include <linux/poll.h>

 #include <scsi/scsi.h>
 #include <scsi/scsi_cmnd.h>
@@ -89,6 +90,9 @@ static struct megasas_mgmt_info megasas_
 static struct fasync_struct *megasas_async_queue;
 static DEFINE_MUTEX(megasas_async_queue_mutex);

+static int megasas_poll_wait_aen;
+static DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait);
+
 static u32 megasas_dbg_lvl;

 static void
@@ -1277,6 +1281,8 @@ megasas_bios_param(struct scsi_device *s
        return 0;
 }

+static void megasas_aen_polling(struct megasas_instance *instance);
+
 /**
  * megasas_service_aen -       Processes an event notification
  * @instance:                  Adapter soft state
@@ -1295,13 +1301,20 @@ megasas_service_aen(struct megasas_insta
        /*
         * Don't signal app if it is just an aborted previously registered aen
         */
-       if (!cmd->abort_aen)
+       if ((!cmd->abort_aen) && (instance->unload == 0)) {
+               megasas_poll_wait_aen = 1;
+               wake_up(&megasas_poll_wait);
                kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
+       }
        else
                cmd->abort_aen = 0;

        instance->aen_cmd = NULL;
        megasas_return_cmd(instance, cmd);
+
+       if ((!cmd->abort_aen) && (instance->unload == 0)) {
+               megasas_aen_polling(instance);
+       }
 }

 /*
@@ -2583,6 +2596,8 @@ megasas_probe_one(struct pci_dev *pdev,

        *instance->producer = 0;
        *instance->consumer = 0;
+       megasas_poll_wait_aen = 0;
+       instance->hotplug_wk = NULL;

        instance->evt_detail = pci_alloc_consistent(pdev,
                                                    sizeof(struct
@@ -2621,6 +2636,7 @@ megasas_probe_one(struct pci_dev *pdev,

        megasas_dbg_lvl = 0;
        instance->flag = 0;
+       instance->unload = 0;
        instance->last_time = 0;

        /*
@@ -2924,6 +2940,7 @@ static void __devexit megasas_detach_one
        struct megasas_instance *instance;

        instance = pci_get_drvdata(pdev);
+       instance->unload = 1;
        host = instance->host;

        if (poll_mode_io)
@@ -2932,6 +2949,15 @@ static void __devexit megasas_detach_one
        scsi_remove_host(instance->host);
        megasas_flush_cache(instance);
        megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
+
+       /*
+       * cancel the delayed work if this work still in queue
+       */
+       if (instance->hotplug_wk != NULL) {
+               cancel_delayed_work(
+                       (struct delayed_work *)instance->hotplug_wk);
+               flush_scheduled_work();
+       }
        tasklet_kill(&instance->isr_tasklet);

        /*
@@ -3027,6 +3053,19 @@ static int megasas_mgmt_fasync(int fd, s
 }

 /**
+ * megasas_mgmt_poll -  char node "poll" entry point
+ * */
+static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
+{
+       unsigned int mask = 0;
+       poll_wait(file, &megasas_poll_wait, wait);
+       if (megasas_poll_wait_aen) {
+               mask |=   (POLLIN | POLLRDNORM);
+       }
+       return mask;
+}
+
+/**
  * megasas_mgmt_fw_ioctl -     Issues management ioctls to FW
  * @instance:                  Adapter soft state
  * @argp:                      User's ioctl packet
@@ -3348,6 +3387,7 @@ static const struct file_operations mega
        .open = megasas_mgmt_open,
        .fasync = megasas_mgmt_fasync,
        .unlocked_ioctl = megasas_mgmt_ioctl,
+       .poll = megasas_mgmt_poll,
 #ifdef CONFIG_COMPAT
        .compat_ioctl = megasas_mgmt_compat_ioctl,
 #endif
@@ -3462,6 +3502,100 @@ out:
        return retval;
 }

+static void
+megasas_scsi_scan_host(struct work_struct *work)
+{
+       struct megasas_aen_event *ev = container_of(work,
+               struct megasas_aen_event, hotplug_work);
+       struct megasas_instance *instance = ev->instance;
+
+       instance->hotplug_wk = NULL;
+       if (!instance) {
+               printk(KERN_ERR "%s: invalid instance!\n", __FUNCTION__);
+               kfree(ev);
+               return;
+       }
+
+       printk(KERN_INFO "%s[%d]: scanning ...\n",
+               __FUNCTION__, instance->host->host_no);
+       scsi_scan_host(instance->host);
+       kfree(ev);
+}
+
+static void
+megasas_aen_polling(struct megasas_instance *instance)
+{
+       union megasas_evt_class_locale class_locale;
+       int doscan = 0;
+       u32 seq_num;
+       int error;
+
+       if (instance->evt_detail) {
+               printk(KERN_INFO "%s[%d]: event code 0x%04x\n", __FUNCTION__,
+                       instance->host->host_no, instance->evt_detail->code);
+
+               switch (instance->evt_detail->code) {
+
+               case MR_EVT_LD_CREATED:
+               case MR_EVT_PD_INSERTED:
+               case MR_EVT_LD_DELETED:
+               case MR_EVT_LD_OFFLINE:
+               case MR_EVT_CFG_CLEARED:
+               case MR_EVT_PD_REMOVED:
+               case MR_EVT_FOREIGN_CFG_IMPORTED:
+               case MR_EVT_LD_STATE_CHANGE:
+               case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
+                       doscan = 1;
+                       break;
+               default:
+                       doscan = 0;
+                       break;
+               }
+       } else {
+               printk(KERN_ERR "%s[%d]: invalid evt_detail!\n",
+                       __FUNCTION__, instance->host->host_no);
+               return;
+       }
+
+       if (doscan) {
+               struct megasas_aen_event *ev;
+               ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
+               if (!ev) {
+                       printk(KERN_ERR "%s: out of memory\n", __FUNCTION__);
+               } else {
+                       ev->instance = instance;
+                       instance->hotplug_wk = &ev->hotplug_work;
+                       INIT_WORK(&ev->hotplug_work, megasas_scsi_scan_host);
+                       schedule_delayed_work(
+                               (struct delayed_work *)&ev->hotplug_work, 0);
+               }
+       }
+
+       seq_num = instance->evt_detail->seq_num + 1;
+
+       /**
+       * Register AEN with FW for latest sequence number plus 1
+       **/
+
+       class_locale.members.reserved = 0;
+       class_locale.members.locale = MR_EVT_LOCALE_ALL;
+       class_locale.members.class = MR_EVT_CLASS_DEBUG;
+
+       if ( instance->aen_cmd != NULL ) {
+               return ;
+       }
+
+       mutex_lock(&instance->aen_mutex);
+       error = megasas_register_aen(instance, seq_num,
+                               class_locale.word);
+       mutex_unlock(&instance->aen_mutex);
+
+       if (error)
+               printk(KERN_ERR "%s[%d]: register aen failed error %x\n",
+                        __FUNCTION__, instance->host->host_no, error);
+}
+
+
 static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUGO,
                megasas_sysfs_show_poll_mode_io,
                megasas_sysfs_set_poll_mode_io);
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-05-04 20:10:21.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-05-04 20:00:31.000000000 -0400
@@ -132,6 +132,17 @@
 #define MR_DCMD_CLUSTER_RESET_ALL              0x08010100
 #define MR_DCMD_CLUSTER_RESET_LD               0x08010200

+#define MR_EVT_CFG_CLEARED                     0x0004
+
+#define MR_EVT_LD_STATE_CHANGE                 0x0051
+#define MR_EVT_PD_INSERTED                     0x005b
+#define MR_EVT_PD_REMOVED                      0x0070
+#define MR_EVT_LD_CREATED                      0x008a
+#define MR_EVT_LD_DELETED                      0x008b
+#define MR_EVT_FOREIGN_CFG_IMPORTED            0x00db
+#define MR_EVT_LD_OFFLINE                      0x00fc
+#define MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED     0x0152
+
 /*
  * MFI command completion codes
  */
@@ -1072,6 +1083,11 @@ struct megasas_evt_detail {
        u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *);
  };

+struct megasas_aen_event {
+       struct work_struct hotplug_work;
+       struct megasas_instance *instance;
+};
+
 struct megasas_instance {

        u32 *producer;
@@ -1118,8 +1134,10 @@ struct megasas_instance {

        struct megasas_instance_template *instancet;
        struct tasklet_struct isr_tasklet;
+       struct work_struct *hotplug_wk;

        u8 flag;
+       u8 unload;
        unsigned long last_time;

        struct timer_list io_completion_timer;

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 3/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-II)
  2009-05-06  0:25                 ` [PATCH 2/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-I) Yang, Bo
@ 2009-05-06  0:41                   ` Yang, Bo
  2009-05-06  1:11                     ` [PATCH 4/10] scsi: megaraid_sas - Add New SAS 2 (iMR) controller support to the driver Yang, Bo
  2009-05-06 21:19                     ` [PATCH 3/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-II) Andrew Morton
  2009-05-06 21:17                   ` [PATCH 2/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-I) Andrew Morton
  1 sibling, 2 replies; 40+ messages in thread
From: Yang, Bo @ 2009-05-06  0:41 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Austria, Winston

Add Poll Wait Mechanism PART-II: Add Poll_wait mechanism to MegaRAID SAS 2 Linux driver.  Add the sysfs entry for the application use.

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
drivers/scsi/megaraid/megaraid_sas.c |   27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-05-04 20:14:30.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-05-04 20:15:48.000000000 -0400
@@ -93,6 +93,8 @@ static DEFINE_MUTEX(megasas_async_queue_
 static int megasas_poll_wait_aen;
 static DECLARE_WAIT_QUEUE_HEAD(megasas_poll_wait);

+static u32 support_poll_for_event;
+
 static u32 megasas_dbg_lvl;

 static void
@@ -3429,6 +3431,15 @@ static DRIVER_ATTR(release_date, S_IRUGO
                   NULL);

 static ssize_t
+megasas_sysfs_show_support_poll_for_event(struct device_driver *dd, char *buf)
+{
+       return sprintf(buf, "%u\n", support_poll_for_event);
+}
+
+static DRIVER_ATTR(support_poll_for_event, S_IRUGO,
+                       megasas_sysfs_show_support_poll_for_event, NULL);
+
+static ssize_t
 megasas_sysfs_show_dbg_lvl(struct device_driver *dd, char *buf)
 {
        return sprintf(buf, "%u\n", megasas_dbg_lvl);
@@ -3595,7 +3606,6 @@ megasas_aen_polling(struct megasas_insta
                         __FUNCTION__, instance->host->host_no, error);
 }

-
 static DRIVER_ATTR(poll_mode_io, S_IRUGO|S_IWUGO,
                megasas_sysfs_show_poll_mode_io,
                megasas_sysfs_set_poll_mode_io);
@@ -3613,6 +3623,8 @@ static int __init megasas_init(void)
        printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION,
               MEGASAS_EXT_VERSION);

+       support_poll_for_event = 1;
+
        memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info));

        /*
@@ -3645,6 +3657,12 @@ static int __init megasas_init(void)
                                  &driver_attr_release_date);
        if (rval)
                goto err_dcf_rel_date;
+
+       rval = driver_create_file(&megasas_pci_driver.driver,
+                               &driver_attr_support_poll_for_event);
+       if (rval)
+               goto err_dcf_support_poll_for_event;
+
        rval = driver_create_file(&megasas_pci_driver.driver,
                                  &driver_attr_dbg_lvl);
        if (rval)
@@ -3662,6 +3680,11 @@ err_dcf_poll_mode_io:
 err_dcf_dbg_lvl:
        driver_remove_file(&megasas_pci_driver.driver,
                           &driver_attr_release_date);
+
+err_dcf_support_poll_for_event:
+       driver_remove_file(&megasas_pci_driver.driver,
+                       &driver_attr_support_poll_for_event);
+
 err_dcf_rel_date:
        driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
 err_dcf_attr_ver:
@@ -3681,6 +3704,8 @@ static void __exit megasas_exit(void)
        driver_remove_file(&megasas_pci_driver.driver,
                           &driver_attr_dbg_lvl);
        driver_remove_file(&megasas_pci_driver.driver,
+                       &driver_attr_support_poll_for_event);
+       driver_remove_file(&megasas_pci_driver.driver,
                           &driver_attr_release_date);
        driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 4/10] scsi: megaraid_sas - Add New SAS 2 (iMR) controller support to the driver
  2009-05-06  0:41                   ` [PATCH 3/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-II) Yang, Bo
@ 2009-05-06  1:11                     ` Yang, Bo
  2009-05-06  1:24                       ` [PATCH 5/10] scsi: megaraid_sas - Fixed load/unload issue and Fire the system pd DCDB cmd to MegaRAID SAS FW to get the system PDs Yang, Bo
  2009-05-06 21:19                     ` [PATCH 3/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-II) Andrew Morton
  1 sibling, 1 reply; 40+ messages in thread
From: Yang, Bo @ 2009-05-06  1:11 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Austria, Winston

Add the new MegaRAID SAS controller (0x73) support to the driver.

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
drivers/scsi/megaraid/megaraid_sas.c |  139 +++++++++++++++++++++++++++++++++--
 drivers/scsi/megaraid/megaraid_sas.h |    4 +
 2 files changed, 138 insertions(+), 5 deletions(-)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-05-04 20:17:46.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-05-04 20:19:05.000000000 -0400
@@ -76,6 +76,10 @@ static struct pci_device_id megasas_pci_
        /* gen2*/
        {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0079GEN2)},
        /* gen2*/
+       {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0073SKINNY)},
+       /* skinny*/
+       {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_SAS0071SKINNY)},
+       /* skinny*/
        {PCI_DEVICE(PCI_VENDOR_ID_LSI_LOGIC, PCI_DEVICE_ID_LSI_VERDE_ZCR)},
        /* xscale IOP, vega */
        {PCI_DEVICE(PCI_VENDOR_ID_DELL, PCI_DEVICE_ID_DELL_PERC5)},
@@ -334,6 +338,99 @@ static struct megasas_instance_template
 };

 /**
+ * megasas_enable_intr_skinny -        Enables interrupts
+ * @regs:                      MFI register set
+ */
+static inline void
+megasas_enable_intr_skinny(struct megasas_register_set __iomem *regs)
+{
+       writel(0xFFFFFFFF, &(regs)->outbound_intr_mask);
+
+       writel(~MFI_SKINNY_ENABLE_INTERRUPT_MASK, &(regs)->outbound_intr_mask);
+
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_disable_intr_skinny -       Disables interrupt
+ * @regs:                      MFI register set
+ */
+static inline void
+megasas_disable_intr_skinny(struct megasas_register_set __iomem *regs)
+{
+       u32 mask = 0xFFFFFFFF;
+       writel(mask, &regs->outbound_intr_mask);
+       /* Dummy readl to force pci flush */
+       readl(&regs->outbound_intr_mask);
+}
+
+/**
+ * megasas_read_fw_status_reg_skinny - returns the current FW status value
+ * @regs:                      MFI register set
+ */
+static u32
+megasas_read_fw_status_reg_skinny(struct megasas_register_set __iomem *regs)
+{
+       return readl(&(regs)->outbound_scratch_pad);
+}
+
+/**
+ * megasas_clear_interrupt_skinny -    Check & clear interrupt
+ * @regs:                              MFI register set
+ */
+static int
+megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs)
+{
+       u32 status;
+       /*
+        * Check if it is our interrupt
+        */
+       status = readl(&regs->outbound_intr_status);
+
+       if (!(status & MFI_SKINNY_ENABLE_INTERRUPT_MASK)) {
+               return 1;
+       }
+
+       /*
+        * Clear the interrupt by writing back the same value
+        */
+       writel(status, &regs->outbound_intr_status);
+
+       /*
+       * dummy read to flush PCI
+       */
+       readl(&regs->outbound_intr_status);
+
+       return 0;
+}
+
+/**
+ * megasas_fire_cmd_skinny -   Sends command to the FW
+ * @frame_phys_addr :          Physical address of cmd
+ * @frame_count :              Number of frames for the command
+ * @regs :                     MFI register set
+ */
+static inline void
+megasas_fire_cmd_skinny(dma_addr_t frame_phys_addr, u32 frame_count,
+                       struct megasas_register_set __iomem *regs)
+{
+       writel(0, &(regs)->inbound_high_queue_port);
+       writel((frame_phys_addr | (frame_count<<1))|1,
+                       &(regs)->inbound_low_queue_port);
+       /*msleep(5);*/
+}
+
+static struct megasas_instance_template megasas_instance_template_skinny = {
+
+       .fire_cmd = megasas_fire_cmd_skinny,
+       .enable_intr = megasas_enable_intr_skinny,
+       .disable_intr = megasas_disable_intr_skinny,
+       .clear_intr = megasas_clear_intr_skinny,
+       .read_fw_status_reg = megasas_read_fw_status_reg_skinny,
+};
+
+/**
 *      The following functions are defined for gen2 (deviceid : 0x78 0x79)
 *      controllers
 */
@@ -1582,16 +1679,34 @@ megasas_transition_to_ready(struct megas
                        /*
                         * Set the CLR bit in inbound doorbell
                         */
-                       writel(MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
-                               &instance->reg_set->inbound_doorbell);
+                       if ((instance->pdev->device == \
+                               PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+                               (instance->pdev->device ==
+                               PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+
+                               writel(
+                                 MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
+                                 &instance->reg_set->reserved_0[0]);
+                       } else {
+                               writel(
+                                   MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
+                                       &instance->reg_set->inbound_doorbell);
+                       }

                        max_wait = 2;
                        cur_state = MFI_STATE_WAIT_HANDSHAKE;
                        break;

                case MFI_STATE_BOOT_MESSAGE_PENDING:
-                       writel(MFI_INIT_HOTPLUG,
-                               &instance->reg_set->inbound_doorbell);
+                       if ((instance->pdev->device ==
+                               PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+                       (instance->pdev->device ==
+                               PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+                               writel(MFI_INIT_HOTPLUG,
+                               &instance->reg_set->reserved_0[0]);
+                       } else
+                               writel(MFI_INIT_HOTPLUG,
+                                       &instance->reg_set->inbound_doorbell);

                        max_wait = 10;
                        cur_state = MFI_STATE_BOOT_MESSAGE_PENDING;
@@ -1602,7 +1717,15 @@ megasas_transition_to_ready(struct megas
                         * Bring it to READY state; assuming max wait 10 secs
                         */
                        instance->instancet->disable_intr(instance->reg_set);
-                       writel(MFI_RESET_FLAGS, &instance->reg_set->inbound_doorbell);
+                       if ((instance->pdev->device ==
+                               PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+                               (instance->pdev->device ==
+                               PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+                               writel(MFI_RESET_FLAGS,
+                               &instance->reg_set->reserved_0[0]);
+                       } else
+                               writel(MFI_RESET_FLAGS,
+                               &instance->reg_set->inbound_doorbell);

                        max_wait = 60;
                        cur_state = MFI_STATE_OPERATIONAL;
@@ -2107,6 +2230,8 @@ static int megasas_init_mfi(struct megas
         * Map the message registers
         */
        if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS1078GEN2) ||
+               (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY) ||
+               (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
                (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0079GEN2)) {
                instance->base_addr = pci_resource_start(instance->pdev, 1);
        } else {
@@ -2137,6 +2262,10 @@ static int megasas_init_mfi(struct megas
                case PCI_DEVICE_ID_LSI_SAS0079GEN2:
                        instance->instancet = &megasas_instance_template_gen2;
                        break;
+               case PCI_DEVICE_ID_LSI_SAS0073SKINNY:
+               case PCI_DEVICE_ID_LSI_SAS0071SKINNY:
+                       instance->instancet = &megasas_instance_template_skinny;
+                       break;
                case PCI_DEVICE_ID_LSI_SAS1064R:
                case PCI_DEVICE_ID_DELL_PERC5:
                default:
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-05-04 20:17:47.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-05-04 20:00:32.000000000 -0400
@@ -30,6 +30,8 @@
 #define        PCI_DEVICE_ID_LSI_VERDE_ZCR             0x0413
 #define        PCI_DEVICE_ID_LSI_SAS1078GEN2           0x0078
 #define        PCI_DEVICE_ID_LSI_SAS0079GEN2           0x0079
+#define        PCI_DEVICE_ID_LSI_SAS0073SKINNY         0x0073
+#define        PCI_DEVICE_ID_LSI_SAS0071SKINNY         0x0071

 /*
  * =====================================
@@ -595,6 +597,8 @@ struct megasas_ctrl_info {
 #define MFI_REPLY_1078_MESSAGE_INTERRUPT       0x80000000
 #define MFI_REPLY_GEN2_MESSAGE_INTERRUPT       0x00000001
 #define MFI_GEN2_ENABLE_INTERRUPT_MASK         (0x00000001 | 0x00000004)
+#define MFI_REPLY_SKINNY_MESSAGE_INTERRUPT     0x40000000
+#define MFI_SKINNY_ENABLE_INTERRUPT_MASK       (0x00000001)

 /*
 * register set for both 1068 and 1078 controllers

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 5/10] scsi: megaraid_sas - Fixed load/unload issue and Fire the system pd DCDB cmd to MegaRAID SAS FW to get the system PDs
  2009-05-06  1:11                     ` [PATCH 4/10] scsi: megaraid_sas - Add New SAS 2 (iMR) controller support to the driver Yang, Bo
@ 2009-05-06  1:24                       ` Yang, Bo
  2009-05-06  1:35                         ` [PATCH 6/10] scsi: megaraid_sas - Report the Unconfigured PD (system PD) to OS Yang, Bo
  2009-05-06 21:20                         ` [PATCH 5/10] scsi: megaraid_sas - Fixed load/unload issue and Fire the system pd DCDB cmd to MegaRAID SAS FW to get the system PDs Andrew Morton
  0 siblings, 2 replies; 40+ messages in thread
From: Yang, Bo @ 2009-05-06  1:24 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Austria, Winston

Fixed the Driver load / Unload issue and Fire the system PD DCDB cmd to MegaRAID SAS FW to get the system PDs List

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
drivers/scsi/megaraid/megaraid_sas.c |  105 +++++++++++++++++++++++++++++++++--
 drivers/scsi/megaraid/megaraid_sas.h |   83 +++++++++++++++++++++++++++
 2 files changed, 183 insertions(+), 5 deletions(-)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-05-04 20:21:03.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-05-04 20:22:17.000000000 -0400
@@ -1686,7 +1686,7 @@ megasas_transition_to_ready(struct megas

                                writel(
                                  MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
-                                 &instance->reg_set->reserved_0[0]);
+                                 &instance->reg_set->outbound_scratch_pad);
                        } else {
                                writel(
                                    MFI_INIT_CLEAR_HANDSHAKE|MFI_INIT_HOTPLUG,
@@ -1703,7 +1703,7 @@ megasas_transition_to_ready(struct megas
                        (instance->pdev->device ==
                                PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
                                writel(MFI_INIT_HOTPLUG,
-                               &instance->reg_set->reserved_0[0]);
+                               &instance->reg_set->outbound_scratch_pad);
                        } else
                                writel(MFI_INIT_HOTPLUG,
                                        &instance->reg_set->inbound_doorbell);
@@ -1722,7 +1722,7 @@ megasas_transition_to_ready(struct megas
                                (instance->pdev->device ==
                                PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
                                writel(MFI_RESET_FLAGS,
-                               &instance->reg_set->reserved_0[0]);
+                               &instance->reg_set->outbound_scratch_pad);
                        } else
                                writel(MFI_RESET_FLAGS,
                                &instance->reg_set->inbound_doorbell);
@@ -2031,6 +2031,97 @@ static int megasas_alloc_cmds(struct meg
        return 0;
 }

+/*
+ * megasas_get_pd_list_info -  Returns FW's pd_list structure
+ * @instance:                          Adapter soft state
+ * @pd_list:                           pd_list structure
+ *
+ * Issues an internal command (DCMD) to get the FW's controller PD
+ * list structure.  This information is mainly used to find out SYSTEM
+ * supported by the FW.
+ */
+static int
+megasas_get_pd_list(struct megasas_instance *instance)
+{
+       int ret = 0, pd_index = 0;
+       struct megasas_cmd *cmd;
+       struct megasas_dcmd_frame *dcmd;
+       struct MR_PD_LIST *ci;
+       struct MR_PD_ADDRESS *pd_addr;
+       dma_addr_t ci_h = 0;
+
+       cmd = megasas_get_cmd(instance);
+
+       if (!cmd) {
+               printk(KERN_DEBUG "megasas (get_pd_list): Failed to get cmd\n");
+               return -ENOMEM;
+       }
+
+       dcmd = &cmd->frame->dcmd;
+
+       ci = pci_alloc_consistent(instance->pdev,
+                 MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST), &ci_h);
+
+       if (!ci) {
+               printk(KERN_DEBUG "Failed to alloc mem for pd_list\n");
+               megasas_return_cmd(instance, cmd);
+               return -ENOMEM;
+       }
+
+       memset(ci, 0, sizeof(*ci));
+       memset(dcmd->mbox.b, 0, MFI_MBOX_SIZE);
+
+       dcmd->mbox.b[0] = MR_PD_QUERY_TYPE_EXPOSED_TO_HOST;
+       dcmd->mbox.b[1] = 0;
+       dcmd->cmd = MFI_CMD_DCMD;
+       dcmd->cmd_status = 0xFF;
+       dcmd->sge_count = 1;
+       dcmd->flags = MFI_FRAME_DIR_READ;
+       dcmd->timeout = 0;
+       dcmd->data_xfer_len = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
+       dcmd->opcode = MR_DCMD_PD_LIST_QUERY;
+       dcmd->sgl.sge32[0].phys_addr = ci_h;
+       dcmd->sgl.sge32[0].length = MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST);
+
+       if (!megasas_issue_polled(instance, cmd)) {
+               ret = 0;
+       } else {
+               ret = -1;
+       }
+
+       /*
+       * the following function will get the instance PD LIST.
+       */
+
+       pd_addr = ci->addr;
+
+       if ( ret == 0 &&
+               (ci->count <
+                 (MEGASAS_MAX_PD_CHANNELS * MEGASAS_MAX_DEV_PER_CHANNEL))) {
+
+               memset(instance->pd_list, 0,
+                       MEGASAS_MAX_PD * sizeof(struct megasas_pd_list));
+
+               for (pd_index = 0; pd_index < ci->count; pd_index++) {
+
+                       instance->pd_list[pd_addr->deviceId].tid        =
+                                                       pd_addr->deviceId;
+                       instance->pd_list[pd_addr->deviceId].driveType  =
+                                                       pd_addr->scsiDevType;
+                       instance->pd_list[pd_addr->deviceId].driveState =
+                                                       MR_PD_STATE_SYSTEM;
+                       pd_addr++;
+               }
+       }
+
+       pci_free_consistent(instance->pdev,
+                               MEGASAS_MAX_PD * sizeof(struct MR_PD_LIST),
+                               ci, ci_h);
+       megasas_return_cmd(instance, cmd);
+
+       return ret;
+}
+
 /**
  * megasas_get_controller_info -       Returns FW's controller structure
  * @instance:                          Adapter soft state
@@ -2310,8 +2401,8 @@ static int megasas_init_mfi(struct megas
        reply_q_sz = context_sz * (instance->max_fw_cmds + 1);

        instance->reply_queue = pci_alloc_consistent(instance->pdev,
-                                                    reply_q_sz,
-                                                    &instance->reply_queue_h);
+                                               reply_q_sz,
+                                               &instance->reply_queue_h);

        if (!instance->reply_queue) {
                printk(KERN_DEBUG "megasas: Out of DMA mem for reply queue\n");
@@ -2321,6 +2412,10 @@ static int megasas_init_mfi(struct megas
        if (megasas_issue_init_mfi(instance))
                goto fail_fw_init;

+       memset(instance->pd_list, 0 ,
+               (MEGASAS_MAX_PD * sizeof(struct megasas_pd_list)));
+       megasas_get_pd_list(instance);
+
        ctrl_info = kmalloc(sizeof(struct megasas_ctrl_info), GFP_KERNEL);

        /*
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-05-04 20:21:05.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-05-04 20:00:32.000000000 -0400
@@ -133,6 +133,7 @@
 #define MR_DCMD_CLUSTER                                0x08000000
 #define MR_DCMD_CLUSTER_RESET_ALL              0x08010100
 #define MR_DCMD_CLUSTER_RESET_LD               0x08010200
+#define MR_DCMD_PD_LIST_QUERY                   0x02010100

 #define MR_EVT_CFG_CLEARED                     0x0004

@@ -264,10 +265,89 @@ enum MR_EVT_ARGS {
        MR_EVT_ARGS_STR,
        MR_EVT_ARGS_TIME,
        MR_EVT_ARGS_ECC,
+       MR_EVT_ARGS_LD_PROP,
+       MR_EVT_ARGS_PD_SPARE,
+       MR_EVT_ARGS_PD_INDEX,
+       MR_EVT_ARGS_DIAG_PASS,
+       MR_EVT_ARGS_DIAG_FAIL,
+       MR_EVT_ARGS_PD_LBA_LBA,
+       MR_EVT_ARGS_PORT_PHY,
+       MR_EVT_ARGS_PD_MISSING,
+       MR_EVT_ARGS_PD_ADDRESS,
+       MR_EVT_ARGS_BITMAP,
+       MR_EVT_ARGS_CONNECTOR,
+       MR_EVT_ARGS_PD_PD,
+       MR_EVT_ARGS_PD_FRU,
+       MR_EVT_ARGS_PD_PATHINFO,
+       MR_EVT_ARGS_PD_POWER_STATE,
+       MR_EVT_ARGS_GENERIC,
+};

+/*
+ * define constants for device list query options
+ */
+enum MR_PD_QUERY_TYPE {
+       MR_PD_QUERY_TYPE_ALL                = 0,
+       MR_PD_QUERY_TYPE_STATE              = 1,
+       MR_PD_QUERY_TYPE_POWER_STATE        = 2,
+       MR_PD_QUERY_TYPE_MEDIA_TYPE         = 3,
+       MR_PD_QUERY_TYPE_SPEED              = 4,
+       MR_PD_QUERY_TYPE_EXPOSED_TO_HOST    = 5,
+} __attribute__ ((packed));
+
+enum MR_PD_STATE {
+       MR_PD_STATE_UNCONFIGURED_GOOD   = 0x00,
+       MR_PD_STATE_UNCONFIGURED_BAD    = 0x01,
+       MR_PD_STATE_HOT_SPARE           = 0x02,
+       MR_PD_STATE_OFFLINE             = 0x10,
+       MR_PD_STATE_FAILED              = 0x11,
+       MR_PD_STATE_REBUILD             = 0x14,
+       MR_PD_STATE_ONLINE              = 0x18,
+       MR_PD_STATE_COPYBACK            = 0x20,
+       MR_PD_STATE_SYSTEM              = 0x40,
 };

 /*
+ * defines the physical drive address structure
+ */
+struct MR_PD_ADDRESS {
+       u16     deviceId;
+       u16     enclDeviceId;
+
+       union {
+               struct {
+                       u8  enclIndex;
+                       u8  slotNumber;
+               } mrPdAddress;
+               struct {
+                       u8  enclPosition;
+                       u8  enclConnectorIndex;
+               } mrEnclAddress;
+       };
+       u8      scsiDevType;
+       union {
+               u8      connectedPortBitmap;
+               u8      connectedPortNumbers;
+       };
+       u64     sasAddr[2];
+} __attribute__ ((packed));
+
+/*
+ * defines the physical drive list structure
+ */
+struct MR_PD_LIST {
+       u32             size;
+       u32             count;
+       struct MR_PD_ADDRESS   addr[1];
+} __attribute__ ((packed));
+
+struct megasas_pd_list {
+       u16             tid;
+       u8             driveType;
+       u8             driveState;
+} __attribute__ ((packed));
+
+/*
  * SAS controller properties
  */
 struct megasas_ctrl_prop {
@@ -553,6 +633,8 @@ struct megasas_ctrl_info {
 #define MEGASAS_DEFAULT_INIT_ID                        -1
 #define MEGASAS_MAX_LUN                                8
 #define MEGASAS_MAX_LD                         64
+#define MEGASAS_MAX_PD                          (MEGASAS_MAX_PD_CHANNELS * \
+                                               MEGASAS_MAX_DEV_PER_CHANNEL)

 #define MEGASAS_DBG_LVL                                1

@@ -1104,6 +1186,7 @@ struct megasas_instance {

        unsigned long base_addr;
        struct megasas_register_set __iomem *reg_set;
+       struct megasas_pd_list          pd_list[MEGASAS_MAX_PD];

        s8 init_id;


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 6/10] scsi: megaraid_sas - Report the Unconfigured PD (system PD) to OS
  2009-05-06  1:24                       ` [PATCH 5/10] scsi: megaraid_sas - Fixed load/unload issue and Fire the system pd DCDB cmd to MegaRAID SAS FW to get the system PDs Yang, Bo
@ 2009-05-06  1:35                         ` Yang, Bo
  2009-05-06  1:43                           ` [PATCH 7/10] scsi: megaraid_sas - Re-assign the Cmds to Application for the iMR controller Yang, Bo
  2009-05-06 21:20                         ` [PATCH 5/10] scsi: megaraid_sas - Fixed load/unload issue and Fire the system pd DCDB cmd to MegaRAID SAS FW to get the system PDs Andrew Morton
  1 sibling, 1 reply; 40+ messages in thread
From: Yang, Bo @ 2009-05-06  1:35 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Austria, Winston

Report the Un-configured PD (system PD) to OS.

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
drivers/scsi/megaraid/megaraid_sas.c |   57 +++++++++++++++++++----------------
 1 file changed, 32 insertions(+), 25 deletions(-)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-05-04 20:24:19.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-05-04 20:30:02.000000000 -0400
@@ -1114,24 +1114,45 @@ megasas_queue_command(struct scsi_cmnd *
        return 0;
 }

+static struct megasas_instance *megasas_lookup_instance(u16 host_no)
+{
+       int i;
+
+       for (i = 0; i < megasas_mgmt_info.max_index; i++) {
+
+               if ((megasas_mgmt_info.instance[i]) &&
+                   (megasas_mgmt_info.instance[i]->host->host_no == host_no))
+                       return megasas_mgmt_info.instance[i];
+       }
+
+       return NULL;
+}
+
 static int megasas_slave_configure(struct scsi_device *sdev)
 {
-       /*
-        * Don't export physical disk devices to the disk driver.
-        *
-        * FIXME: Currently we don't export them to the midlayer at all.
-        *        That will be fixed once LSI engineers have audited the
-        *        firmware for possible issues.
-        */
-       if (sdev->channel < MEGASAS_MAX_PD_CHANNELS && sdev->type == TYPE_DISK)
+       u16                     pd_index = 0;
+       struct megasas_instance *instance;
+       instance = megasas_lookup_instance(sdev->host->host_no);
+
+        /* only export system physical disk devices to the midlayer */
+       if ((sdev->channel < MEGASAS_MAX_PD_CHANNELS) &&
+                       (sdev->type == TYPE_DISK)) {
+               pd_index = (sdev->channel * MEGASAS_MAX_DEV_PER_CHANNEL) +
+                               sdev->id;
+               if ((instance->pd_list[pd_index].driveState ==
+                       MR_PD_STATE_SYSTEM)) {
+                       blk_queue_rq_timeout(sdev->request_queue,
+                                       MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
+                       return 0;
+               }
                return -ENXIO;
+       }

        /*
         * The RAID firmware may require extended timeouts.
         */
-       if (sdev->channel >= MEGASAS_MAX_PD_CHANNELS)
-               blk_queue_rq_timeout(sdev->request_queue,
-                                    MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
+       blk_queue_rq_timeout(sdev->request_queue,
+                            MEGASAS_DEFAULT_CMD_TIMEOUT * HZ);
        return 0;
 }

@@ -3453,20 +3474,6 @@ megasas_mgmt_fw_ioctl(struct megasas_ins
        return error;
 }

-static struct megasas_instance *megasas_lookup_instance(u16 host_no)
-{
-       int i;
-
-       for (i = 0; i < megasas_mgmt_info.max_index; i++) {
-
-               if ((megasas_mgmt_info.instance[i]) &&
-                   (megasas_mgmt_info.instance[i]->host->host_no == host_no))
-                       return megasas_mgmt_info.instance[i];
-       }
-
-       return NULL;
-}
-
 static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
 {
        struct megasas_iocpacket __user *user_ioc =

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 7/10] scsi: megaraid_sas - Re-assign the Cmds to Application for the iMR controller
  2009-05-06  1:35                         ` [PATCH 6/10] scsi: megaraid_sas - Report the Unconfigured PD (system PD) to OS Yang, Bo
@ 2009-05-06  1:43                           ` Yang, Bo
  2009-05-06  1:52                             ` [PATCH 8/10] scsi: megaraid_sas - Driver adds the IEEE SGE format to support SAS 2 controller Yang, Bo
  0 siblings, 1 reply; 40+ messages in thread
From: Yang, Bo @ 2009-05-06  1:43 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Austria, Winston

For the new SAS 2(0x73) controller, Driver needs to Re-allocate the cmds packets to Application

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
drivers/scsi/megaraid/megaraid_sas.c |   24 +++++++++++++++++++++---
 drivers/scsi/megaraid/megaraid_sas.h |    1 +
 2 files changed, 22 insertions(+), 3 deletions(-)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-05-04 20:32:42.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-05-04 20:37:32.000000000 -0400
@@ -1207,7 +1207,14 @@ static void megasas_complete_cmd_dpc(uns

                spin_lock_irqsave(instance->host->host_lock, flags);
                instance->flag &= ~MEGASAS_FW_BUSY;
-               instance->host->can_queue =
+               if ((instance->pdev->device ==
+                       PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+                       (instance->pdev->device ==
+                       PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+                       instance->host->can_queue =
+                               instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
+               } else
+                       instance->host->can_queue =
                                instance->max_fw_cmds - MEGASAS_INT_CMDS;

                spin_unlock_irqrestore(instance->host->host_lock, flags);
@@ -2736,7 +2743,13 @@ static int megasas_io_attach(struct mega
         */
        host->irq = instance->pdev->irq;
        host->unique_id = instance->unique_id;
-       host->can_queue = instance->max_fw_cmds - MEGASAS_INT_CMDS;
+       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+               (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+               host->can_queue =
+                       instance->max_fw_cmds - MEGASAS_SKINNY_INT_CMDS;
+       } else
+               host->can_queue =
+                       instance->max_fw_cmds - MEGASAS_INT_CMDS;
        host->this_id = instance->init_id;
        host->sg_tablesize = instance->max_num_sge;
        host->max_sectors = instance->max_sectors_per_req;
@@ -2871,7 +2884,6 @@ megasas_probe_one(struct pci_dev *pdev,
        spin_lock_init(&instance->completion_lock);

        mutex_init(&instance->aen_mutex);
-       sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);

        /*
         * Initialize PCI related and misc parameters
@@ -2881,6 +2893,12 @@ megasas_probe_one(struct pci_dev *pdev,
        instance->unique_id = pdev->bus->number << 8 | pdev->devfn;
        instance->init_id = MEGASAS_DEFAULT_INIT_ID;

+       if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+               (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+               sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
+       } else
+               sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
+
        megasas_dbg_lvl = 0;
        instance->flag = 0;
        instance->unload = 0;
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-05-04 20:32:42.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-05-04 20:00:31.000000000 -0400
@@ -665,6 +665,7 @@ struct megasas_ctrl_info {
  * is shown below
  */
 #define MEGASAS_INT_CMDS                       32
+#define MEGASAS_SKINNY_INT_CMDS                        5

 /*
  * FW can accept both 32 and 64 bit SGLs. We want to allocate 32/64 bit

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 8/10] scsi: megaraid_sas - Driver adds the IEEE SGE format to support SAS 2 controller
  2009-05-06  1:43                           ` [PATCH 7/10] scsi: megaraid_sas - Re-assign the Cmds to Application for the iMR controller Yang, Bo
@ 2009-05-06  1:52                             ` Yang, Bo
  2009-05-06  2:08                               ` [PATCH 9/10] scsi: megaraid_sas - Fixed the logic drives deleted and cmds pending in FW issue Yang, Bo
  0 siblings, 1 reply; 40+ messages in thread
From: Yang, Bo @ 2009-05-06  1:52 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Austria, Winston

Our new SAS 2 controller supports the IEEE SGE format.  Driver added this IEEE SGE support to the I/O routine.

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
drivers/scsi/megaraid/megaraid_sas.c |   81 +++++++++++++++++++++++++++++++----
 drivers/scsi/megaraid/megaraid_sas.h |    9 +++
 2 files changed, 82 insertions(+), 8 deletions(-)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-05-04 20:39:56.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-05-04 23:01:04.000000000 -0400
@@ -695,6 +695,35 @@ megasas_make_sgl64(struct megasas_instan
        return sge_count;
 }

+/**
+ * megasas_make_sgl_skinny - Prepares IEEE SGL
+ * @instance:           Adapter soft state
+ * @scp:                SCSI command from the mid-layer
+ * @mfi_sgl:            SGL to be filled in
+ *
+ * If successful, this function returns the number of SG elements. Otherwise,
+ * it returnes -1.
+ */
+static int
+megasas_make_sgl_skinny(struct megasas_instance *instance,
+               struct scsi_cmnd *scp, union megasas_sgl *mfi_sgl)
+{
+       int i;
+       int sge_count;
+       struct scatterlist *os_sgl;
+
+       sge_count = scsi_dma_map(scp);
+
+       if (sge_count) {
+               scsi_for_each_sg(scp, os_sgl, sge_count, i) {
+                       mfi_sgl->sge_skinny[i].length = sg_dma_len(os_sgl);
+                       mfi_sgl->sge_skinny[i].phys_addr =
+                                               sg_dma_address(os_sgl);
+               }
+       }
+       return sge_count;
+}
+
  /**
  * megasas_get_frame_count - Computes the number of frames
  * @frame_type         : type of frame- io or pthru frame
@@ -702,8 +731,8 @@ megasas_make_sgl64(struct megasas_instan
  *
  * Returns the number of frames required for numnber of sge's (sge_count)
  */
-
-static u32 megasas_get_frame_count(u8 sge_count, u8 frame_type)
+static u32 megasas_get_frame_count(struct megasas_instance *instance,
+                       u8 sge_count, u8 frame_type)
 {
        int num_cnt;
        int sge_bytes;
@@ -713,6 +742,10 @@ static u32 megasas_get_frame_count(u8 sg
        sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
            sizeof(struct megasas_sge32);

+       if (instance->flag_ieee) {
+               sge_sz = sizeof(struct megasas_sge_skinny);
+       }
+
        /*
         * Main frame can contain 2 SGEs for 64-bit SGLs and
         * 3 SGEs for 32-bit SGLs for ldio &
@@ -720,12 +753,16 @@ static u32 megasas_get_frame_count(u8 sg
         * 2 SGEs for 32-bit SGLs for pthru frame
         */
        if (unlikely(frame_type == PTHRU_FRAME)) {
-               if (IS_DMA64)
+               if (instance->flag_ieee == 1) {
+                       num_cnt = sge_count - 1;
+               } else if (IS_DMA64)
                        num_cnt = sge_count - 1;
                else
                        num_cnt = sge_count - 2;
        } else {
-               if (IS_DMA64)
+               if (instance->flag_ieee == 1) {
+                       num_cnt = sge_count - 1;
+               } else if (IS_DMA64)
                        num_cnt = sge_count - 2;
                else
                        num_cnt = sge_count - 3;
@@ -774,6 +811,10 @@ megasas_build_dcdb(struct megasas_instan
        else if (scp->sc_data_direction == PCI_DMA_NONE)
                flags = MFI_FRAME_DIR_NONE;

+       if (instance->flag_ieee == 1) {
+               flags |= MFI_FRAME_IEEE;
+       }
+
        /*
         * Prepare the DCDB frame
         */
@@ -803,7 +844,11 @@ megasas_build_dcdb(struct megasas_instan
        /*
         * Construct SGL
         */
-       if (IS_DMA64) {
+       if (instance->flag_ieee == 1) {
+               pthru->flags |= MFI_FRAME_SGL64;
+               pthru->sge_count = megasas_make_sgl_skinny(instance, scp,
+                                                     &pthru->sgl);
+       } else if (IS_DMA64) {
                pthru->flags |= MFI_FRAME_SGL64;
                pthru->sge_count = megasas_make_sgl64(instance, scp,
                                                      &pthru->sgl);
@@ -822,7 +867,7 @@ megasas_build_dcdb(struct megasas_instan
         * Compute the total number of frames this command consumes. FW uses
         * 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(instance, pthru->sge_count,
                                                        PTHRU_FRAME);

        return cmd->frame_count;
@@ -853,6 +898,10 @@ megasas_build_ldio(struct megasas_instan
        else if (scp->sc_data_direction == PCI_DMA_FROMDEVICE)
                flags = MFI_FRAME_DIR_READ;

+       if (instance->flag_ieee == 1) {
+               flags |= MFI_FRAME_IEEE;
+       }
+
        /*
         * Prepare the Logical IO frame: 2nd bit is zero for all read cmds
         */
@@ -923,7 +972,11 @@ megasas_build_ldio(struct megasas_instan
        /*
         * Construct SGL
         */
-       if (IS_DMA64) {
+       if (instance->flag_ieee) {
+               ldio->flags |= MFI_FRAME_SGL64;
+               ldio->sge_count = megasas_make_sgl_skinny(instance, scp,
+                                             &ldio->sgl);
+       } else if (IS_DMA64) {
                ldio->flags |= MFI_FRAME_SGL64;
                ldio->sge_count = megasas_make_sgl64(instance, scp, &ldio->sgl);
        } else
@@ -940,7 +993,8 @@ megasas_build_ldio(struct megasas_instan
         * Compute the total number of frames this command consumes. FW uses
         * this number to pull sufficient number of frames from host memory.
         */
-       cmd->frame_count = megasas_get_frame_count(ldio->sge_count, IO_FRAME);
+       cmd->frame_count = megasas_get_frame_count(instance,
+                       ldio->sge_count, IO_FRAME);

        return cmd->frame_count;
 }
@@ -1892,6 +1946,10 @@ static int megasas_create_frame_pool(str
        sge_sz = (IS_DMA64) ? sizeof(struct megasas_sge64) :
            sizeof(struct megasas_sge32);

+       if (instance->flag_ieee) {
+               sge_sz = sizeof(struct megasas_sge_skinny);
+       }
+
        /*
         * Calculated the number of 64byte frames required for SGL
         */
@@ -2687,6 +2745,11 @@ megasas_register_aen(struct megasas_inst
        dcmd->sgl.sge32[0].phys_addr = (u32) instance->evt_detail_h;
        dcmd->sgl.sge32[0].length = sizeof(struct megasas_evt_detail);

+       if (instance->aen_cmd != NULL) {
+               megasas_return_cmd(instance, cmd);
+               return 0;
+       }
+
        /*
         * Store reference to the cmd used to register for AEN. When an
         * application wants us to register for AEN, we have to abort this
@@ -2856,6 +2919,7 @@ megasas_probe_one(struct pci_dev *pdev,

        *instance->producer = 0;
        *instance->consumer = 0;
+       instance->flag_ieee = 0;
        megasas_poll_wait_aen = 0;
        instance->hotplug_wk = NULL;

@@ -2895,6 +2959,7 @@ megasas_probe_one(struct pci_dev *pdev,

        if ((instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
                (instance->pdev->device == PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+               instance->flag_ieee = 1;
                sema_init(&instance->ioctl_sem, MEGASAS_SKINNY_INT_CMDS);
        } else
                sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-05-04 20:39:57.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-05-04 20:00:32.000000000 -0400
@@ -96,6 +96,7 @@
 #define MFI_FRAME_DIR_WRITE                    0x0008
 #define MFI_FRAME_DIR_READ                     0x0010
 #define MFI_FRAME_DIR_BOTH                     0x0018
+#define MFI_FRAME_IEEE                         0x0020

 /*
  * Definition for cmd_status
@@ -742,10 +743,17 @@ struct megasas_sge64 {

 } __attribute__ ((packed));

+struct megasas_sge_skinny {
+       u64 phys_addr;
+       u32 length;
+       u32 flag;
+} __attribute__ ((packed));
+
 union megasas_sgl {

        struct megasas_sge32 sge32[1];
        struct megasas_sge64 sge64[1];
+       struct megasas_sge_skinny sge_skinny[1];

 } __attribute__ ((packed));

@@ -1226,6 +1234,7 @@ struct megasas_instance {

        u8 flag;
        u8 unload;
+       u8 flag_ieee;
        unsigned long last_time;

        struct timer_list io_completion_timer;

^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 9/10] scsi: megaraid_sas - Fixed the logic drives deleted and cmds pending in FW issue
  2009-05-06  1:52                             ` [PATCH 8/10] scsi: megaraid_sas - Driver adds the IEEE SGE format to support SAS 2 controller Yang, Bo
@ 2009-05-06  2:08                               ` Yang, Bo
  2009-05-06  2:12                                 ` [PATCH 10/10] scsi: megaraid_sas - Version and Documentation update Yang, Bo
  0 siblings, 1 reply; 40+ messages in thread
From: Yang, Bo @ 2009-05-06  2:08 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Austria, Winston

When we tested the SAS 2 controller, the system faced the issues of pending cmds in FW after deleted the logic drives.  This patch will fix this issue.

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
drivers/scsi/megaraid/megaraid_sas.c |   72 +++++++++++++++++++++++++++++------
 drivers/scsi/megaraid/megaraid_sas.h |   24 ++++++-----
 2 files changed, 74 insertions(+), 22 deletions(-)

diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-05-04 23:02:46.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-05-04 23:03:28.000000000 -0400
@@ -225,7 +225,10 @@ megasas_clear_intr_xscale(struct megasas
  * @regs :                     MFI register set
  */
 static inline void
-megasas_fire_cmd_xscale(dma_addr_t frame_phys_addr,u32 frame_count, struct megasas_register_set __iomem *regs)
+megasas_fire_cmd_xscale(struct megasas_instance *instance,
+               dma_addr_t frame_phys_addr,
+               u32 frame_count,
+               struct megasas_register_set __iomem *regs)
 {
        writel((frame_phys_addr >> 3)|(frame_count),
               &(regs)->inbound_queue_port);
@@ -322,7 +325,10 @@ megasas_clear_intr_ppc(struct megasas_re
  * @regs :                     MFI register set
  */
 static inline void
-megasas_fire_cmd_ppc(dma_addr_t frame_phys_addr, u32 frame_count, struct megasas_register_set __iomem *regs)
+megasas_fire_cmd_ppc(struct megasas_instance *instance,
+               dma_addr_t frame_phys_addr,
+               u32 frame_count,
+               struct megasas_register_set __iomem *regs)
 {
        writel((frame_phys_addr | (frame_count<<1))|1,
                        &(regs)->inbound_queue_port);
@@ -412,12 +418,18 @@ megasas_clear_intr_skinny(struct megasas
  * @regs :                     MFI register set
  */
 static inline void
-megasas_fire_cmd_skinny(dma_addr_t frame_phys_addr, u32 frame_count,
+megasas_fire_cmd_skinny(struct megasas_instance *instance,
+                       dma_addr_t frame_phys_addr,
+                       u32 frame_count,
                        struct megasas_register_set __iomem *regs)
 {
+       unsigned long flags;
+       spin_lock_irqsave(&instance->fire_lock, flags);
+
        writel(0, &(regs)->inbound_high_queue_port);
        writel((frame_phys_addr | (frame_count<<1))|1,
                        &(regs)->inbound_low_queue_port);
+       spin_unlock_irqrestore(&instance->fire_lock, flags);
        /*msleep(5);*/
 }

@@ -507,7 +519,9 @@ megasas_clear_intr_gen2(struct megasas_r
  * @regs :                     MFI register set
  */
 static inline void
-megasas_fire_cmd_gen2(dma_addr_t frame_phys_addr, u32 frame_count,
+megasas_fire_cmd_gen2(struct megasas_instance *instance,
+                       dma_addr_t frame_phys_addr,
+                       u32 frame_count,
                        struct megasas_register_set __iomem *regs)
 {
        writel((frame_phys_addr | (frame_count<<1))|1,
@@ -549,7 +563,8 @@ megasas_issue_polled(struct megasas_inst
        /*
         * Issue the frame using inbound queue port
         */
-       instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
+       instance->instancet->fire_cmd(instance,
+                       cmd->frame_phys_addr, 0, instance->reg_set);

        /*
         * Wait for cmd_status to change
@@ -580,7 +595,8 @@ megasas_issue_blocked_cmd(struct megasas
 {
        cmd->cmd_status = ENODATA;

-       instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
+       instance->instancet->fire_cmd(instance,
+                       cmd->frame_phys_addr, 0, instance->reg_set);

        wait_event_timeout(instance->int_cmd_wait_q, (cmd->cmd_status != ENODATA),
                MEGASAS_INTERNAL_CMD_WAIT_TIME*HZ);
@@ -625,7 +641,8 @@ megasas_issue_blocked_abort_cmd(struct m
        cmd->sync_cmd = 1;
        cmd->cmd_status = 0xFF;

-       instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
+       instance->instancet->fire_cmd(instance,
+                       cmd->frame_phys_addr, 0, instance->reg_set);

        /*
         * Wait for this cmd to complete
@@ -1151,7 +1168,8 @@ megasas_queue_command(struct scsi_cmnd *
         */
        atomic_inc(&instance->fw_outstanding);

-       instance->instancet->fire_cmd(cmd->frame_phys_addr ,cmd->frame_count-1,instance->reg_set);
+       instance->instancet->fire_cmd(instance, cmd->frame_phys_addr,
+                               cmd->frame_count-1, instance->reg_set);
        /*
         * Check if we have pend cmds to be completed
         */
@@ -1313,8 +1331,16 @@ static int megasas_wait_for_outstanding(
                * Send signal to FW to stop processing any pending cmds.
                * The controller will be taken offline by the OS now.
                */
-               writel(MFI_STOP_ADP,
+               if ((instance->pdev->device ==
+                       PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
+                       (instance->pdev->device ==
+                       PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
+                       writel(MFI_STOP_ADP,
+                               &instance->reg_set->reserved_0[0]);
+               } else {
+                       writel(MFI_STOP_ADP,
                                &instance->reg_set->inbound_doorbell);
+               }
                megasas_dump_pending_frames(instance);
                instance->hw_crit_error = 1;
                return FAILED;
@@ -1761,7 +1787,7 @@ megasas_transition_to_ready(struct megas
                        /*
                         * Set the CLR bit in inbound doorbell
                         */
-                       if ((instance->pdev->device == \
+                       if ((instance->pdev->device ==
                                PCI_DEVICE_ID_LSI_SAS0073SKINNY) ||
                                (instance->pdev->device ==
                                PCI_DEVICE_ID_LSI_SAS0071SKINNY)) {
@@ -2760,7 +2786,8 @@ megasas_register_aen(struct megasas_inst
        /*
         * Issue the aen registration frame
         */
-       instance->instancet->fire_cmd(cmd->frame_phys_addr ,0,instance->reg_set);
+       instance->instancet->fire_cmd(instance,
+                       cmd->frame_phys_addr, 0, instance->reg_set);

        return 0;
 }
@@ -2945,6 +2972,7 @@ megasas_probe_one(struct pci_dev *pdev,
        init_waitqueue_head(&instance->abort_cmd_wait_q);

        spin_lock_init(&instance->cmd_pool_lock);
+       spin_lock_init(&instance->fire_lock);
        spin_lock_init(&instance->completion_lock);

        mutex_init(&instance->aen_mutex);
@@ -3134,6 +3162,7 @@ megasas_suspend(struct pci_dev *pdev, pm
        struct megasas_instance *instance;

        instance = pci_get_drvdata(pdev);
+       instance->unload = 1;
        host = instance->host;

        if (poll_mode_io)
@@ -3230,6 +3259,8 @@ megasas_resume(struct pci_dev *pdev)
                megasas_start_timer(instance, &instance->io_completion_timer,
                                megasas_io_completion_timer,
                                MEGASAS_COMPLETION_TIMER_INTERVAL);
+       instance->unload = 0;
+
        return 0;

 fail_irq:
@@ -3580,6 +3611,17 @@ static int megasas_mgmt_ioctl_fw(struct
                goto out_kfree_ioc;
        }

+       if (instance->hw_crit_error == 1) {
+               printk(KERN_DEBUG "Controller in Crit ERROR\n");
+               error = -ENODEV;
+               goto out_kfree_ioc;
+       }
+
+       if (instance->unload == 1) {
+               error = -ENODEV;
+               goto out_kfree_ioc;
+       }
+
        /*
         * We will allow only MEGASAS_INT_CMDS number of parallel ioctl cmds
         */
@@ -3615,6 +3657,14 @@ static int megasas_mgmt_ioctl_aen(struct
        if (!instance)
                return -ENODEV;

+       if (instance->hw_crit_error == 1) {
+               error = -ENODEV;
+       }
+
+       if (instance->unload == 1) {
+               return -ENODEV;
+       }
+
        mutex_lock(&instance->aen_mutex);
        error = megasas_register_aen(instance, aen.seq_num,
                                     aen.class_locale_word);
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-05-04 20:44:37.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-05-04 20:00:31.000000000 -0400
@@ -1167,17 +1167,6 @@ struct megasas_evt_detail {

 } __attribute__ ((packed));

- struct megasas_instance_template {
-       void (*fire_cmd)(dma_addr_t ,u32 ,struct megasas_register_set __iomem *);
-
-       void (*enable_intr)(struct megasas_register_set __iomem *) ;
-       void (*disable_intr)(struct megasas_register_set __iomem *);
-
-       int (*clear_intr)(struct megasas_register_set __iomem *);
-
-       u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *);
- };
-
 struct megasas_aen_event {
        struct work_struct hotplug_work;
        struct megasas_instance *instance;
@@ -1207,6 +1196,7 @@ struct megasas_instance {
        struct list_head cmd_pool;
        spinlock_t cmd_pool_lock;
        /* used to synch producer, consumer ptrs in dpc */
+       spinlock_t fire_lock;
        spinlock_t completion_lock;
        struct dma_pool *frame_dma_pool;
        struct dma_pool *sense_dma_pool;
@@ -1240,6 +1230,18 @@ struct megasas_instance {
        struct timer_list io_completion_timer;
 };

+struct megasas_instance_template {
+       void (*fire_cmd)(struct megasas_instance *, dma_addr_t, \
+               u32, struct megasas_register_set __iomem *);
+
+       void (*enable_intr)(struct megasas_register_set __iomem *) ;
+       void (*disable_intr)(struct megasas_register_set __iomem *);
+
+       int (*clear_intr)(struct megasas_register_set __iomem *);
+
+       u32 (*read_fw_status_reg)(struct megasas_register_set __iomem *);
+};
+
 #define MEGASAS_IS_LOGICAL(scp)                                                \
        (scp->device->channel < MEGASAS_MAX_PD_CHANNELS) ? 0 : 1


^ permalink raw reply	[flat|nested] 40+ messages in thread

* [PATCH 10/10] scsi: megaraid_sas - Version and Documentation update
  2009-05-06  2:08                               ` [PATCH 9/10] scsi: megaraid_sas - Fixed the logic drives deleted and cmds pending in FW issue Yang, Bo
@ 2009-05-06  2:12                                 ` Yang, Bo
  0 siblings, 0 replies; 40+ messages in thread
From: Yang, Bo @ 2009-05-06  2:12 UTC (permalink / raw)
  To: Yang, Bo, James Bottomley
  Cc: linux-scsi, akpm, linux-kernel, Austria, Winston

Driver Version and Documentation Update

Signed-off-by Bo Yang<bo.yang@lsi.com>

---
Documentation/scsi/ChangeLog.megaraid_sas |   30 ++++++++++++++++++++++++++++++
 drivers/scsi/megaraid/megaraid_sas.c      |    2 +-
 drivers/scsi/megaraid/megaraid_sas.h      |    6 +++---
 3 files changed, 34 insertions(+), 4 deletions(-)

diff -rupN linux-2.6.28_orig/Documentation/scsi/ChangeLog.megaraid_sas linux-2.6.28_new/Documentation/scsi/ChangeLog.megaraid_sas
--- linux-2.6.28_orig/Documentation/scsi/ChangeLog.megaraid_sas 2009-05-04 20:00:32.000000000 -0400
+++ linux-2.6.28_new/Documentation/scsi/ChangeLog.megaraid_sas  2009-05-04 20:00:32.000000000 -0400
@@ -1,4 +1,34 @@

+1 Release Date    : Tues. Feb. 10, 2009 10:12:45 PST 2009 -
+                        (emaild-id:megaraidlinux@lsi.com)
+                        Bo Yang
+
+2 Current Version : 00.00.04.08
+3 Older Version   : 00.00.04.01
+
+1.     Add the Tape drive fix to the driver: If the command is for the tape
+               device, set the pthru timeout to the os layer timeout value.
+
+2.     Add Poll_wait mechanism to Gen-2 Linux driv.
+               In the aen handler, driver needs to wakeup poll handler
+               similar to the way it raises SIGIO. Driver needs to reregister
+               for AEN with the FW when it receives AEN. This will ensure AEN
+               continuity and avoid depending upon storelib to continue events.
+
+3.     Add new controller 0x73(new SAS2) support to the driver.
+
+4.     Report the unconfigured PD (system PD) to OS.
+
+5.     Add the IEEE SGL support to the driver
+
+6.     Reasign the Application cmds to 0x73 controller
+
+7.     Fixed the two AEN cmds pending in FW.
+
+8.     Fixed the logic drive deleted and pemding cmds pending in fw issue.
+
+9.     Fixed the driver load and unload issue.
+
 1 Release Date    : Thur.July. 24 11:41:51 PST 2008 -
                        (emaild-id:megaraidlinux@lsi.com)
                        Sumant Patro
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.c      2009-05-04 23:04:47.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.c       2009-05-04 23:05:23.000000000 -0400
@@ -10,7 +10,7 @@
  *        2 of the License, or (at your option) any later version.
  *
  * FILE                : megaraid_sas.c
- * Version     : v00.00.04.01-rc1
+ * Version     : v00.00.04.08-rc1
  *
  * Authors:
  *     (email-id : megaraidlinux@lsi.com)
diff -rupN linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h
--- linux-2.6.28_orig/drivers/scsi/megaraid/megaraid_sas.h      2009-05-04 20:48:19.000000000 -0400
+++ linux-2.6.28_new/drivers/scsi/megaraid/megaraid_sas.h       2009-05-04 20:00:32.000000000 -0400
@@ -18,9 +18,9 @@
 /*
  * MegaRAID SAS Driver meta data
  */
-#define MEGASAS_VERSION                                "00.00.04.01"
-#define MEGASAS_RELDATE                                "July 24, 2008"
-#define MEGASAS_EXT_VERSION                    "Thu July 24 11:41:51 PST 2008"
+#define MEGASAS_VERSION                                "00.00.04.08-RC1"
+#define MEGASAS_RELDATE                                "May 05, 2009"
+#define MEGASAS_EXT_VERSION                    "Tues May 05, 11:41:51 PST 2008"

 /*
  * Device IDs

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 2/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-I)
  2009-05-06  0:25                 ` [PATCH 2/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-I) Yang, Bo
  2009-05-06  0:41                   ` [PATCH 3/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-II) Yang, Bo
@ 2009-05-06 21:17                   ` Andrew Morton
  2009-05-07 14:56                     ` Yang, Bo
  1 sibling, 1 reply; 40+ messages in thread
From: Andrew Morton @ 2009-05-06 21:17 UTC (permalink / raw)
  To: Yang, Bo
  Cc: Bo.Yang, James.Bottomley, linux-scsi, linux-kernel, Winston.Austria

On Tue, 5 May 2009 18:25:55 -0600
"Yang, Bo" <Bo.Yang@lsi.com> wrote:

> Add Poll_wait mechanism to SAS-2 MegaRAID SAS Linux driver. Driver will wakeup poll after the driver get event from MegaRAID SAS FW.  Driver also reregisters for Event with the FW when it receives AEN.
> 

Seems fairly strage to be adding poll support to a scsi driver, but I
see it isn't the first driver to do this.

> 
>
> ...
>
> @@ -1295,13 +1301,20 @@ megasas_service_aen(struct megasas_insta
>         /*
>          * Don't signal app if it is just an aborted previously registered aen
>          */
> -       if (!cmd->abort_aen)
> +       if ((!cmd->abort_aen) && (instance->unload == 0)) {
> +               megasas_poll_wait_aen = 1;
> +               wake_up(&megasas_poll_wait);
>                 kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
> +       }
>         else
>                 cmd->abort_aen = 0;
> 
>         instance->aen_cmd = NULL;
>         megasas_return_cmd(instance, cmd);
> +
> +       if ((!cmd->abort_aen) && (instance->unload == 0)) {
> +               megasas_aen_polling(instance);
> +       }

I see you're not a big fan of checkpatch, nor of kernel coding style :(

>  }
> 
>  /*
> @@ -2583,6 +2596,8 @@ megasas_probe_one(struct pci_dev *pdev,
> 
>         *instance->producer = 0;
>         *instance->consumer = 0;
> +       megasas_poll_wait_aen = 0;
> +       instance->hotplug_wk = NULL;
> 
>         instance->evt_detail = pci_alloc_consistent(pdev,
>                                                     sizeof(struct
> @@ -2621,6 +2636,7 @@ megasas_probe_one(struct pci_dev *pdev,
> 
>         megasas_dbg_lvl = 0;
>         instance->flag = 0;
> +       instance->unload = 0;
>         instance->last_time = 0;
> 
>         /*
> @@ -2924,6 +2940,7 @@ static void __devexit megasas_detach_one
>         struct megasas_instance *instance;
> 
>         instance = pci_get_drvdata(pdev);
> +       instance->unload = 1;
>         host = instance->host;
> 
>         if (poll_mode_io)
> @@ -2932,6 +2949,15 @@ static void __devexit megasas_detach_one
>         scsi_remove_host(instance->host);
>         megasas_flush_cache(instance);
>         megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
> +
> +       /*
> +       * cancel the delayed work if this work still in queue
> +       */
> +       if (instance->hotplug_wk != NULL) {
> +               cancel_delayed_work(
> +                       (struct delayed_work *)instance->hotplug_wk);

whah?  Can't do that!  cancel_delayed_work() will do del_timer_sync()
on megasas_instance.flag and will crash.

> +                       

> +               flush_scheduled_work();
> +       }
>         tasklet_kill(&instance->isr_tasklet);
> 
>         /*
> @@ -3027,6 +3053,19 @@ static int megasas_mgmt_fasync(int fd, s
>  }
> 
>  /**
> + * megasas_mgmt_poll -  char node "poll" entry point
> + * */
> +static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
> +{
> +       unsigned int mask = 0;
> +       poll_wait(file, &megasas_poll_wait, wait);
> +       if (megasas_poll_wait_aen) {
> +               mask |=   (POLLIN | POLLRDNORM);
> +       }
> +       return mask;
> +}
> +
> +/**
>   * megasas_mgmt_fw_ioctl -     Issues management ioctls to FW
>   * @instance:                  Adapter soft state
>   * @argp:                      User's ioctl packet
> @@ -3348,6 +3387,7 @@ static const struct file_operations mega
>         .open = megasas_mgmt_open,
>         .fasync = megasas_mgmt_fasync,
>         .unlocked_ioctl = megasas_mgmt_ioctl,
> +       .poll = megasas_mgmt_poll,
>  #ifdef CONFIG_COMPAT
>         .compat_ioctl = megasas_mgmt_compat_ioctl,
>  #endif
> @@ -3462,6 +3502,100 @@ out:
>         return retval;
>  }
> 
> +static void
> +megasas_scsi_scan_host(struct work_struct *work)
> +{
> +       struct megasas_aen_event *ev = container_of(work,
> +               struct megasas_aen_event, hotplug_work);
> +       struct megasas_instance *instance = ev->instance;
> +
> +       instance->hotplug_wk = NULL;
> +       if (!instance) {

oh come on.  If this test returns true then the preceding statement
just oopsed the kernel.

> +               printk(KERN_ERR "%s: invalid instance!\n", __FUNCTION__);
> +               kfree(ev);
> +               return;
> +       }
> +
> +       printk(KERN_INFO "%s[%d]: scanning ...\n",
> +               __FUNCTION__, instance->host->host_no);
> +       scsi_scan_host(instance->host);
> +       kfree(ev);
> +}
> +
> +static void
> +megasas_aen_polling(struct megasas_instance *instance)
> +{
> +       union megasas_evt_class_locale class_locale;
> +       int doscan = 0;
> +       u32 seq_num;
> +       int error;
> +
> +       if (instance->evt_detail) {
> +               printk(KERN_INFO "%s[%d]: event code 0x%04x\n", __FUNCTION__,

Users of checkpatch know to use __func__.

> +                       instance->host->host_no, instance->evt_detail->code);
> +
> +               switch (instance->evt_detail->code) {
> +
> +               case MR_EVT_LD_CREATED:
> +               case MR_EVT_PD_INSERTED:
> +               case MR_EVT_LD_DELETED:
> +               case MR_EVT_LD_OFFLINE:
> +               case MR_EVT_CFG_CLEARED:
> +               case MR_EVT_PD_REMOVED:
> +               case MR_EVT_FOREIGN_CFG_IMPORTED:
> +               case MR_EVT_LD_STATE_CHANGE:
> +               case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
> +                       doscan = 1;
> +                       break;
> +               default:
> +                       doscan = 0;
> +                       break;
> +               }
> +       } else {
> +               printk(KERN_ERR "%s[%d]: invalid evt_detail!\n",
> +                       __FUNCTION__, instance->host->host_no);
> +               return;
> +       }
> +
> +       if (doscan) {
> +               struct megasas_aen_event *ev;
> +               ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
> +               if (!ev) {
> +                       printk(KERN_ERR "%s: out of memory\n", __FUNCTION__);
> +               } else {
> +                       ev->instance = instance;
> +                       instance->hotplug_wk = &ev->hotplug_work;
> +                       INIT_WORK(&ev->hotplug_work, megasas_scsi_scan_host);
> +                       schedule_delayed_work(
> +                               (struct delayed_work *)&ev->hotplug_work, 0);
> +               }
> +       }
> +
> +       seq_num = instance->evt_detail->seq_num + 1;
> +
> +       /**
> +       * Register AEN with FW for latest sequence number plus 1
> +       **/

The /** token is used to introduce a kerneldoc comment.  This is not a
kerneldoc comment.

> +       class_locale.members.reserved = 0;
> +       class_locale.members.locale = MR_EVT_LOCALE_ALL;
> +       class_locale.members.class = MR_EVT_CLASS_DEBUG;
> +
> +       if ( instance->aen_cmd != NULL ) {
> +               return ;
> +       }
> +
> +       mutex_lock(&instance->aen_mutex);
> +       error = megasas_register_aen(instance, seq_num,
> +                               class_locale.word);
> +       mutex_unlock(&instance->aen_mutex);
> +
> +       if (error)
> +               printk(KERN_ERR "%s[%d]: register aen failed error %x\n",
> +                        __FUNCTION__, instance->host->host_no, error);
> +}
> +
> +
>
> ...
>
> @@ -1118,8 +1134,10 @@ struct megasas_instance {
> 
>         struct megasas_instance_template *instancet;
>         struct tasklet_struct isr_tasklet;
> +       struct work_struct *hotplug_wk;

"hotplug_work"

> 
>         u8 flag;
> +       u8 unload;
>         unsigned long last_time;
> 
>         struct timer_list io_completion_timer;

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 3/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-II)
  2009-05-06  0:41                   ` [PATCH 3/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-II) Yang, Bo
  2009-05-06  1:11                     ` [PATCH 4/10] scsi: megaraid_sas - Add New SAS 2 (iMR) controller support to the driver Yang, Bo
@ 2009-05-06 21:19                     ` Andrew Morton
  1 sibling, 0 replies; 40+ messages in thread
From: Andrew Morton @ 2009-05-06 21:19 UTC (permalink / raw)
  To: Yang, Bo
  Cc: Bo.Yang, James.Bottomley, linux-scsi, linux-kernel, Winston.Austria

On Tue, 5 May 2009 18:41:45 -0600
"Yang, Bo" <Bo.Yang@lsi.com> wrote:

> @@ -3645,6 +3657,12 @@ static int __init megasas_init(void)
>                                   &driver_attr_release_date);
>         if (rval)
>                 goto err_dcf_rel_date;
> +
> +       rval = driver_create_file(&megasas_pci_driver.driver,
> +                               &driver_attr_support_poll_for_event);
> +       if (rval)
> +               goto err_dcf_support_poll_for_event;

This goto will be taken if the file wasn't successfully added.

>         rval = driver_create_file(&megasas_pci_driver.driver,
>                                   &driver_attr_dbg_lvl);
>         if (rval)
> @@ -3662,6 +3680,11 @@ err_dcf_poll_mode_io:
>  err_dcf_dbg_lvl:
>         driver_remove_file(&megasas_pci_driver.driver,
>                            &driver_attr_release_date);
> +
> +err_dcf_support_poll_for_event:
> +       driver_remove_file(&megasas_pci_driver.driver,
> +                       &driver_attr_support_poll_for_event);

And we then try to remove something which isn't there.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* Re: [PATCH 5/10] scsi: megaraid_sas - Fixed load/unload issue and Fire the system pd DCDB cmd to MegaRAID SAS FW to get the system PDs
  2009-05-06  1:24                       ` [PATCH 5/10] scsi: megaraid_sas - Fixed load/unload issue and Fire the system pd DCDB cmd to MegaRAID SAS FW to get the system PDs Yang, Bo
  2009-05-06  1:35                         ` [PATCH 6/10] scsi: megaraid_sas - Report the Unconfigured PD (system PD) to OS Yang, Bo
@ 2009-05-06 21:20                         ` Andrew Morton
  2009-05-07 15:05                           ` Yang, Bo
  1 sibling, 1 reply; 40+ messages in thread
From: Andrew Morton @ 2009-05-06 21:20 UTC (permalink / raw)
  To: Yang, Bo
  Cc: Bo.Yang, James.Bottomley, linux-scsi, linux-kernel, Winston.Austria

On Tue, 5 May 2009 19:24:07 -0600
"Yang, Bo" <Bo.Yang@lsi.com> wrote:

> +} __attribute__ ((packed));

Please use __packed.  I'd suggest this be done as a single driver-wide cleanup
patch at a convenient time.

^ permalink raw reply	[flat|nested] 40+ messages in thread

* RE: [PATCH 2/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-I)
  2009-05-06 21:17                   ` [PATCH 2/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-I) Andrew Morton
@ 2009-05-07 14:56                     ` Yang, Bo
  0 siblings, 0 replies; 40+ messages in thread
From: Yang, Bo @ 2009-05-07 14:56 UTC (permalink / raw)
  To: Andrew Morton; +Cc: James.Bottomley, linux-scsi, linux-kernel, Austria, Winston

Andrew,

Thanks for the review and good catch.  The following is the changes I did:

1. 

> +       if ((!cmd->abort_aen) && (instance->unload == 0)) {
> +               megasas_aen_polling(instance);
> +       }

> I see you're not a big fan of checkpatch, nor of kernel coding style :(

Changed to:
+       if (!cmd->abort_aen && instance->unload == 0) {
+               megasas_aen_polling(instance);
+       }

2.

> +       /*
> +       * cancel the delayed work if this work still in queue
> +       */
> +       if (instance->hotplug_wk != NULL) {
> +               cancel_delayed_work(
> +                       (struct delayed_work *)instance->hotplug_wk);

>whah?  Can't do that!  cancel_delayed_work() will do del_timer_sync()
>on megasas_instance.flag and will crash.

> +                       

> +               flush_scheduled_work();

Changed to:
+
+       /*
+       * cancel the delayed work if this work still in queue
+       */
+       if (instance->ev != NULL) {
+               struct megasas_aen_event *ev = instance->ev;
+               cancel_delayed_work(
+                       (struct delayed_work *)&ev->hotplug_work);
+               flush_scheduled_work();
+               instance->ev = NULL;
+       }
        tasklet_kill(&instance->isr_tasklet);

.....

+                       ev->instance = instance;
+                       instance->ev = ev;
+                       INIT_WORK(&ev->hotplug_work, megasas_scsi_scan_host);
+                       schedule_delayed_work(
+                               (struct delayed_work *)&ev->hotplug_work, 0);


3.
> +       instance->hotplug_wk = NULL;
> +       if (!instance) {

>oh come on.  If this test returns true then the preceding statement
>just oopsed the kernel.

> +               printk(KERN_ERR "%s: invalid instance!\n", __FUNCTION__); 

Changed to:

+static void
+megasas_scsi_scan_host(struct work_struct *work)
+{
+       struct megasas_aen_event *ev = container_of(work,
+               struct megasas_aen_event, hotplug_work);
+       struct megasas_instance *instance = ev->instance;
+
+       if (!instance) {
+               printk(KERN_ERR "invalid instance!\n");
+               kfree(ev);
+               return;
+       }
+
+       printk(KERN_INFO "scanning ...\n");
+       scsi_scan_host(instance->host);
+       kfree(ev);
+       instance->ev = NULL;
+}

4. 

> +       if (instance->evt_detail) {
> +               printk(KERN_INFO "%s[%d]: event code 0x%04x\n", __FUNCTION__,

Users of checkpatch know to use __func__.

> +                       instance->host->host_no, instance->evt_detail-

Changed to:

+               printk(KERN_INFO "get event code 0x%04x\n",
+                       instance->evt_detail->code); 


5.

> +
> +       /**
> +       * Register AEN with FW for latest sequence number plus 1
> +       **/

>The /** token is used to introduce a kerneldoc comment.  This is not a
>kerneldoc comment.

Changed to:

+	/* Register AEN with FW for latest sequence number plus 1 */

6. 
>         struct tasklet_struct isr_tasklet;
> +       struct work_struct *hotplug_wk;

>"hotplug_work"

+       struct megasas_aen_event *ev;

 
Thanks,

Bo Yang

-----Original Message-----
From: Andrew Morton [mailto:akpm@linux-foundation.org] 
Sent: Wednesday, May 06, 2009 5:17 PM
To: Yang, Bo
Cc: Yang, Bo; James.Bottomley@HansenPartnership.com; linux-scsi@vger.kernel.org; linux-kernel@vger.kernel.org; Austria, Winston
Subject: Re: [PATCH 2/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-I)

On Tue, 5 May 2009 18:25:55 -0600
"Yang, Bo" <Bo.Yang@lsi.com> wrote:

> Add Poll_wait mechanism to SAS-2 MegaRAID SAS Linux driver. Driver will wakeup poll after the driver get event from MegaRAID SAS FW.  Driver also reregisters for Event with the FW when it receives AEN.
> 

Seems fairly strage to be adding poll support to a scsi driver, but I
see it isn't the first driver to do this.

> 
>
> ...
>
> @@ -1295,13 +1301,20 @@ megasas_service_aen(struct megasas_insta
>         /*
>          * Don't signal app if it is just an aborted previously registered aen
>          */
> -       if (!cmd->abort_aen)
> +       if ((!cmd->abort_aen) && (instance->unload == 0)) {
> +               megasas_poll_wait_aen = 1;
> +               wake_up(&megasas_poll_wait);
>                 kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
> +       }
>         else
>                 cmd->abort_aen = 0;
> 
>         instance->aen_cmd = NULL;
>         megasas_return_cmd(instance, cmd);
> +
> +       if ((!cmd->abort_aen) && (instance->unload == 0)) {
> +               megasas_aen_polling(instance);
> +       }

I see you're not a big fan of checkpatch, nor of kernel coding style :(

>  }
> 
>  /*
> @@ -2583,6 +2596,8 @@ megasas_probe_one(struct pci_dev *pdev,
> 
>         *instance->producer = 0;
>         *instance->consumer = 0;
> +       megasas_poll_wait_aen = 0;
> +       instance->hotplug_wk = NULL;
> 
>         instance->evt_detail = pci_alloc_consistent(pdev,
>                                                     sizeof(struct
> @@ -2621,6 +2636,7 @@ megasas_probe_one(struct pci_dev *pdev,
> 
>         megasas_dbg_lvl = 0;
>         instance->flag = 0;
> +       instance->unload = 0;
>         instance->last_time = 0;
> 
>         /*
> @@ -2924,6 +2940,7 @@ static void __devexit megasas_detach_one
>         struct megasas_instance *instance;
> 
>         instance = pci_get_drvdata(pdev);
> +       instance->unload = 1;
>         host = instance->host;
> 
>         if (poll_mode_io)
> @@ -2932,6 +2949,15 @@ static void __devexit megasas_detach_one
>         scsi_remove_host(instance->host);
>         megasas_flush_cache(instance);
>         megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
> +
> +       /*
> +       * cancel the delayed work if this work still in queue
> +       */
> +       if (instance->hotplug_wk != NULL) {
> +               cancel_delayed_work(
> +                       (struct delayed_work *)instance->hotplug_wk);

whah?  Can't do that!  cancel_delayed_work() will do del_timer_sync()
on megasas_instance.flag and will crash.

> +                       

> +               flush_scheduled_work();
> +       }
>         tasklet_kill(&instance->isr_tasklet);
> 
>         /*
> @@ -3027,6 +3053,19 @@ static int megasas_mgmt_fasync(int fd, s
>  }
> 
>  /**
> + * megasas_mgmt_poll -  char node "poll" entry point
> + * */
> +static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
> +{
> +       unsigned int mask = 0;
> +       poll_wait(file, &megasas_poll_wait, wait);
> +       if (megasas_poll_wait_aen) {
> +               mask |=   (POLLIN | POLLRDNORM);
> +       }
> +       return mask;
> +}
> +
> +/**
>   * megasas_mgmt_fw_ioctl -     Issues management ioctls to FW
>   * @instance:                  Adapter soft state
>   * @argp:                      User's ioctl packet
> @@ -3348,6 +3387,7 @@ static const struct file_operations mega
>         .open = megasas_mgmt_open,
>         .fasync = megasas_mgmt_fasync,
>         .unlocked_ioctl = megasas_mgmt_ioctl,
> +       .poll = megasas_mgmt_poll,
>  #ifdef CONFIG_COMPAT
>         .compat_ioctl = megasas_mgmt_compat_ioctl,
>  #endif
> @@ -3462,6 +3502,100 @@ out:
>         return retval;
>  }
> 
> +static void
> +megasas_scsi_scan_host(struct work_struct *work)
> +{
> +       struct megasas_aen_event *ev = container_of(work,
> +               struct megasas_aen_event, hotplug_work);
> +       struct megasas_instance *instance = ev->instance;
> +
> +       instance->hotplug_wk = NULL;
> +       if (!instance) {

oh come on.  If this test returns true then the preceding statement
just oopsed the kernel.

> +               printk(KERN_ERR "%s: invalid instance!\n", __FUNCTION__);
> +               kfree(ev);
> +               return;
> +       }
> +
> +       printk(KERN_INFO "%s[%d]: scanning ...\n",
> +               __FUNCTION__, instance->host->host_no);
> +       scsi_scan_host(instance->host);
> +       kfree(ev);
> +}
> +
> +static void
> +megasas_aen_polling(struct megasas_instance *instance)
> +{
> +       union megasas_evt_class_locale class_locale;
> +       int doscan = 0;
> +       u32 seq_num;
> +       int error;
> +
> +       if (instance->evt_detail) {
> +               printk(KERN_INFO "%s[%d]: event code 0x%04x\n", __FUNCTION__,

Users of checkpatch know to use __func__.

> +                       instance->host->host_no, instance->evt_detail->code);
> +
> +               switch (instance->evt_detail->code) {
> +
> +               case MR_EVT_LD_CREATED:
> +               case MR_EVT_PD_INSERTED:
> +               case MR_EVT_LD_DELETED:
> +               case MR_EVT_LD_OFFLINE:
> +               case MR_EVT_CFG_CLEARED:
> +               case MR_EVT_PD_REMOVED:
> +               case MR_EVT_FOREIGN_CFG_IMPORTED:
> +               case MR_EVT_LD_STATE_CHANGE:
> +               case MR_EVT_CTRL_HOST_BUS_SCAN_REQUESTED:
> +                       doscan = 1;
> +                       break;
> +               default:
> +                       doscan = 0;
> +                       break;
> +               }
> +       } else {
> +               printk(KERN_ERR "%s[%d]: invalid evt_detail!\n",
> +                       __FUNCTION__, instance->host->host_no);
> +               return;
> +       }
> +
> +       if (doscan) {
> +               struct megasas_aen_event *ev;
> +               ev = kzalloc(sizeof(*ev), GFP_ATOMIC);
> +               if (!ev) {
> +                       printk(KERN_ERR "%s: out of memory\n", __FUNCTION__);
> +               } else {
> +                       ev->instance = instance;
> +                       instance->hotplug_wk = &ev->hotplug_work;
> +                       INIT_WORK(&ev->hotplug_work, megasas_scsi_scan_host);
> +                       schedule_delayed_work(
> +                               (struct delayed_work *)&ev->hotplug_work, 0);
> +               }
> +       }
> +
> +       seq_num = instance->evt_detail->seq_num + 1;
> +
> +       /**
> +       * Register AEN with FW for latest sequence number plus 1
> +       **/

The /** token is used to introduce a kerneldoc comment.  This is not a
kerneldoc comment.

> +       class_locale.members.reserved = 0;
> +       class_locale.members.locale = MR_EVT_LOCALE_ALL;
> +       class_locale.members.class = MR_EVT_CLASS_DEBUG;
> +
> +       if ( instance->aen_cmd != NULL ) {
> +               return ;
> +       }
> +
> +       mutex_lock(&instance->aen_mutex);
> +       error = megasas_register_aen(instance, seq_num,
> +                               class_locale.word);
> +       mutex_unlock(&instance->aen_mutex);
> +
> +       if (error)
> +               printk(KERN_ERR "%s[%d]: register aen failed error %x\n",
> +                        __FUNCTION__, instance->host->host_no, error);
> +}
> +
> +
>
> ...
>
> @@ -1118,8 +1134,10 @@ struct megasas_instance {
> 
>         struct megasas_instance_template *instancet;
>         struct tasklet_struct isr_tasklet;
> +       struct work_struct *hotplug_wk;

"hotplug_work"

> 
>         u8 flag;
> +       u8 unload;
>         unsigned long last_time;
> 
>         struct timer_list io_completion_timer;

^ permalink raw reply	[flat|nested] 40+ messages in thread

* RE: [PATCH 5/10] scsi: megaraid_sas - Fixed load/unload issue and Fire the system pd DCDB cmd to MegaRAID SAS FW to get the system PDs
  2009-05-06 21:20                         ` [PATCH 5/10] scsi: megaraid_sas - Fixed load/unload issue and Fire the system pd DCDB cmd to MegaRAID SAS FW to get the system PDs Andrew Morton
@ 2009-05-07 15:05                           ` Yang, Bo
  0 siblings, 0 replies; 40+ messages in thread
From: Yang, Bo @ 2009-05-07 15:05 UTC (permalink / raw)
  To: Andrew Morton; +Cc: James.Bottomley, linux-scsi, linux-kernel, Austria, Winston

Andrew,

Will add one patch to change all the defination.

Thanks,

Bo Yang

-----Original Message-----
From: Andrew Morton [mailto:akpm@linux-foundation.org] 
Sent: Wednesday, May 06, 2009 5:21 PM
To: Yang, Bo
Cc: Yang, Bo; James.Bottomley@HansenPartnership.com; linux-scsi@vger.kernel.org; linux-kernel@vger.kernel.org; Austria, Winston
Subject: Re: [PATCH 5/10] scsi: megaraid_sas - Fixed load/unload issue and Fire the system pd DCDB cmd to MegaRAID SAS FW to get the system PDs

On Tue, 5 May 2009 19:24:07 -0600
"Yang, Bo" <Bo.Yang@lsi.com> wrote:

> +} __attribute__ ((packed));

Please use __packed.  I'd suggest this be done as a single driver-wide cleanup
patch at a convenient time.

^ permalink raw reply	[flat|nested] 40+ messages in thread

end of thread, other threads:[~2009-05-07 15:06 UTC | newest]

Thread overview: 40+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-11-07 17:09 [PATCH 1/6] scsi: megaraid_sas - add hibernation support bo yang
2007-11-16 21:31 ` Yang, Bo
2007-11-16 22:18   ` James Bottomley
     [not found]     ` <9738BCBE884FDB42801FAD8A7769C26501C9A4AF@NAMAIL1.ad.lsil.com>
2008-03-18  7:13       ` [PATCH 1/4] scsi: megaraid_sas - Rollback the sense info implementation bo yang
2008-03-17  7:36         ` [PATCH 2/4] scsi: megaraid_sas - Fix the frame count calculation bo yang
2008-03-17  8:13         ` [PATCH 3/4] scsi: megaraid_sas - Add the new controller Support to Driver bo yang
2008-08-01 16:48           ` [PATCH 2/4] scsi: megaraid_sas - Add the shutdown DCMD cmd to driver shutdown routine Yang, Bo
2008-08-01 21:17             ` [PATCH 3/4] scsi: megaraid_sas - Add the new controllers support Yang, Bo
2008-08-01 21:25               ` [PATCH 4/4] scsi: megaraid_sas - Version and Documentation Update Yang, Bo
2008-03-17  8:18         ` [PATCH 4/4] scsi: megaraid_sas - Update the Version and Changelog bo yang
2008-03-17 20:54           ` James Bottomley
2008-03-17 21:00             ` [PATCH 4/4] scsi: megaraid_sas - Update the Version andChangelog Yang, Bo
2009-02-17 14:44             ` [PATCH 1/9] scsi: megaraid_sas - Fix the tape drive support Yang, Bo
2009-02-17 15:25               ` [PATCH 2/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - I Yang, Bo
2009-02-17 15:36                 ` [PATCH 3/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - II Yang, Bo
2009-02-17 15:51                   ` [PATCH 4/9] scsi: megaraid_sas - Add new controller 0x73(new SAS2) support to the driver Yang, Bo
2009-02-17 16:37                     ` [PATCH 5/9] scsi: megaraid_sas - Add memory support required by 0x73 controller Yang, Bo
2009-02-17 17:09                       ` [PATCH 6/9] scsi: megaraid_sas - Report the unconfigured PD (system PD) to OS Yang, Bo
2009-02-17 17:21                         ` [PATCH 7/9] scsi: megaraid_sas - Resign the Application cmds to 0x73 (new SAS2) controller Yang, Bo
2009-02-17 17:31                           ` [PATCH 8/9] scsi: megaraid_sas - Add the IEEE SGL support to the driver Yang, Bo
2009-02-17 17:50                             ` [PATCH 9/9] scsi: megaraid_sas - Update the Version and ChangeLog Yang, Bo
2009-02-19  0:38                             ` [PATCH 8/9] scsi: megaraid_sas - Add the IEEE SGL support to the driver Andrew Morton
2009-02-19  0:30                       ` [PATCH 5/9] scsi: megaraid_sas - Add memory support required by 0x73 controller Andrew Morton
2009-02-19  0:21                 ` [PATCH 2/9] scsi: megaraid_sas - Add poll wait support to megaraid sas driver - I Andrew Morton
2009-02-19 13:55                   ` Yang, Bo
2009-05-05 23:55               ` [PATCH 1/10] scsi: megaraid_sas - tape drive support fix Yang, Bo
2009-05-06  0:25                 ` [PATCH 2/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-I) Yang, Bo
2009-05-06  0:41                   ` [PATCH 3/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-II) Yang, Bo
2009-05-06  1:11                     ` [PATCH 4/10] scsi: megaraid_sas - Add New SAS 2 (iMR) controller support to the driver Yang, Bo
2009-05-06  1:24                       ` [PATCH 5/10] scsi: megaraid_sas - Fixed load/unload issue and Fire the system pd DCDB cmd to MegaRAID SAS FW to get the system PDs Yang, Bo
2009-05-06  1:35                         ` [PATCH 6/10] scsi: megaraid_sas - Report the Unconfigured PD (system PD) to OS Yang, Bo
2009-05-06  1:43                           ` [PATCH 7/10] scsi: megaraid_sas - Re-assign the Cmds to Application for the iMR controller Yang, Bo
2009-05-06  1:52                             ` [PATCH 8/10] scsi: megaraid_sas - Driver adds the IEEE SGE format to support SAS 2 controller Yang, Bo
2009-05-06  2:08                               ` [PATCH 9/10] scsi: megaraid_sas - Fixed the logic drives deleted and cmds pending in FW issue Yang, Bo
2009-05-06  2:12                                 ` [PATCH 10/10] scsi: megaraid_sas - Version and Documentation update Yang, Bo
2009-05-06 21:20                         ` [PATCH 5/10] scsi: megaraid_sas - Fixed load/unload issue and Fire the system pd DCDB cmd to MegaRAID SAS FW to get the system PDs Andrew Morton
2009-05-07 15:05                           ` Yang, Bo
2009-05-06 21:19                     ` [PATCH 3/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-II) Andrew Morton
2009-05-06 21:17                   ` [PATCH 2/10] scsi: megaraid_sas - Add Poll Wait mechanism to MegaRAID SAS driver (PART-I) Andrew Morton
2009-05-07 14:56                     ` Yang, Bo

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).