Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 11 Apr 2005 01:12:10 -0400
From:      David Sze <dsze@alumni.uwaterloo.ca>
To:        Scott Long <scottl@samsco.org>
Cc:        mb@imp.ch
Subject:   Re: [PATCH] Stability fixes for IPS driver for 4.x
Message-ID:  <6.2.1.2.2.20050411005214.065dc018@mail.distrust.net>
In-Reply-To: <4257F20C.70004@samsco.org>
References:  <4257F20C.70004@samsco.org>

next in thread | previous in thread | raw e-mail | index | archive | help

[-- Attachment #1 --]
At 09:17 AM 09/04/2005 -0600, Scott Long wrote this to All:
>All,
>
>Thanks to the keen eye of David Sze, the cause of the instability in the 
>ips driver in FreeBSD 4.x might have been found.  If it's affecting you,
>please try the attached patch and let me know the results.  I'll commit it 
>when everyone is happy with it.

Scott,

I think there's a problem with the ips_commands.c patch.  After the 
bufq_first call succeeds, bufq_remove must be called before the splx or 
else the iobuf can get issued twice.  However, if the subsequent 
ips_get_free_cmd fails, the iobuf must be put back on the bufq.

Two patches are attached to this message:

1.  ips.RELENG_4.stability.patch is just the stability patch as described.

2.  ips.RELENG_4.mfc-and-stability.patch is an MFC of your IPS cleanup and 
optimization that you committed to HEAD on 01/28/05, plus the stability 
patch as described.

Both patches survived a "make -j8 buildworld" for me.

The problem I'm having now is that ips does not appear to be 
PAE-ified.  With either patch the bus_dmamap_create call fails.  Any 
pointers would be appreciated, this is new territory for me.





>Thanks,
>
>Scott
>
>
>Index: ips_commands.c
>===================================================================
>RCS file: /usr/ncvs/src/sys/dev/ips/ips_commands.c,v
>retrieving revision 1.11.6.1
>diff -u -r1.11.6.1 ips_commands.c
>--- ips_commands.c      13 Jan 2005 00:46:40 -0000      1.11.6.1
>+++ ips_commands.c      9 Apr 2005 15:09:50 -0000
>@@ -162,8 +162,11 @@
>  void ips_start_io_request(ips_softc_t *sc)
>  {
>         struct buf *iobuf;
>+       int s
>
>+       s = splbio();
>         iobuf = bufq_first(&sc->queue);
>+       splx(s);
>         if(!iobuf) {
>                 return;
>         }
>@@ -171,8 +174,10 @@
>         if(ips_get_free_cmd(sc, ips_send_io_request, iobuf, 
> IPS_NOWAIT_FLAG)){
>                 return;
>         }
>-
>+
>+       s = splbio();
>         bufq_remove(&sc->queue, iobuf);
>+       splx(s);
>         return;
>  }
>
>Index: ips_disk.c
>===================================================================
>RCS file: /usr/ncvs/src/sys/dev/ips/ips_disk.c,v
>retrieving revision 1.6.6.1
>diff -u -r1.6.6.1 ips_disk.c
>--- ips_disk.c  13 Jan 2005 00:46:40 -0000      1.6.6.1
>+++ ips_disk.c  9 Apr 2005 15:07:50 -0000
>@@ -128,12 +128,15 @@
>  static void ipsd_strategy(struct buf *iobuf)
>  {
>         ipsdisk_softc_t *dsc;
>+       int s;
>
>         dsc = iobuf->b_dev->si_drv1;
>         DEVICE_PRINTF(8,dsc->dev,"in strategy\n");
>         devstat_start_transaction(&dsc->stats);
>         iobuf->b_driver1 = (void 
> *)(uintptr_t)dsc->sc->drives[dsc->disk_number].drivenum;
>-       bufqdisksort(&dsc->sc->queue, iobuf);
>+       s = splbio();
>+       bufq_insert_tail(&dsc->sc->queue, iobuf);
>+       splx(s);
>         ips_start_io_request(dsc->sc);
>  }
>

[-- Attachment #2 --]
Index: ips_commands.c
===================================================================
RCS file: /var/ncvs/src/sys/dev/ips/ips_commands.c,v
retrieving revision 1.11.6.1
diff -u -r1.11.6.1 ips_commands.c
--- ips_commands.c	13 Jan 2005 00:46:40 -0000	1.11.6.1
+++ ips_commands.c	11 Apr 2005 04:50:53 -0000
@@ -162,17 +162,24 @@
 void ips_start_io_request(ips_softc_t *sc)
 {
 	struct buf *iobuf;
+	intrmask_t mask;
 
+	mask = splbio();
 	iobuf = bufq_first(&sc->queue);
 	if(!iobuf) {
+		splx(mask);
 		return;
 	}
+	bufq_remove(&sc->queue, iobuf);
+	splx(mask);
 
 	if(ips_get_free_cmd(sc, ips_send_io_request, iobuf, IPS_NOWAIT_FLAG)){
+		mask = splbio();
+		bufq_insert_tail(&sc->queue, iobuf);
+		splx(mask);
 		return;
 	}
 	
-	bufq_remove(&sc->queue, iobuf);
 	return;
 }
 
Index: ips_disk.c
===================================================================
RCS file: /var/ncvs/src/sys/dev/ips/ips_disk.c,v
retrieving revision 1.6.6.1
diff -u -r1.6.6.1 ips_disk.c
--- ips_disk.c	13 Jan 2005 00:46:40 -0000	1.6.6.1
+++ ips_disk.c	11 Apr 2005 03:19:52 -0000
@@ -128,12 +128,15 @@
 static void ipsd_strategy(struct buf *iobuf)
 {
 	ipsdisk_softc_t *dsc;
+	intrmask_t mask;
 
 	dsc = iobuf->b_dev->si_drv1;	
 	DEVICE_PRINTF(8,dsc->dev,"in strategy\n");
 	devstat_start_transaction(&dsc->stats);
 	iobuf->b_driver1 = (void *)(uintptr_t)dsc->sc->drives[dsc->disk_number].drivenum;
-	bufqdisksort(&dsc->sc->queue, iobuf);
+	mask = splbio();
+	bufq_insert_tail(&dsc->sc->queue, iobuf);
+	splx(mask);
 	ips_start_io_request(dsc->sc);
 }
 

[-- Attachment #3 --]
Index: ips.c
===================================================================
RCS file: /var/ncvs/src/sys/dev/ips/ips.c,v
retrieving revision 1.13.6.1
diff -u -r1.13.6.1 ips.c
--- ips.c	13 Jan 2005 00:46:40 -0000	1.13.6.1
+++ ips.c	9 Apr 2005 13:40:30 -0000
@@ -109,7 +109,7 @@
 }
 
 /* is locking needed? what locking guarentees are there on removal? */
-static __inline__ int ips_cmdqueue_free(ips_softc_t *sc)
+static int ips_cmdqueue_free(ips_softc_t *sc)
 {
 	int i, error = -1;
 	ips_command_t *command;
@@ -128,22 +128,32 @@
 			bus_dmamem_free(sc->command_dmatag, 
 					command->command_buffer,
 					command->command_dmamap);
+			if (command->data_dmamap != NULL)
+				bus_dmamap_destroy(command->data_dmatag,
+				    command->data_dmamap);
 		}
 		error = 0;
 		sc->state |= IPS_OFFLINE;
 	}
+	sc->staticcmd = NULL;
+	free(sc->commandarray, M_DEVBUF);
 	splx(mask);
 	return error;
 }
 
 /* places all ips command structs on the free command queue.  No locking as if someone else tries
  * to access this during init, we have bigger problems */
