svn commit: r185724 - in head/sys: dev/adb powerpc/powermac

Nathan Whitehorn nwhitehorn at FreeBSD.org
Sat Dec 6 15:26:03 PST 2008


Author: nwhitehorn
Date: Sat Dec  6 23:26:02 2008
New Revision: 185724
URL: http://svn.freebsd.org/changeset/base/185724

Log:
  Fix some nasty race conditions in the VIA-CUDA driver that ended up preventing
  my right mouse button and keyboard LEDs from working due to mangled
  configuration packets. Fixed several other races and associated problems in the
  main ADB stack that were exposed while fixing this.

Modified:
  head/sys/dev/adb/adb.h
  head/sys/dev/adb/adb_bus.c
  head/sys/dev/adb/adb_kbd.c
  head/sys/dev/adb/adb_mouse.c
  head/sys/dev/adb/adbvar.h
  head/sys/powerpc/powermac/cuda.c
  head/sys/powerpc/powermac/cudavar.h

Modified: head/sys/dev/adb/adb.h
==============================================================================
--- head/sys/dev/adb/adb.h	Sat Dec  6 23:00:48 2008	(r185723)
+++ head/sys/dev/adb/adb.h	Sat Dec  6 23:26:02 2008	(r185724)
@@ -68,7 +68,7 @@ uint8_t adb_get_device_type(device_t dev
 uint8_t adb_get_device_handler(device_t dev);
 uint8_t adb_set_device_handler(device_t dev, uint8_t newhandler);
 
-uint8_t adb_read_register(device_t dev, u_char reg, size_t *len, void *data);
+size_t	adb_read_register(device_t dev, u_char reg, void *data);
 
 /* Bits for implementing ADB host bus adapters */
 extern devclass_t adb_devclass;

Modified: head/sys/dev/adb/adb_bus.c
==============================================================================
--- head/sys/dev/adb/adb_bus.c	Sat Dec  6 23:00:48 2008	(r185723)
+++ head/sys/dev/adb/adb_bus.c	Sat Dec  6 23:26:02 2008	(r185724)
@@ -48,7 +48,7 @@ static void adb_bus_enumerate(void *xdev
 static void adb_probe_nomatch(device_t dev, device_t child);
 static int adb_print_child(device_t dev, device_t child);
 
-static int adb_send_raw_packet_sync(device_t dev, uint8_t to, uint8_t command, uint8_t reg, int len, u_char *data);
+static int adb_send_raw_packet_sync(device_t dev, uint8_t to, uint8_t command, uint8_t reg, int len, u_char *data, u_char *reply);
 
 static char *adb_device_string[] = {
 	"HOST", "dongle", "keyboard", "mouse", "tablet", "modem", "RESERVED", "misc"
@@ -118,8 +118,7 @@ adb_bus_enumerate(void *xdev)
 
 	sc->packet_reply = 0;
 	sc->autopoll_mask = 0;
-
-	mtx_init(&sc->sc_sync_mtx,"adbsyn",NULL,MTX_DEF | MTX_RECURSE);
+	sc->sync_packet = 0xffff;
 
 	/* Initialize devinfo */
 	for (i = 0; i < 16; i++) {
@@ -128,7 +127,7 @@ adb_bus_enumerate(void *xdev)
 	}
 	
 	/* Reset ADB bus */
-	adb_send_raw_packet_sync(dev,0,ADB_COMMAND_BUS_RESET,0,0,NULL);
+	adb_send_raw_packet_sync(dev,0,ADB_COMMAND_BUS_RESET,0,0,NULL,NULL);
 	DELAY(1500);
 
 	/* Enumerate bus */
@@ -140,7 +139,7 @@ adb_bus_enumerate(void *xdev)
 
 	    do {
 		reply = adb_send_raw_packet_sync(dev,i,
-			    ADB_COMMAND_TALK,3,0,NULL);
+			    ADB_COMMAND_TALK,3,0,NULL,NULL);
 	
 		if (reply) {
 			/* If we got a response, relocate to next_free */
@@ -150,10 +149,10 @@ adb_bus_enumerate(void *xdev)
 			r3 |= 0x00fe;
 
 			adb_send_raw_packet_sync(dev,i, ADB_COMMAND_LISTEN,3,
-			    sizeof(uint16_t),(u_char *)(&r3));
+			    sizeof(uint16_t),(u_char *)(&r3),NULL);
 
 			adb_send_raw_packet_sync(dev,next_free,
-			    ADB_COMMAND_TALK,3,0,NULL);
+			    ADB_COMMAND_TALK,3,0,NULL,NULL);
 
 			sc->devinfo[next_free].default_address = i;
 			if (first_relocated < 0)
@@ -169,9 +168,9 @@ adb_bus_enumerate(void *xdev)
 			
 			adb_send_raw_packet_sync(dev,first_relocated,
 			    ADB_COMMAND_LISTEN,3,
-			    sizeof(uint16_t),(u_char *)(&r3));
+			    sizeof(uint16_t),(u_char *)(&r3),NULL);
 			adb_send_raw_packet_sync(dev,i,
-			    ADB_COMMAND_TALK,3,0,NULL);
+			    ADB_COMMAND_TALK,3,0,NULL,NULL);
 
 			sc->devinfo[i].default_address = i;
 			sc->devinfo[(int)(first_relocated)].default_address = 0;
