Re: [RFC] Megaraid update, submission

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Jeff,

Corrected patch, thanks for seeing I missed a paste when removing all the
ifdefs for testing variations.

Cheers,

Andre Hedrick
LAD Storage Consulting Group

On Tue, 16 May 2006, Jeff Garzik wrote:

> Andre Hedrick wrote:
> > +static int megaraid_pci_master_abort(struct pci_dev* dev)
> > +{
> > +	u16 status, error_bits;
> > +
> > +	pci_read_config_word(dev, PCI_STATUS, &status);
> > +	if (error_bits)
> > +		pci_write_config_word(dev, PCI_STATUS, error_bits);
> > +	pci_read_config_word(dev, PCI_STATUS, &status);
> 
> error_bits is used before a value is assigned to it.  Presumably you are 
> missing a duplicate of a line further down in the function,
> 
> 	error_bits = (status & PCI_STATUS_REC_MASTER_ABORT);
> 
> The list stuff looks OK, to my quick glance.
> 
> 	Jeff
> 
> 
> -
> : send the line "unsubscribe linux-scsi" in
> the body of a message to majordomo@xxxxxxxxxxxxxxx
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> 
diff -ur linux-2.6.17-rc4/drivers/scsi/megaraid/megaraid_mbox.c linux-2.6.17-rc4.new/drivers/scsi/megaraid/megaraid_mbox.c
--- linux-2.6.17-rc4/drivers/scsi/megaraid/megaraid_mbox.c	2006-05-11 16:31:53.000000000 -0700
+++ linux-2.6.17-rc4.new/drivers/scsi/megaraid/megaraid_mbox.c	2006-05-16 11:18:56.263708705 -0700
@@ -94,6 +94,8 @@
 static int megaraid_sysfs_alloc_resources(adapter_t *);
 static void megaraid_sysfs_free_resources(adapter_t *);
 
+static int megaraid_pci_master_abort(struct pci_dev *);
+
 static int megaraid_abort_handler(struct scsi_cmnd *);
 static int megaraid_reset_handler(struct scsi_cmnd *);
 
@@ -1276,7 +1278,7 @@
 	// detach scb from free pool
 	spin_lock_irqsave(SCSI_FREE_LIST_LOCK(adapter), flags);
 
-	if (list_empty(head)) {
+	if (list_empty_careful(head)) {
 		spin_unlock_irqrestore(SCSI_FREE_LIST_LOCK(adapter), flags);
 		return NULL;
 	}
@@ -1314,7 +1316,7 @@
 	scb->scp	= NULL;
 	spin_lock_irqsave(SCSI_FREE_LIST_LOCK(adapter), flags);
 
-	list_add(&scb->list, &adapter->kscb_pool);
+	list_move(&scb->list, &adapter->kscb_pool);
 
 	spin_unlock_irqrestore(SCSI_FREE_LIST_LOCK(adapter), flags);
 
@@ -1911,7 +1913,7 @@
 
 	if (scb_q) {
 		scb_q->state = SCB_PENDQ;
-		list_add_tail(&scb_q->list, &adapter->pend_list);
+		list_move_tail(&scb_q->list, &adapter->pend_list);
 	}
 
 	// if the adapter in not in quiescent mode, post the commands to FW
@@ -1920,7 +1922,7 @@
 		return;
 	}
 
-	while (!list_empty(&adapter->pend_list)) {
+	while (!list_empty_careful(&adapter->pend_list)) {
 
 		assert_spin_locked(PENDING_LIST_LOCK(adapter));
 
@@ -1946,7 +1948,7 @@
 
 			scb->state = SCB_PENDQ;
 
-			list_add(&scb->list, &adapter->pend_list);
+			list_move(&scb->list, &adapter->pend_list);
 
 			spin_unlock_irqrestore(PENDING_LIST_LOCK(adapter),
 				flags);
@@ -2148,7 +2150,7 @@
 			}
 
 			scb->status = mbox->status;
-			list_add_tail(&scb->list, &clist);
+			list_move_tail(&scb->list, &clist);
 		}
 
 		// Acknowledge interrupt
@@ -2477,6 +2479,28 @@
 
 
 /**
+ * megaraid_pci_master_abort
+ * @dev                : pci device structure
+ *
+ * Tests for PCI Master Abort on the host adapter and clears state
+ * Returns state of error with inverted logic test to give proper
+ * state of the pci statuts bit describing master_abort.
+ */
+static int megaraid_pci_master_abort(struct pci_dev* dev)
+{
+	u16 status, error_bits;
+
+	pci_read_config_word(dev, PCI_STATUS, &status);
+	error_bits = (status & PCI_STATUS_REC_MASTER_ABORT);
+	if (error_bits)
+		pci_write_config_word(dev, PCI_STATUS, error_bits);
+	pci_read_config_word(dev, PCI_STATUS, &status);
+	error_bits = (status & PCI_STATUS_REC_MASTER_ABORT);
+	return (!error_bits) ? 0 : 1;
+}
+
+
+/**
  * megaraid_abort_handler - abort the scsi command
  * @scp		: command to be aborted
  *
@@ -2505,9 +2529,13 @@
 
 	// If FW has stopped responding, simply return failure
 	if (raid_dev->hw_error) {
-		con_log(CL_ANN, (KERN_NOTICE
-			"megaraid: hw error, not aborting\n"));
-		return FAILED;
+		// test if adapter is locked up because of pci master abort
+		if (megaraid_pci_master_abort(adapter->pdev)) {
+			con_log(CL_ANN, (KERN_NOTICE
+				"megaraid: hw error, cannot reset\n"));
+			return FAILED;
+		}
+		raid_dev->hw_error = 0;
 	}
 
 	// There might a race here, where the command was completed by the
@@ -2519,14 +2547,13 @@
 	list_for_each_entry_safe(scb, tmp, &adapter->completed_list, list) {
 
 		if (scb->scp == scp) {	// Found command
-
-			list_del_init(&scb->list);	// from completed list
-
 			con_log(CL_ANN, (KERN_WARNING
 			"megaraid: %ld:%d[%d:%d], abort from completed list\n",
 				scp->serial_number, scb->sno,
 				scb->dev_channel, scb->dev_target));
 
+			list_del_init(&scb->list);	// from completed list
+
 			scp->result = (DID_ABORT << 16);
 			scp->scsi_done(scp);
 
@@ -2549,8 +2576,6 @@
 
 		if (scb->scp == scp) {	// Found command
 
-			list_del_init(&scb->list);	// from pending list
-
 			ASSERT(!(scb->state & SCB_ISSUED));
 
 			con_log(CL_ANN, (KERN_WARNING
@@ -2558,6 +2583,8 @@
 				scp->serial_number, scb->dev_channel,
 				scb->dev_target));
 
+			list_del_init(&scb->list);	// from pending list
+
 			scp->result = (DID_ABORT << 16);
 			scp->scsi_done(scp);
 
@@ -3606,7 +3633,7 @@
 	// detach one scb from free pool
 	spin_lock_irqsave(USER_FREE_LIST_LOCK(adapter), flags);
 
-	if (list_empty(head)) {	// should never happen because of CMM
+	if (list_empty_careful(head)) {	// should never happen because of CMM
 
 		con_log(CL_ANN, (KERN_WARNING
 			"megaraid mbox: bug in cmm handler, lost resources\n"));
@@ -3737,7 +3764,7 @@
 
 	spin_lock_irqsave(USER_FREE_LIST_LOCK(adapter), flags);
 
-	list_add(&scb->list, &adapter->uscb_pool);
+	list_move(&scb->list, &adapter->uscb_pool);
 
 	spin_unlock_irqrestore(USER_FREE_LIST_LOCK(adapter), flags);
 
diff -ur linux-2.6.17-rc4/drivers/scsi/megaraid/megaraid_mm.c linux-2.6.17-rc4.new/drivers/scsi/megaraid/megaraid_mm.c
--- linux-2.6.17-rc4/drivers/scsi/megaraid/megaraid_mm.c	2006-05-11 16:31:53.000000000 -0700
+++ linux-2.6.17-rc4.new/drivers/scsi/megaraid/megaraid_mm.c	2006-05-16 10:16:19.461954269 -0700
@@ -577,7 +577,7 @@
 
 	head = &adp->kioc_pool;
 
-	if (list_empty(head)) {
+	if (list_empty_careful(head)) {
 		up(&adp->kioc_semaphore);
 		spin_unlock_irqrestore(&adp->kioc_pool_lock, flags);
 
@@ -641,7 +641,7 @@
 
 	/* Return the kioc to the free pool */
 	spin_lock_irqsave(&adp->kioc_pool_lock, flags);
-	list_add(&kioc->list, &adp->kioc_pool);
+	list_move(&kioc->list, &adp->kioc_pool);
 	spin_unlock_irqrestore(&adp->kioc_pool_lock, flags);
 
 	/* increment the free kioc count */
diff -ur linux-2.6.17-rc4/drivers/scsi/megaraid/megaraid_sas.c linux-2.6.17-rc4.new/drivers/scsi/megaraid/megaraid_sas.c
--- linux-2.6.17-rc4/drivers/scsi/megaraid/megaraid_sas.c	2006-05-11 16:31:53.000000000 -0700
+++ linux-2.6.17-rc4.new/drivers/scsi/megaraid/megaraid_sas.c	2006-05-16 10:25:54.562822089 -0700
@@ -95,7 +95,7 @@
 
 	spin_lock_irqsave(&instance->cmd_pool_lock, flags);
 
-	if (!list_empty(&instance->cmd_pool)) {
+	if (!list_empty_careful(&instance->cmd_pool)) {
 		cmd = list_entry((&instance->cmd_pool)->next,
 				 struct megasas_cmd, list);
 		list_del_init(&cmd->list);
@@ -120,7 +120,7 @@
 	spin_lock_irqsave(&instance->cmd_pool_lock, flags);
 
 	cmd->scmd = NULL;
-	list_add_tail(&cmd->list, &instance->cmd_pool);
+	list_move_tail(&cmd->list, &instance->cmd_pool);
 
 	spin_unlock_irqrestore(&instance->cmd_pool_lock, flags);
 }

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Index of Archives]     [SCSI Target Devel]     [Linux SCSI Target Infrastructure]     [Kernel Newbies]     [IDE]     [Security]     [Git]     [Netfilter]     [Bugtraq]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Linux ATA RAID]     [Linux IIO]     [Samba]     [Device Mapper]
  Powered by Linux