-static __inline__ int ips_cmdqueue_init(ips_softc_t *sc)
+static int ips_cmdqueue_init(ips_softc_t *sc)
 {
 	int i;
 	ips_command_t *command;
+
+	sc->commandarray = (ips_command_t *)malloc(sizeof(ips_command_t) *
+	    sc->max_cmds, M_DEVBUF, M_NOWAIT|M_ZERO);
+	if (sc->commandarray == NULL)
+		return (ENOMEM);
+
 	SLIST_INIT(&sc->free_cmd_list);
-	STAILQ_INIT(&sc->cmd_wait_list);
 	for(i = 0; i < sc->max_cmds; i++){
 		command = &sc->commandarray[i];
 		command->id = i;
@@ -161,7 +171,14 @@
 			goto error;
 		}
 
-		SLIST_INSERT_HEAD(&sc->free_cmd_list, command, next);	
+ 		if (i != 0) {
+ 			command->data_dmatag = sc->sg_dmatag;
+ 			if (bus_dmamap_create(command->data_dmatag, 0,
+ 			    &command->data_dmamap))
+ 				goto error;
+ 			SLIST_INSERT_HEAD(&sc->free_cmd_list, command, next);	
+ 		} else
+ 			sc->staticcmd = command;
 	}
 	sc->state &= ~IPS_OFFLINE;
 	return 0;
@@ -170,75 +187,12 @@
 	return ENOMEM;
 }
 