@@ -194,10 +193,6 @@ adb_bus_enumerate(void *xdev)
 
 static int adb_bus_detach(device_t dev)
 {
-	struct adb_softc *sc = device_get_softc(dev);
-
-	mtx_destroy(&sc->sc_sync_mtx);
-
 	return (bus_generic_detach(dev));
 }
 	
@@ -230,6 +225,7 @@ adb_receive_raw_packet(device_t dev, u_c
 	if (sc->sync_packet == command)  {
 		memcpy(sc->syncreg,data,(len > 8) ? 8 : len);
 		atomic_store_rel_int(&sc->packet_reply,len + 1);
+		wakeup(sc);
 	}
 
 	if (sc->children[addr] != NULL) {
@@ -317,12 +313,12 @@ adb_get_device_handler(device_t dev) 
 
 static int 
 adb_send_raw_packet_sync(device_t dev, uint8_t to, uint8_t command, 
-    uint8_t reg, int len, u_char *data) 
+    uint8_t reg, int len, u_char *data, u_char *reply) 
 {
 	u_char command_byte = 0;
 	struct adb_softc *sc;
 	int result = -1;
-	int i = 0;
+	int i = 1;
 
 	sc = device_get_softc(dev);
 	
@@ -331,7 +327,8 @@ adb_send_raw_packet_sync(device_t dev, u
 	command_byte |= reg;
 
 	/* Wait if someone else has a synchronous request pending */
-	mtx_lock(&sc->sc_sync_mtx);
+	while (!atomic_cmpset_int(&sc->sync_packet, 0xffff, command_byte))
+		tsleep(sc, 0, "ADB sync", hz/10);
 
 	sc->packet_reply = 0;
 	sc->sync_packet = command_byte;
@@ -343,21 +340,27 @@ adb_send_raw_packet_sync(device_t dev, u
 		 * Maybe the command got lost? Try resending and polling the 
 		 * controller.
 		 */
-		if (i > 40)
+		if (i % 40 == 0)
 			ADB_HB_SEND_RAW_PACKET(sc->parent, command_byte, 
 			    len, data, 1);
 
-		DELAY(100);
+		tsleep(sc, 0, "ADB sync", hz/10);
 		i++;
 	}
 
 	result = sc->packet_reply - 1;
 
+	if (reply != NULL && result > 0)
+		memcpy(reply,sc->syncreg,result);
+
 	/* Clear packet sync */
 	sc->packet_reply = 0;
-	sc->sync_packet = 0xffff; /* We can't match a 16 bit value */
 
-	mtx_unlock(&sc->sc_sync_mtx);
+	/*
+	 * We can't match a value beyond 8 bits, so set sync_packet to 
+	 * 0xffff to avoid collisions.
+	 */
+	atomic_set_int(&sc->sync_packet, 0xffff); 
 
 	return (result);
 }
@@ -375,37 +378,27 @@ adb_set_device_handler(device_t dev, uin
 	newr3 = dinfo->register3 & 0xff00;
 	newr3 |= (uint16_t)(newhandler);
 
+	adb_send_raw_packet_sync(sc->sc_dev,dinfo->address, ADB_COMMAND_LISTEN, 
+	    3, sizeof(uint16_t), (u_char *)(&newr3), NULL);
 	adb_send_raw_packet_sync(sc->sc_dev,dinfo->address, 
-	    ADB_COMMAND_LISTEN, 3, sizeof(uint16_t), (u_char *)(&newr3));
-	adb_send_raw_packet_sync(sc->sc_dev,dinfo->address, 
-	    ADB_COMMAND_TALK, 3, 0, NULL);
+	    ADB_COMMAND_TALK, 3, 0, NULL, NULL);
 
 	return (dinfo->handler_id);
 }
 
-uint8_t 
-adb_read_register(device_t dev, u_char reg, 
-    size_t *len, void *data) 
+size_t 
+adb_read_register(device_t dev, u_char reg, void *data) 
 {
 	struct adb_softc *sc;
 	struct adb_devinfo *dinfo;
-	size_t orig_len;
+	size_t result;
 
 	dinfo = device_get_ivars(dev);
 	sc = device_get_softc(device_get_parent(dev));
 
-	orig_len = *len;
-
-	mtx_lock(&sc->sc_sync_mtx);
-	
-	*len = adb_send_raw_packet_sync(sc->sc_dev,dinfo->address,
-	           ADB_COMMAND_TALK, reg, 0, NULL);
+	result = adb_send_raw_packet_sync(sc->sc_dev,dinfo->address,
+	           ADB_COMMAND_TALK, reg, 0, NULL, data);
 
-	if (*len > 0)
-		memcpy(data,sc->syncreg,*len);
-
-	mtx_unlock(&sc->sc_sync_mtx);
-
-	return ((*len > 0) ? 0 : -1);
+	return (result);
 }
 

Modified: head/sys/dev/adb/adb_kbd.c
==============================================================================
--- head/sys/dev/adb/adb_kbd.c	Sat Dec  6 23:00:48 2008	(r185723)
+++ head/sys/dev/adb/adb_kbd.c	Sat Dec  6 23:26:02 2008	(r185724)
@@ -271,11 +271,12 @@ adb_kbd_attach(device_t dev) 
 	}
 #endif
 
