Subject: Re: kern/34202
To: None <kern-bug-people@netbsd.org, gnats-admin@netbsd.org,>
From: Dave Huang <khym@azeotrope.org>
List: netbsd-bugs
Date: 11/29/2006 20:42:11
The following reply was made to PR kern/34202; it has been noted by GNATS.

From: Dave Huang <khym@azeotrope.org>
To: gnats-bugs@netbsd.org
Cc: 
Subject: Re: kern/34202
Date: Sun, 26 Nov 2006 00:12:05 -0600

 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