-static int ips_add_waiting_command(ips_softc_t *sc, int (*callback)(ips_command_t *), void *data, unsigned long flags)
-{
-	intrmask_t mask;
-	ips_command_t *command;
-	ips_wait_list_t *waiter;
-	unsigned long memflags = 0;
-	if(IPS_NOWAIT_FLAG & flags)
-		memflags = M_NOWAIT;
-	waiter = malloc(sizeof(ips_wait_list_t), M_IPSBUF, memflags);
-	if(!waiter)
-		return ENOMEM;
-	mask = splbio();
-	if(sc->state & IPS_OFFLINE){
-		splx(mask);
-		free(waiter, M_IPSBUF);
-		return EIO;
-	}
-	command = SLIST_FIRST(&sc->free_cmd_list);
-	if(command && !(sc->state & IPS_TIMEOUT)){
-		SLIST_REMOVE_HEAD(&sc->free_cmd_list, next);
-		(sc->used_commands)++;
-		splx(mask);
-		clear_ips_command(command);
-		bzero(command->command_buffer, IPS_COMMAND_LEN);
-		free(waiter, M_IPSBUF);
-		command->arg = data;
-		return callback(command);
-	}
-	DEVICE_PRINTF(1, sc->dev, "adding command to the wait queue\n"); 
-	waiter->callback = callback; 
-	waiter->data = data;
-	STAILQ_INSERT_TAIL(&sc->cmd_wait_list, waiter, next);
-	splx(mask);
-	return 0;
-}
-
-static void ips_run_waiting_command(ips_softc_t *sc)
-{
-	ips_wait_list_t *waiter;
-	ips_command_t	*command;
-	int (*callback)(ips_command_t*);
-	intrmask_t mask;
-
-	mask = splbio();
-	waiter = STAILQ_FIRST(&sc->cmd_wait_list);
-	command = SLIST_FIRST(&sc->free_cmd_list);
-	if(!waiter || !command){
-		splx(mask);
-		return;
-	}
-	DEVICE_PRINTF(1, sc->dev, "removing command from wait queue\n");
-	SLIST_REMOVE_HEAD(&sc->free_cmd_list, next);
-	STAILQ_REMOVE_HEAD(&sc->cmd_wait_list, next);
-	(sc->used_commands)++;
-	splx(mask);
-	clear_ips_command(command);
-	bzero(command->command_buffer, IPS_COMMAND_LEN);
-	command->arg = waiter->data;
-	callback = waiter->callback;
-	free(waiter, M_IPSBUF);
-	callback(command);
-	return;	
-}
 /* returns a free command struct if one is available. 
  * It also blanks out anything that may be a wild pointer/value.
  * Also, command buffers are not freed.  They are
  * small so they are saved and kept dmamapped and loaded.
  */
-int ips_get_free_cmd(ips_softc_t *sc, int (*callback)(ips_command_t *), void *data, unsigned long flags)
+int ips_get_free_cmd(ips_softc_t *sc, ips_command_t **cmd, unsigned long flags)
 {
 	intrmask_t mask;
 	ips_command_t *command;
@@ -248,20 +202,27 @@
 		splx(mask);
 		return EIO;
 	}
-	command = SLIST_FIRST(&sc->free_cmd_list);
-	if(!command || (sc->state & IPS_TIMEOUT)){
-		splx(mask);
-		if(flags & IPS_NOWAIT_FLAG)
+	if ((flags & IPS_STATIC_FLAG) == 0) {
+		command = SLIST_FIRST(&sc->free_cmd_list);
+		if(!command || (sc->state & IPS_TIMEOUT)){
+			splx(mask);
+			return EBUSY;
+		}
+		SLIST_REMOVE_HEAD(&sc->free_cmd_list, next);
+		(sc->used_commands)++;
+	} else {
+		if (sc->state & IPS_STATIC_BUSY){
+			splx(mask);
 			return EAGAIN;
-		return ips_add_waiting_command(sc, callback, data, flags);
+		}
+		command = sc->staticcmd;
+		sc->state |= IPS_STATIC_BUSY;
 	}
-	SLIST_REMOVE_HEAD(&sc->free_cmd_list, next);
-	(sc->used_commands)++;
 	splx(mask);
 	clear_ips_command(command);
 	bzero(command->command_buffer, IPS_COMMAND_LEN);
-	command->arg = data;
-	return callback(command);
+	*cmd = command;
+	return 0;
 }
 
 /* adds a command back to the free command queue */
@@ -270,11 +231,13 @@
 	intrmask_t mask;
 	mask = splbio();
 
-	SLIST_INSERT_HEAD(&sc->free_cmd_list, command, next);
-	(sc->used_commands)--;
+	if (command != sc->staticcmd) {
+		SLIST_INSERT_HEAD(&sc->free_cmd_list, command, next);
+		(sc->used_commands)--;
+	} else {
+		sc->state &= ~IPS_STATIC_BUSY;
+	}
 	splx(mask);
-	if(!(sc->state & IPS_TIMEOUT))
-		ips_run_waiting_command(sc);
 }
 static const char* ips_diskdev_statename(u_int8_t state)
 {
@@ -379,7 +342,6 @@
 			   would go to the card. This sucks. */
 		} else
 			sc->state &= ~IPS_TIMEOUT;
