Subject: kern/34202 (Accessing cd device on alpha causes kernel trap)
To: None <current-users@netbsd.org>
From: Dave Huang <khym@azeotrope.org>
List: current-users
Date: 11/26/2006 00:55:57
Well, no response for months on this, so I looked into it myself...
the problem is in:

static int
read_cd_capacity(struct scsipi_periph *periph, u_int *blksize, u_long *size)
{
	struct scsipi_read_cd_capacity    cap_cmd;
	struct scsipi_read_cd_cap_data    cap;
	struct scsipi_read_discinfo       di_cmd;
	struct scsipi_read_discinfo_data  di;
	struct scsipi_read_trackinfo      ti_cmd;
	struct scsipi_read_trackinfo_data ti;

All of those structs consist solely of u_int8_t members and arrays of
u_int8_t, and it looks like gcc4 packs those on the stack as tightly
as possible. On a test run on my system, the structs were placed at
these addresses:

...f9: ti
...d6: di
...cc: cap_cmd
...c2: di_cmd
...b8: ti_cmd
...b0: cap

Since struct scsipi_read_discinfo_data is an odd number of bytes long
(35 bytes), ti ends up being unaligned. wdc_datain_pio() uses
bus_space_read_multi_4() to read the response from the drive, and
since ti is unaligned, it causes an unaligned access fault.

I don't know what the correct fix for this is, but adding the
aligned(4) attribute to struct scsipi_read_trackinfo_data seems to
work. If adding the attribute is the right thing to do, perhaps it
should be added to all of the scsipi structs?

Index: dev/scsipi/scsipi_cd.h
===================================================================
RCS file: /cvsroot/src/sys/dev/scsipi/scsipi_cd.h,v
retrieving revision 1.14
diff -u -r1.14 scsipi_cd.h
--- dev/scsipi/scsipi_cd.h	20 Dec 2005 01:44:22 -0000	1.14
+++ dev/scsipi/scsipi_cd.h	26 Nov 2006 05:36:47 -0000
@@ -237,7 +237,7 @@
 	uint8_t  track_msb;
 	uint8_t  session_msb;
 	uint8_t  unused2[2];
-} __attribute__((packed));
+} __attribute__((packed, aligned(4)));
 #define READ_TRACKINFO_RETURNSIZE 36
 
-- 
Name: Dave Huang         |  Mammal, mammal / their names are called /
INet: khym@azeotrope.org |  they raise a paw / the bat, the cat /
FurryMUCK: Dahan         |  dolphin and dog / koala bear and hog -- TMBG
Dahan: Hani G Y+C 31 Y++ L+++ W- C++ T++ A+ E+ S++ V++ F- Q+++ P+ B+ PA+ PL++