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>
