All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH] aacraid 2.6: add scsi synchronize cache support.
@ 2005-01-19 22:01 Mark Haverkamp
  2005-01-20 11:31 ` Christoph Hellwig
  0 siblings, 1 reply; 3+ messages in thread
From: Mark Haverkamp @ 2005-01-19 22:01 UTC (permalink / raw)
  To: James Bottomley, linux-scsi; +Cc: Mark Salyzyn

This is an update from the adaptec driver that adds support for the scsi
synchronize cache command.  It essentially blocks further commands until
data has been flushed to the disks.

Signed-off-by: Mark Havekamp <markh@osdl.org>



===== drivers/scsi/aacraid/aachba.c 1.31 vs edited =====
--- 1.31/drivers/scsi/aacraid/aachba.c	2004-10-21 09:53:08 -07:00
+++ edited/drivers/scsi/aacraid/aachba.c	2005-01-06 13:15:17 -08:00
@@ -1029,6 +1029,112 @@
 	return 0;
 }
 
+static void synchronize_callback(void *context, struct fib * fibptr)
+{
+	struct aac_synchronize_reply * synchronizereply;
+	struct scsi_cmnd * scsicmd;
+
+	scsicmd = (struct scsi_cmnd *) context;
+
+	dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies));
+	if (fibptr == NULL)
+		BUG();
+
+
+	synchronizereply = (struct aac_synchronize_reply *) fib_data(fibptr);
+	if (le32_to_cpu(synchronizereply->status) == CT_OK) {
+		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+	} else {
+		struct scsi_device * device = scsicmd->device;
+		struct aac_dev *dev = (struct aac_dev *)device->host->hostdata;
+		u32 cid = ID_LUN_TO_CONTAINER(device->id, device->lun);
+		printk(KERN_WARNING "synchronize_callback: synchronize failed, status = %d\n", synchronizereply->status);
+		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
+		set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
+				    HARDWARE_ERROR,
+				    SENCODE_INTERNAL_TARGET_FAILURE,
+				    ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
+				    0, 0);
+		memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
+		  (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer))
+		    ? sizeof(scsicmd->sense_buffer)
+		    : sizeof(dev->fsa_dev[cid].sense_data));
+	}
+
+	fib_complete(fibptr);
+	fib_free(fibptr);
+	aac_io_done(scsicmd);
+}
+
+static int aac_synchronize(struct scsi_cmnd * scsicmd, int cid)
+{
+	int status;
+	struct fib * cmd_fibcontext;
+	struct aac_synchronize * synchronizecmd;
+
+	/*
+	 * Wait for all commands to complete to this specific
+	 * target (block).
+	 */
+	struct scsi_cmnd * cmd;
+	struct scsi_device * device = scsicmd->device;
+	int active = 0;
+	unsigned long flags;
+	spin_lock_irqsave(&device->list_lock, flags);
+	list_for_each_entry(cmd, &device->cmd_list, list) {
+		if ((cmd != scsicmd) && (cmd->serial_number != 0)) {
+			++active;
+			break;
+		}
+	}
+	spin_unlock_irqrestore(&device->list_lock, flags);
+	if (active) {
+		/*
+		 *	Yield the processor (requeue for later)
+		 */
+		return SCSI_MLQUEUE_DEVICE_BUSY;
+	}
+
+/* XXX */printk(KERN_DEBUG "aac_synchronize[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies);
+/* XXX 	dprintk((KERN_DEBUG "aac_synchronize[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies)); */
+	/*
+	 *	Alocate and initialize a Fib
+	 */
+	if (!(cmd_fibcontext = fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) {
+		return SCSI_MLQUEUE_HOST_BUSY;
+	}
+
+	fib_init(cmd_fibcontext);
+
+	synchronizecmd = (struct aac_synchronize *) fib_data(cmd_fibcontext);
+	synchronizecmd->command = cpu_to_le32(VM_ContainerConfig);
+	synchronizecmd->type = cpu_to_le32(CT_FLUSH_CACHE);
+	synchronizecmd->cid = cpu_to_le32(cid);
+	synchronizecmd->count = cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data));
+
+	/*
+	 *	Now send the Fib to the adapter
+	 */
+	status = fib_send(ContainerCommand,
+		  cmd_fibcontext,
+		  sizeof(struct aac_synchronize),
+		  FsaNormal,
+		  0, 1,
+		  (fib_callback) synchronize_callback,
+		  (void *) scsicmd);
+
+	/*
+	 *	Check that the command queued to the controller
+	 */
+	if (status == -EINPROGRESS) {
+		return 0;
+	}
+
+	printk(KERN_WARNING "aac_synchronize: fib_send failed with status: %d.\n", status);
+	fib_complete(cmd_fibcontext);
+	fib_free(cmd_fibcontext);
+	return SCSI_MLQUEUE_HOST_BUSY;
+}
 
 /**
  *	aac_scsi_cmd()		-	Process SCSI command
@@ -1274,6 +1380,11 @@
 			ret = aac_write(scsicmd, cid);
 			spin_lock_irq(host->host_lock);
 			return ret;
+
+		case SYNCHRONIZE_CACHE:
+			/* Issue FIB to tell Firmware to flush it's cache */
+			return aac_synchronize(scsicmd, cid);
+			
 		default:
 			/*
 			 *	Unhandled commands
===== drivers/scsi/aacraid/aacraid.h 1.28 vs edited =====
--- 1.28/drivers/scsi/aacraid/aacraid.h	2004-12-27 10:28:37 -08:00
+++ edited/drivers/scsi/aacraid/aacraid.h	2005-01-06 08:17:45 -08:00
@@ -1069,6 +1069,30 @@
 	u32		committed;
 };
 
+#define CT_FLUSH_CACHE 129
+struct aac_synchronize {
+	u32		command;	/* VM_ContainerConfig */
+	u32		type;		/* CT_FLUSH_CACHE */
+	u32		cid;
+	u32		parm1;
+	u32		parm2;
+	u32		parm3;
+	u32		parm4;
+	u32		count;	/* sizeof(((struct aac_synchronize_reply *)NULL)->data) */
+};
+
+struct aac_synchronize_reply {
+	u32		dummy0;
+	u32		dummy1;
+	u32		status;	/* CT_OK */
+	u32		parm1;
+	u32		parm2;
+	u32		parm3;
+	u32		parm4;
+	u32		parm5;
+	u8		data[16];
+};
+
 struct aac_srb
 {
 	u32		function;

-- 
Mark Haverkamp <markh@osdl.org>


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

* Re: [PATCH] aacraid 2.6: add scsi synchronize cache support.
  2005-01-19 22:01 [PATCH] aacraid 2.6: add scsi synchronize cache support Mark Haverkamp
@ 2005-01-20 11:31 ` Christoph Hellwig
  2005-01-20 17:03   ` [PATCH] aacraid 2.6: add scsi synchronize cache support. (Update) Mark Haverkamp
  0 siblings, 1 reply; 3+ messages in thread
From: Christoph Hellwig @ 2005-01-20 11:31 UTC (permalink / raw)
  To: Mark Haverkamp; +Cc: James Bottomley, linux-scsi, Mark Salyzyn

> +static void synchronize_callback(void *context, struct fib * fibptr)
> +{
> +	struct aac_synchronize_reply * synchronizereply;
> +	struct scsi_cmnd * scsicmd;

Superflous whitespaces before the *.  Also the canonical name for
scsi_cmnds seems to be cmd - that makes easiert to read code.

> +
> +	scsicmd = (struct scsi_cmnd *) context;

No need to cast.  You could also move the assigment into the declaration.

> +
> +	dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies));

please linewrrap after 80 chars

> +	if (fibptr == NULL)
> +		BUG();

BUG_ON()

> +	synchronizereply = (struct aac_synchronize_reply *) fib_data(fibptr);

fib_data return void *, no cast needed.

> 
> +	if (le32_to_cpu(synchronizereply->status) == CT_OK) {
> +		scsicmd->result = DID_OK << 16 | COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;

linelength again.

> 
> +	} else {
> +		struct scsi_device * device = scsicmd->device;

Canonical name is sdev, superflous space again.

> +		set_sense((u8 *) &dev->fsa_dev[cid].sense_data,

sense_data is u8 already.

> +		memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
> +		  (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer))
> +		    ? sizeof(scsicmd->sense_buffer)
> +		    : sizeof(dev->fsa_dev[cid].sense_data));

Use max here?

> +		if ((cmd != scsicmd) && (cmd->serial_number != 0)) {

superflous braces.

> +/* XXX */printk(KERN_DEBUG "aac_synchronize[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies);
> +/* XXX 	dprintk((KERN_DEBUG "aac_synchronize[cpu %d]: t = %ld.\n", smp_processor_id(), jiffies)); */

take this out?


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

* Re: [PATCH] aacraid 2.6: add scsi synchronize cache support. (Update)
  2005-01-20 11:31 ` Christoph Hellwig