-		ips_run_waiting_command(sc);
 	}
 	if (sc->state != IPS_OFFLINE)
 		sc->timer = timeout(ips_timeout, sc, 10*hz);
Index: ips.h
===================================================================
RCS file: /var/ncvs/src/sys/dev/ips/ips.h,v
retrieving revision 1.11.6.1
diff -u -r1.11.6.1 ips.h
--- ips.h	13 Jan 2005 00:46:40 -0000	1.11.6.1
+++ ips.h	11 Apr 2005 01:51:43 -0000
@@ -69,12 +69,13 @@
 #define IPS_MAX_SG_LEN			(sizeof(ips_sg_element_t) * IPS_MAX_SG_ELEMENTS)
 #define IPS_NVRAM_PAGE_SIZE		128
 /* various flags */
-#define IPS_NOWAIT_FLAG			1
+#define IPS_STATIC_FLAG			0x01
 
 /* states for the card to be in */
 #define IPS_DEV_OPEN			0x01
 #define IPS_TIMEOUT			0x02 /* command time out, need reset */
 #define IPS_OFFLINE			0x04 /* can't reset card/card failure */
+#define IPS_STATIC_BUSY			0x08
 
 /* max number of commands set to something low for now */
 #define IPS_MAX_CMD_NUM			128	
@@ -377,24 +378,18 @@
 	u_int8_t 		id;
 	u_int8_t		timeout;
 	struct ips_softc *	sc;
+	bus_dma_tag_t		data_dmatag;
+	bus_dmamap_t		data_dmamap;
 	bus_dmamap_t		command_dmamap;
 	void *			command_buffer;
 	u_int32_t		command_phys_addr;/*WARNING! must be changed if 64bit addressing ever used*/	
 	ips_cmd_status_t	status;
 	SLIST_ENTRY(ips_command)	next;
-	bus_dma_tag_t		data_dmatag;
-	bus_dmamap_t		data_dmamap;
 	void *			data_buffer;
-	void * 			arg;
+	void *			arg;
 	void			(* callback)(struct ips_command *command);
 }ips_command_t;
 
