Author: nwhitehorn
Date: Sun Sep 29 20:10:22 2013
New Revision: 255943
URL: http://svnweb.freebsd.org/changeset/base/255943

Log:
  Changes to CAM or busdma have caused SIMs to be sent 0-length CCBs on
  occasion. This resulted in zero mapped segments, triggering an assert in
  the PS3 CDROM driver. Allow no DMA for 0-length transfers.
  
  Approved by:  re (glebius)
  MFC after:    1 week

Modified:
  head/sys/powerpc/ps3/ps3cdrom.c

Modified: head/sys/powerpc/ps3/ps3cdrom.c
==============================================================================
--- head/sys/powerpc/ps3/ps3cdrom.c     Sun Sep 29 18:07:14 2013        
(r255942)
+++ head/sys/powerpc/ps3/ps3cdrom.c     Sun Sep 29 20:10:22 2013        
(r255943)
@@ -557,7 +557,9 @@ ps3cdrom_transfer(void *arg, bus_dma_seg
        uint64_t start_sector, block_count;
        int err;
 
-       KASSERT(nsegs == 1, ("invalid number of DMA segments"));
+       KASSERT(nsegs == 1 || nsegs == 0,
+           ("ps3cdrom_transfer: invalid number of DMA segments %d", nsegs));
+       KASSERT(error == 0, ("ps3cdrom_transfer: DMA error %d", error));
 
        PS3CDROM_ASSERT_LOCKED(sc);
 
@@ -581,6 +583,7 @@ ps3cdrom_transfer(void *arg, bus_dma_seg
 
        switch (cdb[0]) {
        case READ_10:
+               KASSERT(nsegs == 1, ("ps3cdrom_transfer: no data to read"));
                start_sector = (cdb[2] << 24) | (cdb[3] << 16) |
                    (cdb[4] << 8) | cdb[5];
                block_count = (cdb[7] << 8) | cdb[8];
@@ -592,6 +595,7 @@ ps3cdrom_transfer(void *arg, bus_dma_seg
                    BUS_DMASYNC_POSTREAD);
                break;
        case WRITE_10:
+               KASSERT(nsegs == 1, ("ps3cdrom_transfer: no data to write"));
                start_sector = (cdb[2] << 24) | (cdb[3] << 16) |
                    (cdb[4] << 8) | cdb[5];
                block_count = (cdb[7] << 8) | cdb[8];
@@ -622,9 +626,10 @@ ps3cdrom_transfer(void *arg, bus_dma_seg
                        atapi_cmd.proto = NON_DATA_PROTO;
                }
 
-               atapi_cmd.nblocks = atapi_cmd.arglen = segs[0].ds_len;
+               atapi_cmd.nblocks = atapi_cmd.arglen =
+                   (nsegs == 0) ? 0 : segs[0].ds_len;
                atapi_cmd.blksize = 1;
-               atapi_cmd.buf = segs[0].ds_addr;
+               atapi_cmd.buf = (nsegs == 0) ? 0 : segs[0].ds_addr;
 
                if (ccb->ccb_h.flags & CAM_DIR_OUT)
                        bus_dmamap_sync(sc->sc_dmatag, xp->x_dmamap,
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to