freebsd-skq/sys/cam
ken 60f9c7106b Probable fix for the "cdda2wav" panics that various people have been
reporting since this past summer.  (I think Daniel O'Conner was the first.)

The problem appears to have been something like this:

 - cdda2wav by default passes in a buffer that is close to the 128K MAXPHYS
   limit.
 - many times, the buffer is not page aligned
 - vmapbuf() truncates the address, so that it is page aligned
 - that causes the total size of the buffer to be greater than MAXPHYS,
   which of course is a bad thing.

Here's a quote from the PR (kern/9067):

==================
In particular, note bp->b_bufsize = 0x0001f950 and bp->b_data = 0xf2219960
(which does not start on a page boundary).  vunmapbuf() loops through all
the pages without any difficulty until addr reaches 0xf2239000, and then
the panic occurs.  This seems to indicate that we are exceeding MAXPHYS
since we actually started from the middle of a page (the data is being
transfered to a non page aligned location).

To complete the description, note that the system call originates from
ReadCddaMMC12() (in scsi_cmds.c of cdda2wav) with a request to read 55
audio sectors of 2352 bytes (which is calculated to fall under MAXPHYS).
This in turn ends up calling scsi_send() (in scsi-bsd.c) which calls
cam_fill_csio() and cam_send_ccb().  This results in a CAMIOCOMMAND ioctl
with a ccb function code of XPT_SCSI_IO.
==================

The fix is to change the size check in cam_periph_mapmem() so that it is
like the one in minphys().  In particular, it is something like:

if ((buffer_length + (buf_ptr & PAGE_MASK)) > MAXPHYS)
	buffer is too big

My fix is based on the one in the PR, but I cleaned up a fair number of
things in cam_periph_mapmem().  The checks for each buffer to be mapped
are now in a separate loop from the actual mapping operation.  With the new
arrangement, we don't have to bother with unmapping any previously mapped
buffers if one of the checks fails.

Many thanks to James Liu for tracking this down.  I'd appreciate it if some
vm-savvy folks would look this over.  I believe this fix is correct, but I
could be wrong.

PR:		kern/9067 (also, kern/8112)
Reviewed by:	gibbs
Submitted by:	"James T. Liu" <jtliu@phlebas.rockefeller.edu>
1998-12-16 18:00:39 +00:00
..
scsi Enable/Disable our lun on open/close. Track resources kept at the controller 1998-12-15 08:15:15 +00:00
cam_ccb.h Expand the hba_misc fied in the Path Inquiry ccb to allow a controller driver 1998-12-10 04:05:49 +00:00
cam_conf.h CAM Transport Layer (XPT). 1998-09-15 06:33:23 +00:00
cam_debug.h Add a CAM_DEBUG_XPT define (to debug XPT layer only). Add a CAM_DEBUGGED 1998-12-05 23:55:48 +00:00
cam_extend.c CAM Transport Layer (XPT). 1998-09-15 06:33:23 +00:00
cam_extend.h CAM Transport Layer (XPT). 1998-09-15 06:33:23 +00:00
cam_periph.c Probable fix for the "cdda2wav" panics that various people have been 1998-12-16 18:00:39 +00:00
cam_periph.h Fix a problem with the way we handled device invalidation when attaching 1998-10-22 22:16:56 +00:00
cam_queue.c CAM Transport Layer (XPT). 1998-09-15 06:33:23 +00:00
cam_queue.h Add definitions for TAILQ, LIST, and SLIST ccb_hdr queues. 1998-12-15 08:12:03 +00:00
cam_sim.c CAM Transport Layer (XPT). 1998-09-15 06:33:23 +00:00
cam_sim.h CAM Transport Layer (XPT). 1998-09-15 06:33:23 +00:00
cam_xpt_periph.h CAM Transport Layer (XPT). 1998-09-15 06:33:23 +00:00
cam_xpt_sim.h CAM Transport Layer (XPT). 1998-09-15 06:33:23 +00:00
cam_xpt.c Wire up the XPT_ABORT and XPT_RESET_DEV ccb function codes so they can 1998-12-15 08:13:10 +00:00
cam_xpt.h CAM Transport Layer (XPT). 1998-09-15 06:33:23 +00:00
cam.c cam.c: 1998-09-22 04:53:23 +00:00
cam.h CAM Transport Layer (XPT). 1998-09-15 06:33:23 +00:00