-typedef struct ips_wait_list{
-	STAILQ_ENTRY(ips_wait_list) next;
-	void 			*data;
-	int			(* callback)(ips_command_t *command);
-}ips_wait_list_t;
-
 typedef struct ips_softc{
         struct resource *       iores;
         struct resource *       irqres;
@@ -423,9 +418,9 @@
 	u_int8_t		next_drive;
 	u_int8_t		max_cmds;
 	volatile u_int8_t	used_commands;
-	ips_command_t		commandarray[IPS_MAX_CMD_NUM];
+	ips_command_t		*commandarray;
+	ips_command_t		*staticcmd;
 	SLIST_HEAD(command_list, ips_command) free_cmd_list;
-	STAILQ_HEAD(command_wait_list,ips_wait_list)  cmd_wait_list;
 	int			(* ips_adapter_reinit)(struct ips_softc *sc, 
 						       int force);
         void                    (* ips_adapter_intr)(void *sc);
@@ -451,8 +446,7 @@
 extern int ips_clear_adapter(ips_softc_t *sc);
 
 /* function defines from ips.c */
-extern int ips_get_free_cmd(ips_softc_t *sc, int (*callback)(ips_command_t *), 
-				void *data, unsigned long flags);
+extern int ips_get_free_cmd(ips_softc_t *sc, ips_command_t **command, unsigned long flags);
 extern void ips_insert_free_cmd(ips_softc_t *sc, ips_command_t *command);
 extern int ips_adapter_init(ips_softc_t *sc);
 extern int ips_morpheus_reinit(ips_softc_t *sc, int force);
Index: ips_commands.c
===================================================================
RCS file: /var/ncvs/src/sys/dev/ips/ips_commands.c,v
retrieving revision 1.11.6.1
diff -u -r1.11.6.1 ips_commands.c
--- ips_commands.c	13 Jan 2005 00:46:40 -0000	1.11.6.1
+++ ips_commands.c	11 Apr 2005 01:57:41 -0000
@@ -38,12 +38,9 @@
  */
 static void ips_wakeup_callback(ips_command_t *command)
 {
-	ips_cmd_status_t *status;
-	status = command->arg;
-	status->value = command->status.value;
 	bus_dmamap_sync(command->sc->command_dmatag, command->command_dmamap, 
 			BUS_DMASYNC_POSTWRITE);
-	wakeup(status);
+	wakeup(&command->status);
 }
 /* Below are a series of functions for sending an IO request
  * to the adapter.  The flow order is: start, send, callback, finish.
@@ -61,7 +58,6 @@
 				BUS_DMASYNC_POSTWRITE);
 	}
 	bus_dmamap_unload(command->data_dmatag, command->data_dmamap);
-	bus_dmamap_destroy(command->data_dmatag, command->data_dmamap);
 	if(COMMAND_ERROR(&command->status)){
 		iobuf->b_flags |=B_ERROR;
 		iobuf->b_error = EIO;
@@ -84,7 +80,6 @@
 	if(error){
 		printf("ips: error = %d in ips_sg_request_callback\n", error);
 		bus_dmamap_unload(command->data_dmatag, command->data_dmamap);
-		bus_dmamap_destroy(command->data_dmatag, command->data_dmamap);
 		iobuf->b_flags |= B_ERROR;
 		iobuf->b_error = ENOMEM;
 		ips_insert_free_cmd(sc, command);
@@ -138,20 +133,10 @@
 	return;
 }
 
-static int ips_send_io_request(ips_command_t *command)
+static int ips_send_io_request(ips_command_t *command, struct buf *iobuf)
 {
-	ips_softc_t *sc = command->sc;
-	struct buf *iobuf = command->arg;
-	command->data_dmatag = sc->sg_dmatag;
-	if(bus_dmamap_create(command->data_dmatag, 0, &command->data_dmamap)){
-		device_printf(sc->dev, "dmamap failed\n");
-		iobuf->b_flags |= B_ERROR;
-		iobuf->b_error = ENOMEM;
-		ips_insert_free_cmd(sc, command);
-		ipsd_finish(iobuf);
-		return 0;
-	}
 	command->callback = ips_io_request_finish;
+	command->arg = iobuf;
 	PRINTF(10, "ips test: : bcount %ld\n", iobuf->b_bcount);
 	bus_dmamap_load(command->data_dmatag, command->data_dmamap,
 			iobuf->b_data, iobuf->b_bcount,
@@ -162,17 +147,23 @@
 void ips_start_io_request(ips_softc_t *sc)
 {
 	struct buf *iobuf;
+	ips_command_t *command;
+	intrmask_t mask = splbio();
 
 	iobuf = bufq_first(&sc->queue);
-	if(!iobuf) {
+	if(!iobuf){
+		splx(mask);
 		return;
 	}
 
-	if(ips_get_free_cmd(sc, ips_send_io_request, iobuf, IPS_NOWAIT_FLAG)){
+	if (ips_get_free_cmd(sc, &command, 0)){
+		splx(mask);
 		return;
 	}
 	
 	bufq_remove(&sc->queue, iobuf);
+	splx(mask);
+	ips_send_io_request(command, iobuf);
 	return;
 }
 
@@ -187,8 +178,7 @@
 	ips_adapter_info_cmd *command_struct;
 	sc = command->sc;
 	if(error){
-		ips_cmd_status_t * status = command->arg;
-		status->value = IPS_ERROR_STATUS; /* a lovely error value */
+		command->status.value = IPS_ERROR_STATUS; /* a lovely error value */
 		ips_insert_free_cmd(sc, command);
 		printf("ips: error = %d in ips_get_adapter_info\n", error);
 		return;
@@ -211,7 +201,6 @@
 {
 	int error = 0;
 	ips_softc_t *sc = command->sc;
-	ips_cmd_status_t *status = command->arg;
 
 	if (bus_dma_tag_create(	/* parent    */	sc->adapter_dmatag,
 				/* alignemnt */	1,
@@ -235,7 +224,7 @@
 		goto exit;
 	}
 	command->callback = ips_wakeup_callback;
-	asleep(status, 0, "ips", 30*hz);
+	asleep(&command->status, 0, "ips", 30*hz);
 	bus_dmamap_load(command->data_dmatag, command->data_dmamap, 
 			command->data_buffer,IPS_ADAPTER_INFO_LEN, 
 			ips_adapter_info_callback, command, BUS_DMA_NOWAIT);
@@ -261,21 +250,17 @@
 
 int ips_get_adapter_info(ips_softc_t *sc)
 {
+	ips_command_t *command;
 	int error = 0;
-	ips_cmd_status_t *status;
-	status = malloc(sizeof(ips_cmd_status_t), M_IPSBUF, M_NOWAIT|M_ZERO);
-	if(!status)
-		return ENOMEM;
-	if(ips_get_free_cmd(sc, ips_send_adapter_info_cmd, status, 
-			    IPS_NOWAIT_FLAG) > 0){
+
+	if (ips_get_free_cmd(sc, &command, IPS_STATIC_FLAG) > 0){
 		device_printf(sc->dev, "unable to get adapter configuration\n");
-		free(status, M_IPSBUF);
 		return ENXIO;
 	}
-	if (COMMAND_ERROR(status)){
+	ips_send_adapter_info_cmd(command);
+	if (COMMAND_ERROR(&command->status)){
 		error = ENXIO;
 	}
-	free(status, M_IPSBUF);
 	return error;
 }
 
@@ -290,8 +275,7 @@
 	ips_drive_cmd *command_struct;
 	sc = command->sc;
 	if(error){
-		ips_cmd_status_t * status = command->arg;
-                status->value = IPS_ERROR_STATUS;
+                command->status.value = IPS_ERROR_STATUS;
 		ips_insert_free_cmd(sc, command);
 		printf("ips: error = %d in ips_get_drive_info\n", error);
 		return;
@@ -312,7 +296,6 @@
 {
 	int error = 0;
 	ips_softc_t *sc = command->sc;
-	ips_cmd_status_t *status = command->arg;
 	ips_drive_info_t *driveinfo;
 
 	if (bus_dma_tag_create(	/* parent    */	sc->adapter_dmatag,
@@ -337,7 +320,7 @@
 		goto exit;
 	}
 	command->callback = ips_wakeup_callback;
-	asleep(status, 0, "ips", 10*hz);
+	asleep(&command->status, 0, "ips", 10*hz);
 	bus_dmamap_load(command->data_dmatag, command->data_dmamap, 
 			command->data_buffer,IPS_DRIVE_INFO_LEN, 
 			ips_drive_info_callback, command, BUS_DMA_NOWAIT);
@@ -365,20 +348,16 @@
 int ips_get_drive_info(ips_softc_t *sc)
 {
 	int error = 0;
-	ips_cmd_status_t *status;
-	status = malloc(sizeof(ips_cmd_status_t), M_IPSBUF, M_NOWAIT|M_ZERO);
-	if(!status)
-		return ENOMEM;
-	if(ips_get_free_cmd(sc, ips_send_drive_info_cmd, status, 
-			    IPS_NOWAIT_FLAG) > 0){
-		free(status, M_IPSBUF);
+	ips_command_t *command;
+
+	if (ips_get_free_cmd(sc, &command, IPS_STATIC_FLAG) > 0){
 		device_printf(sc->dev, "unable to get drive configuration\n");
 		return ENXIO;
 	}
-	if(COMMAND_ERROR(status)){
+	ips_send_drive_info_cmd(command);
+	if(COMMAND_ERROR(&command->status)){
 		error = ENXIO;
 	}
-	free(status, M_IPSBUF);
 	return error;
 }
 
@@ -387,7 +366,6 @@
 static int ips_send_flush_cache_cmd(ips_command_t *command)
 {
 	ips_softc_t *sc = command->sc;
-	ips_cmd_status_t *status = command->arg;
 	ips_generic_cmd *command_struct;
 
 	PRINTF(10,"ips test: got a command, building flush command\n");
@@ -397,7 +375,7 @@
 	command_struct->id = command->id;
 	bus_dmamap_sync(sc->command_dmatag, command->command_dmamap, 
 			BUS_DMASYNC_PREWRITE);
-	asleep(status, 0, "slush2", 0);
+	asleep(&command->status, 0, "slush2", 0);
 	sc->ips_issue_cmd(command);
 	await(-1, -1);
 	ips_insert_free_cmd(sc, command);
@@ -406,20 +384,16 @@
 
 int ips_flush_cache(ips_softc_t *sc)
 {
-	ips_cmd_status_t *status;
-	status = malloc(sizeof(ips_cmd_status_t), M_IPSBUF, M_NOWAIT|M_ZERO);
-	if(!status)
-		return ENOMEM;
+	ips_command_t *command;
+
 	device_printf(sc->dev, "flushing cache\n");
-	if(ips_get_free_cmd(sc, ips_send_flush_cache_cmd, status, 
-			    IPS_NOWAIT_FLAG)){
-		free(status, M_IPSBUF);
+	if (ips_get_free_cmd(sc, &command, IPS_STATIC_FLAG)){
 		device_printf(sc->dev, "ERROR: unable to get a command! can't flush cache!\n");
 	}
-	if(COMMAND_ERROR(status)){
+	ips_send_flush_cache_cmd(command);
+	if(COMMAND_ERROR(&command->status)){
 		device_printf(sc->dev, "ERROR: cache flush command failed!\n");
 	}
-	free(status, M_IPSBUF);
 	return 0;
 }
 
@@ -469,7 +443,6 @@
 static int ips_send_ffdc_reset_cmd(ips_command_t *command)
 {
 	ips_softc_t *sc = command->sc;
-	ips_cmd_status_t *status = command->arg;
 	ips_adapter_ffdc_cmd *command_struct;
 
 	PRINTF(10,"ips test: got a command, building ffdc reset command\n");
@@ -483,7 +456,7 @@
 
 	bus_dmamap_sync(sc->command_dmatag, command->command_dmamap,
 			BUS_DMASYNC_PREWRITE);
-	asleep(status, 0, "ips_ffdc", 0);
+	asleep(&command->status, 0, "ips_ffdc", 0);
 	sc->ips_issue_cmd(command);
 	await(-1, -1);
 	ips_insert_free_cmd(sc, command);
@@ -492,19 +465,15 @@
 
 int ips_ffdc_reset(ips_softc_t *sc)
 {
-	ips_cmd_status_t *status;
-	status = malloc(sizeof(ips_cmd_status_t), M_IPSBUF, M_NOWAIT|M_ZERO);
-	if(!status)
-		return ENOMEM;
-	if(ips_get_free_cmd(sc, ips_send_ffdc_reset_cmd, status,
-			    IPS_NOWAIT_FLAG)){
-		free(status, M_IPSBUF);
+	ips_command_t *command;
+
+	if (ips_get_free_cmd(sc, &command, IPS_STATIC_FLAG)){
 		device_printf(sc->dev, "ERROR: unable to get a command! can't send ffdc reset!\n");
 	}
-	if(COMMAND_ERROR(status)){
+	ips_send_ffdc_reset_cmd(command);
+	if(COMMAND_ERROR(&command->status)){
 		device_printf(sc->dev, "ERROR: ffdc reset command failed!\n");
 	}
-	free(status, M_IPSBUF);
 	return 0;
 }
 
@@ -541,8 +510,7 @@
 	ips_rw_nvram_cmd *command_struct;
 	sc = command->sc;
 	if(error){
-		ips_cmd_status_t * status = command->arg;
-                status->value = IPS_ERROR_STATUS;
+                command->status.value = IPS_ERROR_STATUS;
 		ips_insert_free_cmd(sc, command);
 		printf("ips: error = %d in ips_read_nvram_callback\n", error);
 		return;
@@ -561,10 +529,10 @@
 	sc->ips_issue_cmd(command);
 }
 
-static int ips_read_nvram(ips_command_t *command){
+static int ips_read_nvram(ips_command_t *command)
+{
 	int error = 0;
 	ips_softc_t *sc = command->sc;
-	ips_cmd_status_t *status = command->arg;
 
 	if (bus_dma_tag_create(	/* parent    */	sc->adapter_dmatag,
 				/* alignemnt */	1,
@@ -588,7 +556,7 @@
 		goto exit;
 	}
 	command->callback = ips_write_nvram;
-	asleep(status, 0, "ips", 0);
+	asleep(&command->status, 0, "ips", 0);
 	bus_dmamap_load(command->data_dmatag, command->data_dmamap, 
 			command->data_buffer,IPS_NVRAM_PAGE_SIZE, 
 			ips_read_nvram_callback, command, BUS_DMA_NOWAIT);
@@ -610,19 +578,16 @@
 
 int ips_update_nvram(ips_softc_t *sc)
 {
-	ips_cmd_status_t *status;
-	status = malloc(sizeof(ips_cmd_status_t), M_IPSBUF, M_NOWAIT|M_ZERO);
-	if(!status)
-		return ENOMEM;
-	if(ips_get_free_cmd(sc, ips_read_nvram, status, IPS_NOWAIT_FLAG)){
-		free(status, M_IPSBUF);
+	ips_command_t *command;
+
+	if (ips_get_free_cmd(sc, &command, IPS_STATIC_FLAG)){
 		device_printf(sc->dev, "ERROR: unable to get a command! can't update nvram\n");
 		return 1;
 	}
-	if(COMMAND_ERROR(status)){
+	ips_read_nvram(command);
+	if(COMMAND_ERROR(&command->status)){
 		device_printf(sc->dev, "ERROR: nvram update command failed!\n");
 	}
-	free(status, M_IPSBUF);
 	return 0;
 
 
@@ -632,7 +597,6 @@
 static int ips_send_config_sync_cmd(ips_command_t *command)
 {
 	ips_softc_t *sc = command->sc;
-	ips_cmd_status_t *status = command->arg;
 	ips_generic_cmd *command_struct;
 
 	PRINTF(10,"ips test: got a command, building flush command\n");
@@ -643,7 +607,7 @@
 	command_struct->reserve2 = IPS_POCL;
 	bus_dmamap_sync(sc->command_dmatag, command->command_dmamap, 
 			BUS_DMASYNC_PREWRITE);
-	asleep(status, 0, "ipssyn", 0);
+	asleep(&command->status, 0, "ipssyn", 0);
 	sc->ips_issue_cmd(command);
 	await(-1, -1);
 	ips_insert_free_cmd(sc, command);
@@ -653,7 +617,6 @@
 static int ips_send_error_table_cmd(ips_command_t *command)
 {
 	ips_softc_t *sc = command->sc;
-	ips_cmd_status_t *status = command->arg;
 	ips_generic_cmd *command_struct;
 
 	PRINTF(10,"ips test: got a command, building errortable command\n");
@@ -664,7 +627,7 @@
 	command_struct->reserve2 = IPS_CSL;
 	bus_dmamap_sync(sc->command_dmatag, command->command_dmamap, 
 			BUS_DMASYNC_PREWRITE);
-	asleep(status, 0, "ipsetc", 0);
+	asleep(&command->status, 0, "ipsetc", 0);
 	sc->ips_issue_cmd(command);
 	await(-1, -1);
 	ips_insert_free_cmd(sc, command);
@@ -674,36 +637,29 @@
 
 int ips_clear_adapter(ips_softc_t *sc)
 {
-	ips_cmd_status_t *status;
-	status = malloc(sizeof(ips_cmd_status_t), M_IPSBUF, M_NOWAIT|M_ZERO);
-	if(!status)
-		return ENOMEM;
+	ips_command_t *command;
+
 	device_printf(sc->dev, "syncing config\n");
-	if(ips_get_free_cmd(sc, ips_send_config_sync_cmd, status, 
-			    IPS_NOWAIT_FLAG)){
-		free(status, M_IPSBUF);
+	if (ips_get_free_cmd(sc, &command, IPS_STATIC_FLAG)){
 		device_printf(sc->dev, "ERROR: unable to get a command! can't sync cache!\n");
 		return 1;
 	}
-	if(COMMAND_ERROR(status)){
-		free(status, M_IPSBUF);
+	ips_send_config_sync_cmd(command);
+	if(COMMAND_ERROR(&command->status)){
 		device_printf(sc->dev, "ERROR: cache sync command failed!\n");
 		return 1;
 	}
 
 	device_printf(sc->dev, "clearing error table\n");
-	if(ips_get_free_cmd(sc, ips_send_error_table_cmd, status, 
-			    IPS_NOWAIT_FLAG)){
-		free(status, M_IPSBUF);
+	if(ips_get_free_cmd(sc, &command, IPS_STATIC_FLAG)){
 		device_printf(sc->dev, "ERROR: unable to get a command! can't sync cache!\n");
 		return 1;
 	}
-	if(COMMAND_ERROR(status)){
+	ips_send_error_table_cmd(command);
+	if(COMMAND_ERROR(&command->status)){
 		device_printf(sc->dev, "ERROR: etable command failed!\n");
-		free(status, M_IPSBUF);
 		return 1;
 	}
 
-	free(status, M_IPSBUF);
 	return 0;
 }
Index: ips_disk.c
===================================================================
RCS file: /var/ncvs/src/sys/dev/ips/ips_disk.c,v
retrieving revision 1.6.6.1
diff -u -r1.6.6.1 ips_disk.c
--- ips_disk.c	13 Jan 2005 00:46:40 -0000	1.6.6.1
+++ ips_disk.c	11 Apr 2005 01:54:44 -0000
@@ -128,12 +128,15 @@
 static void ipsd_strategy(struct buf *iobuf)
 {
 	ipsdisk_softc_t *dsc;
+	intrmask_t mask;
 
 	dsc = iobuf->b_dev->si_drv1;	
 	DEVICE_PRINTF(8,dsc->dev,"in strategy\n");
 	devstat_start_transaction(&dsc->stats);
 	iobuf->b_driver1 = (void *)(uintptr_t)dsc->sc->drives[dsc->disk_number].drivenum;
-	bufqdisksort(&dsc->sc->queue, iobuf);
+	mask = splbio();
+	bufq_insert_tail(&dsc->sc->queue, iobuf);
+	splx(mask);
 	ips_start_io_request(dsc->sc);
 }
 
Index: ips_ioctl.c
===================================================================
RCS file: /var/ncvs/src/sys/dev/ips/ips_ioctl.c,v
retrieving revision 1.5.6.1
diff -u -r1.5.6.1 ips_ioctl.c
--- ips_ioctl.c	13 Jan 2005 00:46:40 -0000	1.5.6.1
+++ ips_ioctl.c	7 Apr 2005 23:56:08 -0000
@@ -84,6 +84,7 @@
 
 static int ips_ioctl_cmd(ips_softc_t *sc, ips_ioctl_t *ioctl_cmd, ips_user_request *user_request)
 {
+	ips_command_t *command;
 	int error = EINVAL;
 
 	if (bus_dma_tag_create(	/* parent    */	sc->adapter_dmatag,
@@ -109,10 +110,12 @@
 	    ioctl_cmd->datasize))
 		goto exit;
 	ioctl_cmd->status.value = 0xffffffff;
-	if((error = ips_get_free_cmd(sc, ips_ioctl_start, ioctl_cmd,0)) > 0){
+	if((error = ips_get_free_cmd(sc, &command, 0)) > 0){
 		error = ENOMEM;
 		goto exit;
 	}
+	command->arg = ioctl_cmd;
+	ips_ioctl_start(command);
 	while( ioctl_cmd->status.value == 0xffffffff)
 		tsleep(ioctl_cmd, 0, "ips", hz/10);
 	if(COMMAND_ERROR(&ioctl_cmd->status))

Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?6.2.1.2.2.20050411005214.065dc018>