-	adb_set_autopoll(dev,1);
-
-	/* Check (asynchronously) if we can read out the LED state from 
+	/* Check if we can read out the LED state from 
 	   this keyboard by reading the key state register */
-	adb_send_packet(dev,ADB_COMMAND_TALK,2,0,NULL);
+	if (adb_read_register(dev, 2, NULL) == 2)
+		sc->have_led_control = 1;
+
+	adb_set_autopoll(dev,1);
 
 	return (0);
 }
@@ -323,11 +324,6 @@ adb_kbd_receive_packet(device_t dev, u_c
 	if (command != ADB_COMMAND_TALK)
 		return 0;
 
-	if (reg == 2 && len == 2) {
-		sc->have_led_control = 1;
-		return 0;
-	}
-
 	if (reg != 0 || len != 2)
 		return (0);
 

Modified: head/sys/dev/adb/adb_mouse.c
==============================================================================
--- head/sys/dev/adb/adb_mouse.c	Sat Dec  6 23:00:48 2008	(r185723)
+++ head/sys/dev/adb/adb_mouse.c	Sat Dec  6 23:26:02 2008	(r185724)
@@ -181,7 +181,7 @@ adb_mouse_attach(device_t dev) 
 		sc->mode.resolution = 200;
 		break;
 	case 4:
-		adb_read_register(dev,1,&r1_len,r1);
+		r1_len = adb_read_register(dev,1,r1);
 		if (r1_len < 8)
 			break;
 

Modified: head/sys/dev/adb/adbvar.h
==============================================================================
--- head/sys/dev/adb/adbvar.h	Sat Dec  6 23:00:48 2008	(r185723)
+++ head/sys/dev/adb/adbvar.h	Sat Dec  6 23:26:02 2008	(r185724)
@@ -40,7 +40,6 @@ struct adb_softc {
 	device_t	parent;
 
 	struct intr_config_hook enum_hook;
-	struct mtx	sc_sync_mtx;
 	
 	volatile int 	sync_packet;
 	volatile int	packet_reply;

Modified: head/sys/powerpc/powermac/cuda.c
==============================================================================
--- head/sys/powerpc/powermac/cuda.c	Sat Dec  6 23:00:48 2008	(r185723)
+++ head/sys/powerpc/powermac/cuda.c	Sat Dec  6 23:26:02 2008	(r185724)
@@ -65,10 +65,12 @@ static int	cuda_probe(device_t);
 static int	cuda_attach(device_t);
 static int	cuda_detach(device_t);
 
-static u_int cuda_adb_send(device_t dev, u_char command_byte, int len, 
+static u_int	cuda_adb_send(device_t dev, u_char command_byte, int len, 
     u_char *data, u_char poll);
-static u_int cuda_adb_autopoll(device_t dev, uint16_t mask);
-static void cuda_poll(device_t dev);
+static u_int	cuda_adb_autopoll(device_t dev, uint16_t mask);
+static void	cuda_poll(device_t dev);
+static void	cuda_send_inbound(struct cuda_softc *sc);
+static void	cuda_send_outbound(struct cuda_softc *sc);
 
 static device_method_t  cuda_methods[] = {
 	/* Device interface */
@@ -102,6 +104,8 @@ static devclass_t cuda_devclass;
 DRIVER_MODULE(cuda, macio, cuda_driver, cuda_devclass, 0, 0);
 DRIVER_MODULE(adb, cuda, adb_driver, adb_devclass, 0, 0);
 
+MALLOC_DEFINE(M_CUDA, "cuda", "CUDA packet queue");
+
 static void cuda_intr(void *arg);
 static uint8_t cuda_read_reg(struct cuda_softc *sc, u_int offset);
 static void cuda_write_reg(struct cuda_softc *sc, u_int offset, uint8_t value);
@@ -170,9 +174,11 @@ cuda_attach(device_t dev)
 	sc->sc_waiting = 0;
 	sc->sc_polling = 0;
 	sc->sc_state = CUDA_NOTREADY;
-	sc->sc_error = 0;
 	sc->sc_autopoll = 0;
 
+	STAILQ_INIT(&sc->sc_inq);
+	STAILQ_INIT(&sc->sc_outq);
+
 	/* Init CUDA */
 
 	reg = cuda_read_reg(sc, vDirB);
@@ -335,42 +341,126 @@ cuda_send(void *cookie, int poll, int le
 {
 	struct cuda_softc *sc = cookie;
 	device_t dev = sc->sc_dev;
+	struct cuda_packet *pkt;
 
 	if (sc->sc_state == CUDA_NOTREADY)
-		return -1;
+		return (-1);
 
 	mtx_lock(&sc->sc_mutex);
 
-	if (sc->sc_state != CUDA_IDLE) {
-		if (sc->sc_waiting == 0) {
-			sc->sc_waiting = 1;
-		} else {
-			mtx_unlock(&sc->sc_mutex);
-			return -1;
-		}
+	pkt = malloc(sizeof(struct cuda_packet), M_CUDA, M_WAITOK);
+	pkt->len = length - 1;
+	pkt->type = msg[0];
+	memcpy(pkt->data, &msg[1], pkt->len);
+
+	STAILQ_INSERT_TAIL(&sc->sc_outq, pkt, pkt_q);
+
+	/*
+	 * If we already are sending a packet, we should bail now that this
+	 * one has been added to the queue.
+	 */
+
+	if (sc->sc_waiting) {
+		mtx_unlock(&sc->sc_mutex);
+		return (0);
 	}
 
-	sc->sc_error = 0;
-	memcpy(sc->sc_out, msg, length);
-	sc->sc_out_length = length;
+	cuda_send_outbound(sc);
+	mtx_unlock(&sc->sc_mutex);
+
+	if (sc->sc_polling || poll || cold)
+		cuda_poll(dev);
+
+	return (0);
+}
+
+static void
+cuda_send_outbound(struct cuda_softc *sc)
+{
+	struct cuda_packet *pkt;
+
+	mtx_assert(&sc->sc_mutex, MA_OWNED);
+
+	pkt = STAILQ_FIRST(&sc->sc_outq);
+	if (pkt == NULL)
+		return;
+
+	sc->sc_out_length = pkt->len + 1;
+	memcpy(sc->sc_out, &pkt->type, pkt->len + 1);
 	sc->sc_sent = 0;
 
-	if (sc->sc_waiting != 1) {
-		DELAY(150);
+	free(pkt, M_CUDA);
+	STAILQ_REMOVE_HEAD(&sc->sc_outq, pkt_q);
+
+	sc->sc_waiting = 1;
+
+	cuda_poll(sc->sc_dev);
+
+	DELAY(150);
+
+	if (sc->sc_state == CUDA_IDLE && !cuda_intr_state(sc)) {
 		sc->sc_state = CUDA_OUT;
 		cuda_out(sc);
 		cuda_write_reg(sc, vSR, sc->sc_out[0]);
 		cuda_ack_off(sc);
 		cuda_tip(sc);
 	}
-	sc->sc_waiting = 1;
-	mtx_unlock(&sc->sc_mutex);
+}
 
-	if (sc->sc_polling || poll || cold) {
-		cuda_poll(dev);
+static void
+cuda_send_inbound(struct cuda_softc *sc)
+{
+	device_t dev;
+	struct cuda_packet *pkt;
+
+	dev = sc->sc_dev;
+	
+	mtx_lock(&sc->sc_mutex);
+
+	while ((pkt = STAILQ_FIRST(&sc->sc_inq)) != NULL) {
+		STAILQ_REMOVE_HEAD(&sc->sc_inq, pkt_q);
+
+		mtx_unlock(&sc->sc_mutex);
+
+		/* check if we have a handler for this message */
+		switch (pkt->type) {
+		   case CUDA_ADB:
+			if (pkt->len > 2) {
+				adb_receive_raw_packet(sc->adb_bus,
+				    pkt->data[0],pkt->data[1],
+				    pkt->len - 2,&pkt->data[2]);
+			} else {
+				adb_receive_raw_packet(sc->adb_bus,
+				    pkt->data[0],pkt->data[1],0,NULL);
+			}
+			break;
+		   case CUDA_PSEUDO:
+			mtx_lock(&sc->sc_mutex);
+			if (pkt->data[0] == CMD_AUTOPOLL)
+				sc->sc_autopoll = 1;
+			mtx_unlock(&sc->sc_mutex);
+			break;
+		   case CUDA_ERROR:
+			/*
+			 * CUDA will throw errors if we miss a race between
+			 * sending and receiving packets. This is already
+			 * handled when we abort packet output to handle
+			 * this packet in cuda_intr(). Thus, we ignore
+			 * these messages.
+			 */
+			break;
+		   default:
+			device_printf(dev,"unknown CUDA command %d\n",
+			    pkt->type);
+			break;
+		}
+
+		free(pkt,M_CUDA);
+
+		mtx_lock(&sc->sc_mutex);
 	}
 
-	return 0;
+	mtx_unlock(&sc->sc_mutex);
 }
 
 static void
@@ -382,8 +472,7 @@ cuda_poll(device_t dev)
 	    !sc->sc_waiting)
 		return;
 
-	if ((cuda_read_reg(sc, vIFR) & vSR_INT) == vSR_INT)
-		cuda_intr(dev);
+	cuda_intr(dev);
 }
 
 static void
@@ -392,7 +481,7 @@ cuda_intr(void *arg)
 	device_t        dev;
 	struct cuda_softc *sc;
 
-	int i, ending, type, restart_send;
+	int i, ending, restart_send, process_inbound;
 	uint8_t reg;
 
         dev = (device_t)arg;
@@ -401,7 +490,13 @@ cuda_intr(void *arg)
 	mtx_lock(&sc->sc_mutex);
 
 	restart_send = 0;
+	process_inbound = 0;
 	reg = cuda_read_reg(sc, vIFR);
+	if ((reg & vSR_INT) != vSR_INT) {
+		mtx_unlock(&sc->sc_mutex);
+		return;
+	}
+
 	cuda_write_reg(sc, vIFR, 0x7f);	/* Clear interrupt */
 
 switch_start:
@@ -450,13 +545,6 @@ switch_start:
 		} else
 			sc->sc_received++;
 
-		if (sc->sc_received > 3) {
-			if ((sc->sc_in[3] == CMD_IIC) && 
-			    (sc->sc_received > (sc->sc_i2c_read_len + 4))) {
-				ending = 1;
-			}
-		}
-
 		/* intr off means this is the last byte (end of frame) */
 		if (cuda_intr_state(sc) == 0) {
 			ending = 1;
@@ -465,42 +553,24 @@ switch_start:
 		}
 		
 		if (ending == 1) {	/* end of message? */
-			sc->sc_in[0] = sc->sc_received - 1;
+			struct cuda_packet *pkt;
 
 			/* reset vars and signal the end of this frame */
 			cuda_idle(sc);
 
-			/* check if we have a handler for this message */
-			type = sc->sc_in[1];
+			/* Queue up the packet */
+			pkt = malloc(sizeof(struct cuda_packet), M_CUDA, 
+			    M_WAITOK);
+
+			pkt->len = sc->sc_received - 2;
+			pkt->type = sc->sc_in[1];
+			memcpy(pkt->data, &sc->sc_in[2], pkt->len);
 
-			switch (type) {
-			   case CUDA_ADB:
-				if (sc->sc_received > 4) {
-					adb_receive_raw_packet(sc->adb_bus,
-					    sc->sc_in[2],sc->sc_in[3],
-					    sc->sc_received - 4,&sc->sc_in[4]);
-				} else {
-					adb_receive_raw_packet(sc->adb_bus,
-					    sc->sc_in[2],sc->sc_in[3],0,NULL);
-				}
-				break;
-			   case CUDA_PSEUDO:
-				if (sc->sc_in[3] == CMD_AUTOPOLL)
-					sc->sc_autopoll = 1;
-				break;
-			   case CUDA_ERROR:
-				device_printf(dev,"CUDA Error\n");
-				sc->sc_error = 1;
-				break;
-			   default:
-				device_printf(dev,"unknown CUDA command %d\n",
-				    type);
-				break;
-			}
+			STAILQ_INSERT_TAIL(&sc->sc_inq, pkt, pkt_q);
 
 			sc->sc_state = CUDA_IDLE;
-			
 			sc->sc_received = 0;
+			process_inbound = 1;
 
 			/*
 			 * If there is something waiting to be sent out,
@@ -526,6 +596,7 @@ switch_start:
 					DELAY(150);
 					goto switch_start;
 				}
+
 				/*
 				 * If we got here, it's ok to start sending
 				 * so load the first byte and tell the chip
@@ -558,7 +629,6 @@ switch_start:
 			break;
 		}
 		if (sc->sc_out_length == sc->sc_sent) {	/* check for done */
-
 			sc->sc_waiting = 0;	/* done writing */
 			sc->sc_state = CUDA_IDLE;	/* signal bus is idle */
 			cuda_in(sc);
@@ -579,14 +649,26 @@ switch_start:
 	}
 
 	mtx_unlock(&sc->sc_mutex);
+
+	if (process_inbound)
+		cuda_send_inbound(sc);
+
+	mtx_lock(&sc->sc_mutex);
+	/* If we have another packet waiting, set it up */
+	if (!sc->sc_waiting && sc->sc_state == CUDA_IDLE)
+		cuda_send_outbound(sc);
+
+	mtx_unlock(&sc->sc_mutex);
+
 }
 
 static u_int
-cuda_adb_send(device_t dev, u_char command_byte, int len, u_char *data, u_char poll)
+cuda_adb_send(device_t dev, u_char command_byte, int len, u_char *data, 
+    u_char poll)
 {
 	struct cuda_softc *sc = device_get_softc(dev);
-	int i;
 	uint8_t packet[16];
+	int i;
 
 	/* construct an ADB command packet and send it */
 	packet[0] = CUDA_ADB;
@@ -594,15 +676,9 @@ cuda_adb_send(device_t dev, u_char comma
 	for (i = 0; i < len; i++)
 		packet[i + 2] = data[i];
 
-	if (poll)
-		cuda_poll(dev);
-
 	cuda_send(sc, poll, len + 2, packet);
 
-	if (poll)
-		cuda_poll(dev);
-
-	return 0;
+	return (0);
 }
 
 static u_int 
@@ -615,17 +691,14 @@ cuda_adb_autopoll(device_t dev, uint16_t
 
 	if (cmd[2] == sc->sc_autopoll) {
 		mtx_unlock(&sc->sc_mutex);
-		return 0;
+		return (0);
 	}
 
-	while (sc->sc_state != CUDA_IDLE)
-		mtx_sleep(dev,&sc->sc_mutex,0,"cuda",1);
-
 	sc->sc_autopoll = -1;
-	cuda_send(sc, 0, 3, cmd);
+	cuda_send(sc, 1, 3, cmd);
 
 	mtx_unlock(&sc->sc_mutex);
-	
-	return 0;
+
+	return (0);
 }
 

Modified: head/sys/powerpc/powermac/cudavar.h
==============================================================================
--- head/sys/powerpc/powermac/cudavar.h	Sat Dec  6 23:00:48 2008	(r185723)
+++ head/sys/powerpc/powermac/cudavar.h	Sat Dec  6 23:26:02 2008	(r185724)
@@ -61,6 +61,16 @@
 #define CUDA_IN		0x4	/* receiving data */
 #define CUDA_POLLING	0x5	/* polling - II only */
 
+struct cuda_packet {
+	uint8_t len;
+	uint8_t type;
+
+	uint8_t data[253];
+	STAILQ_ENTRY(cuda_packet) pkt_q;
+};
+
+STAILQ_HEAD(cuda_pktq, cuda_packet);
+
 struct cuda_softc {
 	device_t	sc_dev;
 	int		sc_memrid;
@@ -73,22 +83,24 @@ struct cuda_softc {
 
 	device_t	adb_bus;
 
-	int sc_node;
-	volatile int sc_state;
-	int sc_waiting;
-	int sc_polling;
-	int sc_sent;
-	int sc_out_length;
-	int sc_received;
-	int sc_iic_done;
-	int sc_error;
-	volatile int sc_autopoll;
+	int		sc_node;
+	volatile int	sc_state;
+	int		sc_waiting;
+	int		sc_polling;
+	int		sc_iic_done;
+	volatile int	sc_autopoll;
 
 	int sc_i2c_read_len;
 
 	/* internal buffers */
-	uint8_t sc_in[256];
-	uint8_t sc_out[256];
+	uint8_t		sc_in[256];
+	uint8_t		sc_out[256];
+	int		sc_sent;
+	int		sc_out_length;
+	int		sc_received;
+
+	struct cuda_pktq sc_inq;
+	struct cuda_pktq sc_outq;
 };
 
 #endif /* _POWERPC_CUDAVAR_H_ */


More information about the svn-src-all mailing list