I tested this (the combined patches) with several of the different USB thumbdrives that I have and didn't have any problems. In fact it actually increased the pass rate of my failing Ubuntu booting problem from ~0% to ~50%, but I'll address that in that email stream.
dave ----- Original Message ----- > From: "Paolo Bonzini" <pbonz...@redhat.com> > To: "Kevin O'Connor" <ke...@koconnor.net> > Cc: seabios@seabios.org > Sent: Friday, March 16, 2012 11:54:46 AM > Subject: Re: [SeaBIOS] usb-msc.c: TEST_UNIT_READY needs USB_DIR_OUT? > > Il 15/03/2012 02:31, Kevin O'Connor ha scritto: > > On Wed, Mar 14, 2012 at 01:02:39PM -0600, Steve Goodrich wrote: > >> I've been working with coreboot and SeaBIOS lately to try to get a > >> platform > >> working, including having boot capability using an SD-to-USB > >> adapter. I got > >> stuck on this last part: the USB/SD adapter would start > >> enumeration, but > >> would fail out during TEST_UNIT_READY because the device came back > >> with a > >> STALL (this via a LeCroy/CACT USB analyzer). I compared the > >> transactions to > >> those done during USB enumeration/configuration in Linux, and I > >> noticed that > >> the Direction bit in bmCBWFlags is *cleared* for the > >> TEST_UNIT_READY command > >> in Linux, but *set* in coreboot. > > > > If Linux always clears the direction bit for zero length transfers, > > then I think it should be safe to do that in SeaBIOS also. How > > about > > the patch below? > > > > -Kevin > > > > > > From 1fd9a89082b807a4bb4ab6ce1285df474cb75746 Mon Sep 17 00:00:00 > > 2001 > > From: Kevin O'Connor <ke...@koconnor.net> > > Date: Wed, 14 Mar 2012 21:27:45 -0400 > > Subject: [PATCH] Use OUT mode for all zero byte "scsi" transfers. > > > > Some devices can get confused if asked to "read" data during a zero > > byte transfer, so consider these transfers as "writes". (Reported > > by > > Steve Goodrich.) > > > > Also, extract out the code to determine the transfer direction into > > cdb_is_read(). > > > > Signed-off-by: Kevin O'Connor <ke...@koconnor.net> > > --- > > src/blockcmd.c | 7 +++++++ > > src/blockcmd.h | 1 + > > src/usb-msc.c | 4 ++-- > > src/virtio-scsi.c | 7 ++++--- > > 4 files changed, 14 insertions(+), 5 deletions(-) > > > > diff --git a/src/blockcmd.c b/src/blockcmd.c > > index 8d881a5..2dda04d 100644 > > --- a/src/blockcmd.c > > +++ b/src/blockcmd.c > > @@ -35,6 +35,13 @@ cdb_cmd_data(struct disk_op_s *op, void *cdbcmd, > > u16 blocksize) > > } > > } > > > > +// Determine if the command is a request to pull data from the > > device > > +int > > +cdb_is_read(u8 *cdbcmd, u16 blocksize) > > +{ > > + return blocksize && cdbcmd[0] != CDB_CMD_WRITE_10; > > +} > > + > > int > > scsi_is_ready(struct disk_op_s *op) > > { > > diff --git a/src/blockcmd.h b/src/blockcmd.h > > index ccfeeaf..8459d3e 100644 > > --- a/src/blockcmd.h > > +++ b/src/blockcmd.h > > @@ -100,6 +100,7 @@ struct cdbres_mode_sense_geom { > > } PACKED; > > > > // blockcmd.c > > +int cdb_is_read(u8 *cdbcmd, u16 blocksize); > > int cdb_get_inquiry(struct disk_op_s *op, struct cdbres_inquiry > > *data); > > int cdb_get_sense(struct disk_op_s *op, struct > > cdbres_request_sense *data); > > int cdb_test_unit_ready(struct disk_op_s *op); > > diff --git a/src/usb-msc.c b/src/usb-msc.c > > index dadb9ca..c53a1f5 100644 > > --- a/src/usb-msc.c > > +++ b/src/usb-msc.c > > @@ -77,13 +77,13 @@ usb_cmd_data(struct disk_op_s *op, void > > *cdbcmd, u16 blocksize) > > cbw.dCBWSignature = CBW_SIGNATURE; > > cbw.dCBWTag = 999; // XXX > > cbw.dCBWDataTransferLength = bytes; > > - cbw.bmCBWFlags = (cbw.CBWCB[0] == CDB_CMD_WRITE_10) ? > > USB_DIR_OUT : USB_DIR_IN; > > + cbw.bmCBWFlags = cdb_is_read(cdbcmd, blocksize) ? USB_DIR_IN : > > USB_DIR_OUT; > > cbw.bCBWLUN = 0; // XXX > > cbw.bCBWCBLength = USB_CDB_SIZE; > > > > // Transfer cbw to device. > > int ret = usb_msc_send(udrive_g, USB_DIR_OUT > > - , MAKE_FLATPTR(GET_SEG(SS), &cbw), > > sizeof(cbw)); > > + , MAKE_FLATPTR(GET_SEG(SS), &cbw), > > sizeof(cbw)); > > if (ret) > > goto fail; > > > > diff --git a/src/virtio-scsi.c b/src/virtio-scsi.c > > index 3c59438..50339d7 100644 > > --- a/src/virtio-scsi.c > > +++ b/src/virtio-scsi.c > > @@ -31,7 +31,7 @@ struct virtio_lun_s { > > > > static int > > virtio_scsi_cmd(u16 ioaddr, struct vring_virtqueue *vq, struct > > disk_op_s *op, > > - void *cdbcmd, u16 target, u16 lun, u32 len) > > + void *cdbcmd, u16 target, u16 lun, u16 blocksize) > > { > > struct virtio_scsi_req_cmd req; > > struct virtio_scsi_resp_cmd resp; > > @@ -44,7 +44,8 @@ virtio_scsi_cmd(u16 ioaddr, struct > > vring_virtqueue *vq, struct disk_op_s *op, > > req.lun[3] = (lun & 0xff); > > memcpy(req.cdb, cdbcmd, 16); > > > > - int datain = (req.cdb[0] != CDB_CMD_WRITE_10); > > + u32 len = op->count * blocksize; > > + int datain = cdb_is_read(cdbcmd, blocksize); > > The patch changes the way TEST_UNIT_READY is composed in the > buffers and breaks virtio-scsi. Now I remember why I did it > this way. :) > > You can squash this in: > > diff --git a/src/virtio-scsi.c b/src/virtio-scsi.c > index 76c5f29..d03a562 100644 > --- a/src/virtio-scsi.c > +++ b/src/virtio-scsi.c > @@ -46,9 +46,8 @@ virtio_scsi_cmd(u16 ioaddr, struct vring_virtqueue > *vq, struct disk_op_s *op, > > u32 len = op->count * blocksize; > int datain = cdb_is_read(cdbcmd, blocksize); > - int data_idx = (datain ? 2 : 1); > - int out_num = (datain ? 1 : 2); > - int in_num = (len ? 3 : 2) - out_num; > + int in_num = (datain ? 2 : 1); > + int out_num = (len ? 3 : 2) - in_num; > > sg[0].addr = MAKE_FLATPTR(GET_SEG(SS), &req); > sg[0].length = sizeof(req); > @@ -56,8 +56,11 @@ virtio_scsi_cmd(u16 ioaddr, struct vring_virtqueue > *vq, struct disk_op_s *op, > sg[out_num].addr = MAKE_FLATPTR(GET_SEG(SS), &resp); > sg[out_num].length = sizeof(resp); > > - sg[data_idx].addr = op->buf_fl; > - sg[data_idx].length = len; > + if (len) { > + int data_idx = (datain ? 2 : 1); > + sg[data_idx].addr = op->buf_fl; > + sg[data_idx].length = len; > + } > > /* Add to virtqueue and kick host */ > vring_add_buf(vq, sg, out_num, in_num, 0, 0); > > and apply the patch. > > Thanks! > > Paolo > > _______________________________________________ > SeaBIOS mailing list > SeaBIOS@seabios.org > http://www.seabios.org/mailman/listinfo/seabios > _______________________________________________ SeaBIOS mailing list SeaBIOS@seabios.org http://www.seabios.org/mailman/listinfo/seabios