@ 2005-01-20 17:03   ` Mark Haverkamp
  0 siblings, 0 replies; 3+ messages in thread
From: Mark Haverkamp @ 2005-01-20 17:03 UTC (permalink / raw)
  To: Christoph Hellwig, James Bottomley; +Cc: linux-scsi, Mark Salyzyn

Christoph,

On Thu, 2005-01-20 at 11:31 +0000, Christoph Hellwig wrote:

Fixed whitespace, 80 column wrap, casts, braces, parenthesis, etc.

> 
> > +		set_sense((u8 *) &dev->fsa_dev[cid].sense_data,
> 
> sense_data is u8 already.
sense_data is "struct sense_data" and I get a compiler warning without
the cast.

> 
> > +		memcpy(scsicmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
> > +		  (sizeof(dev->fsa_dev[cid].sense_data) > sizeof(scsicmd->sense_buffer))
> > +		    ? sizeof(scsicmd->sense_buffer)
> > +		    : sizeof(dev->fsa_dev[cid].sense_data));
> 
> Use max here?
I think min() is what is needed here.
--

James,
If this addresses Christoph's issues, here is the updated patch.

-----
This is an update from the Adaptec driver that adds support for the scsi
synchronize cache command.  It essentially blocks further commands until
data has been flushed to the disks.

Signed-off-by: Mark Haverkamp <markh@osdl.org>



===== drivers/scsi/aacraid/aachba.c 1.32 vs edited =====
--- 1.32/drivers/scsi/aacraid/aachba.c	2005-01-07 21:44:25 -08:00
+++ edited/drivers/scsi/aacraid/aachba.c	2005-01-20 08:51:37 -08:00
@@ -1029,6 +1029,114 @@
 	return 0;
 }
 
+static void synchronize_callback(void *context, struct fib *fibptr)
+{
+	struct aac_synchronize_reply *synchronizereply;
+	struct scsi_cmnd *cmd;
+
+	cmd = context;
+
+	dprintk((KERN_DEBUG "synchronize_callback[cpu %d]: t = %ld.\n", 
+				smp_processor_id(), jiffies));
+	BUG_ON(fibptr == NULL);
+
+
+	synchronizereply = fib_data(fibptr);
+	if (le32_to_cpu(synchronizereply->status) == CT_OK)
+		cmd->result = DID_OK << 16 | 
+			COMMAND_COMPLETE << 8 | SAM_STAT_GOOD;
+	else {
+		struct scsi_device *sdev = cmd->device;
+		struct aac_dev *dev = (struct aav_dev *)sdev->host->hostdata;
+		u32 cid = ID_LUN_TO_CONTAINER(sdev->id, sdev->lun);
+		printk(KERN_WARNING 
+		     "synchronize_callback: synchronize failed, status = %d\n",
+		     synchronizereply->status);
+		cmd->result = DID_OK << 16 | 
+			COMMAND_COMPLETE << 8 | SAM_STAT_CHECK_CONDITION;
+		set_sense((u8 *)&dev->fsa_dev[cid].sense_data,
+				    HARDWARE_ERROR,
+				    SENCODE_INTERNAL_TARGET_FAILURE,
+				    ASENCODE_INTERNAL_TARGET_FAILURE, 0, 0,
+				    0, 0);
+		memcpy(cmd->sense_buffer, &dev->fsa_dev[cid].sense_data,
+		  min(sizeof(dev->fsa_dev[cid].sense_data), 
+			  sizeof(cmd->sense_buffer)));
+	}
+
+	fib_complete(fibptr);
+	fib_free(fibptr);
+	aac_io_done(cmd);
+}
+
+static int aac_synchronize(struct scsi_cmnd *scsicmd, int cid)
+{
+	int status;
+	struct fib *cmd_fibcontext;
+	struct aac_synchronize *synchronizecmd;
+	struct scsi_cmnd *cmd;
+	struct scsi_device *sdev = scsicmd->device;
+	int active = 0;
+	unsigned long flags;
+
+	/*
+	 * Wait for all commands to complete to this specific
+	 * target (block).
+	 */
+	spin_lock_irqsave(&sdev->list_lock, flags);
+	list_for_each_entry(cmd, &sdev->cmd_list, list)
+		if (cmd != scsicmd && cmd->serial_number != 0) {
+			++active;
+			break;
+		}
+
+	spin_unlock_irqrestore(&sdev->list_lock, flags);
+
+	/*
+	 *	Yield the processor (requeue for later)
+	 */
+	if (active)
+		return SCSI_MLQUEUE_DEVICE_BUSY;
+
+	/*
+	 *	Alocate and initialize a Fib
+	 */
+	if (!(cmd_fibcontext = 
+	    fib_alloc((struct aac_dev *)scsicmd->device->host->hostdata))) 
+		return SCSI_MLQUEUE_HOST_BUSY;
+
+	fib_init(cmd_fibcontext);
+
+	synchronizecmd = fib_data(cmd_fibcontext);
+	synchronizecmd->command = cpu_to_le32(VM_ContainerConfig);
+	synchronizecmd->type = cpu_to_le32(CT_FLUSH_CACHE);
+	synchronizecmd->cid = cpu_to_le32(cid);
+	synchronizecmd->count = 
+	     cpu_to_le32(sizeof(((struct aac_synchronize_reply *)NULL)->data));
+
+	/*
+	 *	Now send the Fib to the adapter
+	 */
+	status = fib_send(ContainerCommand,
+		  cmd_fibcontext,
+		  sizeof(struct aac_synchronize),
+		  FsaNormal,
+		  0, 1,
+		  (fib_callback)synchronize_callback,
+		  (void *)scsicmd);
+
+	/*
+	 *	Check that the command queued to the controller
+	 */
+	if (status == -EINPROGRESS)
+		return 0;
+
+	printk(KERN_WARNING 
+		"aac_synchronize: fib_send failed with status: %d.\n", status);
+	fib_complete(cmd_fibcontext);
+	fib_free(cmd_fibcontext);
+	return SCSI_MLQUEUE_HOST_BUSY;
+}
 
 /**
  *	aac_scsi_cmd()		-	Process SCSI command
@@ -1274,6 +1382,11 @@
 			ret = aac_write(scsicmd, cid);
 			spin_lock_irq(host->host_lock);
 			return ret;
+
+		case SYNCHRONIZE_CACHE:
+			/* Issue FIB to tell Firmware to flush it's cache */
+			return aac_synchronize(scsicmd, cid);
+			
 		default:
 			/*
 			 *	Unhandled commands
===== drivers/scsi/aacraid/aacraid.h 1.28 vs edited =====
--- 1.28/drivers/scsi/aacraid/aacraid.h	2004-12-27 10:28:37 -08:00
+++ edited/drivers/scsi/aacraid/aacraid.h	2005-01-19 10:48:23 -08:00
@@ -1069,6 +1069,30 @@
 	u32		committed;
 };
 
+#define CT_FLUSH_CACHE 129
+struct aac_synchronize {
+	u32		command;	/* VM_ContainerConfig */
+	u32		type;		/* CT_FLUSH_CACHE */
+	u32		cid;
+	u32		parm1;
+	u32		parm2;
+	u32		parm3;
+	u32		parm4;
+	u32		count;	/* sizeof(((struct aac_synchronize_reply *)NULL)->data) */
+};
+
+struct aac_synchronize_reply {
+	u32		dummy0;
+	u32		dummy1;
+	u32		status;	/* CT_OK */
+	u32		parm1;
+	u32		parm2;
+	u32		parm3;
+	u32		parm4;
+	u32		parm5;
+	u8		data[16];
+};
+
 struct aac_srb
 {
 	u32		function;

-- 
Mark Haverkamp <markh@osdl.org>


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

end of thread, other threads:[~2005-01-20 17:03 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2005-01-19 22:01 [PATCH] aacraid 2.6: add scsi synchronize cache support Mark Haverkamp
2005-01-20 11:31 ` Christoph Hellwig
2005-01-20 17:03   ` [PATCH] aacraid 2.6: add scsi synchronize cache support. (Update) Mark Haverkamp

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.