[kernel] r16603 - in dists/sid/linux-2.6/debian: . patches/features/all patches/series

Ben Hutchings benh at alioth.debian.org
Sat Nov 27 21:42:49 UTC 2010


Author: benh
Date: Sat Nov 27 21:42:32 2010
New Revision: 16603

Log:
megaraid_sas: Add support for 'entry-level' SAS controllers including the 9240 family (Closes: #604083)

Added:
   dists/sid/linux-2.6/debian/patches/features/all/SCSI-megaraid_sas-Add-new-megaraid-SAS-2-controller.patch
   dists/sid/linux-2.6/debian/patches/features/all/SCSI-megaraid_sas-Add-poll-mechanism-to-megaraid-sas.patch
   dists/sid/linux-2.6/debian/patches/features/all/SCSI-megaraid_sas-Fix-fw-hang-caused-by-megaraid-sas-app.patch
   dists/sid/linux-2.6/debian/patches/features/all/SCSI-megaraid_sas-add-sysfs-for-AEN-polling.patch
   dists/sid/linux-2.6/debian/patches/features/all/SCSI-megaraid_sas-allocate-cmds-to-sas2-controller.patch
   dists/sid/linux-2.6/debian/patches/series/29
Modified:
   dists/sid/linux-2.6/debian/changelog

Modified: dists/sid/linux-2.6/debian/changelog
==============================================================================
--- dists/sid/linux-2.6/debian/changelog	Thu Nov 25 16:37:27 2010	(r16602)
+++ dists/sid/linux-2.6/debian/changelog	Sat Nov 27 21:42:32 2010	(r16603)
@@ -1,3 +1,11 @@
+linux-2.6 (2.6.32-29) UNRELEASED; urgency=low
+
+  [ Ben Hutchings ]
+  * megaraid_sas: Add support for 'entry-level' SAS controllers including
+    the 9240 family (Closes: #604083)
+
+ -- Ben Hutchings <ben at decadent.org.uk>  Sat, 27 Nov 2010 21:06:54 +0000
+
 linux-2.6 (2.6.32-28) unstable; urgency=high
 
   [ maximilian attems ]

Added: dists/sid/linux-2.6/debian/patches/features/all/SCSI-megaraid_sas-Add-new-megaraid-SAS-2-controller.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/SCSI-megaraid_sas-Add-new-megaraid-SAS-2-controller.patch	Sat Nov 27 21:42:32 2010	(r16603)
@@ -0,0 +1,233 @@
+From: Yang, Bo <Bo.Yang at lsi.com>
+Date: Tue, 6 Oct 2009 14:31:54 -0600
+Subject: [PATCH 3/5] [SCSI] megaraid_sas: Add new megaraid SAS 2 controller support to the driver
+
+commit 879111224d0784eab623fe8130a1f4481e0e1966 upstream.
+
+Add the new megaraid sas 2 controller to the driver.  megaraid sas2 is
+LSI next generation SAS products.  driver add the interface to support
+this product.
+
+Signed-off-by Bo Yang<bo.yang at lsi.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/megaraid/megaraid_sas.c |  139 ++++++++++++++++++++++++++++++++-
+ drivers/scsi/megaraid/megaraid_sas.h |    4 +
+ 2 files changed, 138 insertions(+), 5 deletions(-)
+
+diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
+index 0121413..b6e4327 100644
+--- a/drivers/scsi/megaraid/megaraid_sas.c
++++ b/drivers/scsi/megaraid/megaraid_sas.c
+@@ -76,6 +76,10 @@ static struct pci_device_id megasas_pci_table[] = {
+ 	/* 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)},
+@@ -335,6 +339,99 @@ static struct megasas_instance_template megasas_instance_template_ppc = {
+ };
+ 
+ /**
++ * 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);
++}
++
++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
+ */
+@@ -1587,16 +1684,34 @@ megasas_transition_to_ready(struct megasas_instance* instance)
+ 			/*
+ 			 * 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;
+@@ -1607,7 +1722,15 @@ megasas_transition_to_ready(struct megasas_instance* instance)
+ 			 * 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;
+@@ -2112,6 +2235,8 @@ static int megasas_init_mfi(struct megasas_instance *instance)
+ 	 * 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 {
+@@ -2142,6 +2267,10 @@ static int megasas_init_mfi(struct megasas_instance *instance)
+ 		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 --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
+index 900359f..365a961 100644
+--- a/drivers/scsi/megaraid/megaraid_sas.h
++++ b/drivers/scsi/megaraid/megaraid_sas.h
+@@ -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
+ 
+ /*
+  * =====================================
+@@ -584,6 +586,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
+-- 
+1.7.2.3
+

Added: dists/sid/linux-2.6/debian/patches/features/all/SCSI-megaraid_sas-Add-poll-mechanism-to-megaraid-sas.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/SCSI-megaraid_sas-Add-poll-mechanism-to-megaraid-sas.patch	Sat Nov 27 21:42:32 2010	(r16603)
@@ -0,0 +1,170 @@
+From: Yang, Bo <Bo.Yang at lsi.com>
+Date: Tue, 6 Oct 2009 14:18:02 -0600
+Subject: [PATCH 1/5] [SCSI] megaraid_sas: Add poll mechanism to megaraid sas driver
+
+commit c35188377f12e5e0a74f18c3dfdd67baf88db514 upstream.
+
+Add Poll_wait mechanism to SAS-2 MegaRAID SAS Linux driver. Driver
+will wakeup poll after the driver get event from MegaRAID SAS FW.
+
+Signed-off-by Bo Yang<bo.yang at lsi.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/megaraid/megaraid_sas.c |   45 +++++++++++++++++++++++++++++++++-
+ drivers/scsi/megaraid/megaraid_sas.h |    1 +
+ 2 files changed, 45 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
+index 6fd1e17..0d44fec 100644
+--- a/drivers/scsi/megaraid/megaraid_sas.c
++++ b/drivers/scsi/megaraid/megaraid_sas.c
+@@ -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,8 +90,14 @@ static struct megasas_mgmt_info megasas_mgmt_info;
+ 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;
+ 
++/* define lock for aen poll */
++spinlock_t poll_aen_lock;
++
+ static void
+ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
+ 		     u8 alt_status);
+@@ -1292,11 +1299,17 @@ megasas_bios_param(struct scsi_device *sdev, struct block_device *bdev,
+ static void
+ megasas_service_aen(struct megasas_instance *instance, struct megasas_cmd *cmd)
+ {
++	unsigned long flags;
+ 	/*
+ 	 * Don't signal app if it is just an aborted previously registered aen
+ 	 */
+-	if (!cmd->abort_aen)
++	if ((!cmd->abort_aen) && (instance->unload == 0)) {
++		spin_lock_irqsave(&poll_aen_lock, flags);
++		megasas_poll_wait_aen = 1;
++		spin_unlock_irqrestore(&poll_aen_lock, flags);
++		wake_up(&megasas_poll_wait);
+ 		kill_fasync(&megasas_async_queue, SIGIO, POLL_IN);
++	}
+ 	else
+ 		cmd->abort_aen = 0;
+ 
+@@ -1381,6 +1394,7 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
+ {
+ 	int exception = 0;
+ 	struct megasas_header *hdr = &cmd->frame->hdr;
++	unsigned long flags;
+ 
+ 	if (cmd->scmd)
+ 		cmd->scmd->SCp.ptr = NULL;
+@@ -1470,6 +1484,12 @@ megasas_complete_cmd(struct megasas_instance *instance, struct megasas_cmd *cmd,
+ 	case MFI_CMD_SMP:
+ 	case MFI_CMD_STP:
+ 	case MFI_CMD_DCMD:
++		if (cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET_INFO ||
++			cmd->frame->dcmd.opcode == MR_DCMD_CTRL_EVENT_GET) {
++			spin_lock_irqsave(&poll_aen_lock, flags);
++			megasas_poll_wait_aen = 0;
++			spin_unlock_irqrestore(&poll_aen_lock, flags);
++		}
+ 
+ 		/*
+ 		 * See if got an event notification
+@@ -2583,6 +2603,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+ 
+ 	*instance->producer = 0;
+ 	*instance->consumer = 0;
++	megasas_poll_wait_aen = 0;
+ 
+ 	instance->evt_detail = pci_alloc_consistent(pdev,
+ 						    sizeof(struct
+@@ -2607,6 +2628,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+ 
+ 	spin_lock_init(&instance->cmd_pool_lock);
+ 	spin_lock_init(&instance->completion_lock);
++	spin_lock_init(&poll_aen_lock);
+ 
+ 	mutex_init(&instance->aen_mutex);
+ 	sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
+@@ -2621,6 +2643,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+ 
+ 	megasas_dbg_lvl = 0;
+ 	instance->flag = 0;
++	instance->unload = 0;
+ 	instance->last_time = 0;
+ 
+ 	/*
+@@ -2924,6 +2947,7 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev)
+ 	struct megasas_instance *instance;
+ 
+ 	instance = pci_get_drvdata(pdev);
++	instance->unload = 1;
+ 	host = instance->host;
+ 
+ 	if (poll_mode_io)
+@@ -3027,6 +3051,23 @@ static int megasas_mgmt_fasync(int fd, struct file *filep, int mode)
+ }
+ 
+ /**
++ * megasas_mgmt_poll -  char node "poll" entry point
++ * */
++static unsigned int megasas_mgmt_poll(struct file *file, poll_table *wait)
++{
++	unsigned int mask;
++	unsigned long flags;
++	poll_wait(file, &megasas_poll_wait, wait);
++	spin_lock_irqsave(&poll_aen_lock, flags);
++	if (megasas_poll_wait_aen)
++		mask =   (POLLIN | POLLRDNORM);
++	else
++		mask = 0;
++	spin_unlock_irqrestore(&poll_aen_lock, flags);
++	return mask;
++}
++
++/**
+  * megasas_mgmt_fw_ioctl -	Issues management ioctls to FW
+  * @instance:			Adapter soft state
+  * @argp:			User's ioctl packet
+@@ -3067,6 +3108,7 @@ megasas_mgmt_fw_ioctl(struct megasas_instance *instance,
+ 	 */
+ 	memcpy(cmd->frame, ioc->frame.raw, 2 * MEGAMFI_FRAME_SIZE);
+ 	cmd->frame->hdr.context = cmd->index;
++	cmd->frame->hdr.pad_0 = 0;
+ 
+ 	/*
+ 	 * The management interface between applications and the fw uses
+@@ -3348,6 +3390,7 @@ static const struct file_operations megasas_mgmt_fops = {
+ 	.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
+diff --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
+index 0d03324..900359f 100644
+--- a/drivers/scsi/megaraid/megaraid_sas.h
++++ b/drivers/scsi/megaraid/megaraid_sas.h
+@@ -1120,6 +1120,7 @@ struct megasas_instance {
+ 	struct tasklet_struct isr_tasklet;
+ 
+ 	u8 flag;
++	u8 unload;
+ 	unsigned long last_time;
+ 
+ 	struct timer_list io_completion_timer;
+-- 
+1.7.2.3
+

Added: dists/sid/linux-2.6/debian/patches/features/all/SCSI-megaraid_sas-Fix-fw-hang-caused-by-megaraid-sas-app.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/SCSI-megaraid_sas-Fix-fw-hang-caused-by-megaraid-sas-app.patch	Sat Nov 27 21:42:32 2010	(r16603)
@@ -0,0 +1,290 @@
+From: Yang, Bo <Bo.Yang at lsi.com>
+Date: Tue, 6 Oct 2009 14:47:35 -0600
+Subject: [PATCH 5/5] [SCSI] megaraid_sas: Fix the fix for fw hang caused by megaraid sas application
+
+commit 0c79e681eef10810a5ed41a2eb1dce244ab1c37d upstream.
+
+Add a lock to the skinny firmware initialisation sequence to prevent
+the two stage write being non atomic if multiple instances use it.
+
+Add a flag to the driver shutdown sequence to prevent aen ioctls being
+called after shutdown begins.
+
+Signed-off-by Bo Yang<bo.yang at lsi.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/megaraid/megaraid_sas.c |   75 ++++++++++++++++++++++++++++-----
+ drivers/scsi/megaraid/megaraid_sas.h |   25 ++++++-----
+ 2 files changed, 77 insertions(+), 23 deletions(-)
+
+diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
+index 4c04a68..6d998e0 100644
+--- a/drivers/scsi/megaraid/megaraid_sas.c
++++ b/drivers/scsi/megaraid/megaraid_sas.c
+@@ -226,7 +226,10 @@ megasas_clear_intr_xscale(struct megasas_register_set __iomem * regs)
+  * @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);
+@@ -323,7 +326,10 @@ megasas_clear_intr_ppc(struct megasas_register_set __iomem * regs)
+  * @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);
+@@ -413,12 +419,17 @@ megasas_clear_intr_skinny(struct megasas_register_set __iomem *regs)
+  * @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);
+ }
+ 
+ static struct megasas_instance_template megasas_instance_template_skinny = {
+@@ -508,7 +519,9 @@ megasas_clear_intr_gen2(struct megasas_register_set __iomem *regs)
+  * @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,
+@@ -550,7 +563,8 @@ megasas_issue_polled(struct megasas_instance *instance, struct megasas_cmd *cmd)
+ 	/*
+ 	 * 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
+@@ -581,7 +595,8 @@ megasas_issue_blocked_cmd(struct megasas_instance *instance,
+ {
+ 	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);
+@@ -626,7 +641,8 @@ megasas_issue_blocked_abort_cmd(struct megasas_instance *instance,
+ 	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
+@@ -1153,7 +1169,8 @@ megasas_queue_command(struct scsi_cmnd *scmd, void (*done) (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
+ 	 */
+@@ -1346,8 +1363,16 @@ static int megasas_wait_for_outstanding(struct megasas_instance *instance)
+ 		* 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;
+@@ -1799,7 +1824,7 @@ megasas_transition_to_ready(struct megasas_instance* instance)
+ 			/*
+ 			 * 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)) {
+@@ -2799,7 +2824,8 @@ megasas_register_aen(struct megasas_instance *instance, u32 seq_num,
+ 	/*
+ 	 * 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;
+ }
+@@ -2983,6 +3009,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+ 	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);
+ 	spin_lock_init(&poll_aen_lock);
+ 
+@@ -3005,7 +3032,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+ 
+ 	megasas_dbg_lvl = 0;
+ 	instance->flag = 0;
+-	instance->unload = 0;
++	instance->unload = 1;
+ 	instance->last_time = 0;
+ 
+ 	/*
+@@ -3051,6 +3078,7 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+ 	if (megasas_io_attach(instance))
+ 		goto fail_io_attach;
+ 
++	instance->unload = 0;
+ 	return 0;
+ 
+       fail_start_aen:
+@@ -3174,6 +3202,7 @@ megasas_suspend(struct pci_dev *pdev, pm_message_t state)
+ 
+ 	instance = pci_get_drvdata(pdev);
+ 	host = instance->host;
++	instance->unload = 1;
+ 
+ 	if (poll_mode_io)
+ 		del_timer_sync(&instance->io_completion_timer);
+@@ -3269,6 +3298,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:
+@@ -3366,6 +3397,7 @@ static void __devexit megasas_detach_one(struct pci_dev *pdev)
+ static void megasas_shutdown(struct pci_dev *pdev)
+ {
+ 	struct megasas_instance *instance = pci_get_drvdata(pdev);
++	instance->unload = 1;
+ 	megasas_flush_cache(instance);
+ 	megasas_shutdown_controller(instance, MR_DCMD_CTRL_SHUTDOWN);
+ }
+@@ -3615,6 +3647,17 @@ static int megasas_mgmt_ioctl_fw(struct file *file, unsigned long arg)
+ 		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
+ 	 */
+@@ -3650,6 +3693,14 @@ static int megasas_mgmt_ioctl_aen(struct file *file, unsigned long arg)
+ 	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 --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
+index a1fd44b..13ac37e 100644
+--- a/drivers/scsi/megaraid/megaraid_sas.h
++++ b/drivers/scsi/megaraid/megaraid_sas.h
+@@ -1157,17 +1157,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_instance {
+ 
+ 	u32 *producer;
+@@ -1193,6 +1182,8 @@ struct megasas_instance {
+ 	spinlock_t cmd_pool_lock;
+ 	/* used to synch producer, consumer ptrs in dpc */
+ 	spinlock_t completion_lock;
++	/* used to sync fire the cmd to fw */
++	spinlock_t fire_lock;
+ 	struct dma_pool *frame_dma_pool;
+ 	struct dma_pool *sense_dma_pool;
+ 
+@@ -1224,6 +1215,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
+ 
+-- 
+1.7.2.3
+

Added: dists/sid/linux-2.6/debian/patches/features/all/SCSI-megaraid_sas-add-sysfs-for-AEN-polling.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/SCSI-megaraid_sas-add-sysfs-for-AEN-polling.patch	Sat Nov 27 21:42:32 2010	(r16603)
@@ -0,0 +1,81 @@
+From: Yang, Bo <Bo.Yang at lsi.com>
+Date: Tue, 6 Oct 2009 14:20:59 -0600
+Subject: [PATCH 2/5] [SCSI] megaraid_sas: add sysfs for AEN polling
+
+commit 72c4fd36dc7f755a5245ef2495fe27d5084d776d upstream.
+
+update the sysfs parameter to tell application driver support AEN poll
+
+Signed-off-by Bo Yang<bo.yang at lsi.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/megaraid/megaraid_sas.c |   24 +++++++++++++++++++++++-
+ 1 files changed, 23 insertions(+), 1 deletions(-)
+
+diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
+index 0d44fec..0121413 100644
+--- a/drivers/scsi/megaraid/megaraid_sas.c
++++ b/drivers/scsi/megaraid/megaraid_sas.c
+@@ -92,7 +92,7 @@ static DEFINE_MUTEX(megasas_async_queue_mutex);
+ 
+ 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;
+ 
+ /* define lock for aen poll */
+@@ -3432,6 +3432,15 @@ static DRIVER_ATTR(release_date, S_IRUGO, megasas_sysfs_show_release_date,
+ 		   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);
+@@ -3522,6 +3531,8 @@ static int __init megasas_init(void)
+ 	printk(KERN_INFO "megasas: %s %s\n", MEGASAS_VERSION,
+ 	       MEGASAS_EXT_VERSION);
+ 
++	support_poll_for_event = 2;
++
+ 	memset(&megasas_mgmt_info, 0, sizeof(megasas_mgmt_info));
+ 
+ 	/*
+@@ -3554,6 +3565,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)
+@@ -3570,7 +3587,12 @@ err_dcf_poll_mode_io:
+ 			   &driver_attr_dbg_lvl);
+ err_dcf_dbg_lvl:
+ 	driver_remove_file(&megasas_pci_driver.driver,
++			&driver_attr_support_poll_for_event);
++
++err_dcf_support_poll_for_event:
++	driver_remove_file(&megasas_pci_driver.driver,
+ 			   &driver_attr_release_date);
++
+ err_dcf_rel_date:
+ 	driver_remove_file(&megasas_pci_driver.driver, &driver_attr_version);
+ err_dcf_attr_ver:
+-- 
+1.7.2.3
+

Added: dists/sid/linux-2.6/debian/patches/features/all/SCSI-megaraid_sas-allocate-cmds-to-sas2-controller.patch
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/features/all/SCSI-megaraid_sas-allocate-cmds-to-sas2-controller.patch	Sat Nov 27 21:42:32 2010	(r16603)
@@ -0,0 +1,87 @@
+From: Yang, Bo <Bo.Yang at lsi.com>
+Date: Tue, 6 Oct 2009 14:40:58 -0600
+Subject: [PATCH 4/5] [SCSI] megaraid_sas: allocate the application cmds to sas2 controller
+
+commit 7bebf5c79cb62766c76c6c1b9c77b86496fd363e upstream.
+
+MegaRAID SAS2 controller ioctl can't use 32 cmd for applications.
+Driver need to divide different number of cmds to IO and application.
+
+Signed-off-by Bo Yang<bo.yang at lsi.com>
+Signed-off-by: James Bottomley <James.Bottomley at suse.de>
+---
+ drivers/scsi/megaraid/megaraid_sas.c |   24 +++++++++++++++++++++---
+ drivers/scsi/megaraid/megaraid_sas.h |    1 +
+ 2 files changed, 22 insertions(+), 3 deletions(-)
+
+diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
+index 9967ee7..5afd651 100644
+--- a/drivers/scsi/megaraid/megaraid_sas.c
++++ b/drivers/scsi/megaraid/megaraid_sas.c
+@@ -1239,7 +1239,14 @@ static void megasas_complete_cmd_dpc(unsigned long instance_addr)
+ 
+ 		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);
+@@ -2774,7 +2781,13 @@ static int megasas_io_attach(struct megasas_instance *instance)
+ 	 */
+ 	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;
+@@ -2909,7 +2922,6 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+ 	spin_lock_init(&poll_aen_lock);
+ 
+ 	mutex_init(&instance->aen_mutex);
+-	sema_init(&instance->ioctl_sem, MEGASAS_INT_CMDS);
+ 
+ 	/*
+ 	 * Initialize PCI related and misc parameters
+@@ -2919,6 +2931,12 @@ megasas_probe_one(struct pci_dev *pdev, const struct pci_device_id *id)
+ 	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 --git a/drivers/scsi/megaraid/megaraid_sas.h b/drivers/scsi/megaraid/megaraid_sas.h
+index 8ac6b26..4c78cd3 100644
+--- a/drivers/scsi/megaraid/megaraid_sas.h
++++ b/drivers/scsi/megaraid/megaraid_sas.h
+@@ -655,6 +655,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
+-- 
+1.7.2.3
+

Added: dists/sid/linux-2.6/debian/patches/series/29
==============================================================================
--- /dev/null	00:00:00 1970	(empty, because file is newly added)
+++ dists/sid/linux-2.6/debian/patches/series/29	Sat Nov 27 21:42:32 2010	(r16603)
@@ -0,0 +1,5 @@
++ features/all/SCSI-megaraid_sas-Add-poll-mechanism-to-megaraid-sas.patch
++ features/all/SCSI-megaraid_sas-add-sysfs-for-AEN-polling.patch
++ features/all/SCSI-megaraid_sas-Add-new-megaraid-SAS-2-controller.patch
++ features/all/SCSI-megaraid_sas-allocate-cmds-to-sas2-controller.patch
++ features/all/SCSI-megaraid_sas-Fix-fw-hang-caused-by-megaraid-sas-app.patch



More information about the Kernel-svn-changes mailing list