From dillon@flea.best.net  Thu Dec 11 11:19:58 1997
Received: from flea.best.net (root@flea.best.net [206.184.139.131])
          by hub.freebsd.org (8.8.7/8.8.7) with ESMTP id LAA06753
          for <FreeBSD-gnats-submit@freebsd.org>; Thu, 11 Dec 1997 11:19:58 -0800 (PST)
          (envelope-from dillon@flea.best.net)
Received: (from dillon@localhost) by flea.best.net (8.8.8/8.7.3) id LAA05901; Thu, 11 Dec 1997 11:19:29 -0800 (PST)
Message-Id: <199712111919.LAA05901@flea.best.net>
Date: Thu, 11 Dec 1997 11:19:29 -0800 (PST)
From: Matt Dillon <dillon@best.net>
Reply-To: dillon@best.net
To: FreeBSD-gnats-submit@freebsd.org
Subject: SCSI tape compression setting fails (with fix)
X-Send-Pr-Version: 3.2

>Number:         5274
>Category:       kern
>Synopsis:       [PATCH] mt comp 0/1 does not work, with fix
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    gibbs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Thu Dec 11 11:20:01 PST 1997
>Closed-Date:    Mon Nov 2 11:43:48 PST 1998
>Last-Modified:  Mon Nov  2 11:44:16 PST 1998
>Originator:     Matt Dillon
>Release:        FreeBSD 2.2.5-STABLE i386
>Organization:
BEST Internet Communications
>Environment:

	FreeBSD 2.2.5, SCSI-II tape library / Exabyte tapes

>Description:

	The 'mt comp 0/1' command fails because it is sending a SCSI-II
	page without setting the PF bit in byte2, causing the tape unit 
	to interpret the command as SCSI-I.

	Note: my fix below does not double-check that the SCSI tape unit
	is returning a SCSI-II page for the mode sense of the configuration
	page, but compression didn't work at all before so this should be
	an improvement.

>How-To-Repeat:

	Attempt to turn on or off compression on a SCSI tape unit.

>Fix:
	

*** LINK/st.c	Wed Sep 17 15:09:25 1997
--- st.c	Thu Dec 11 11:09:21 1997
***************
*** 81,87 ****
  static errval	st_write_filemarks __P((u_int32_t unit, int32_t number, u_int32_t flags));
  static errval	st_load __P((u_int32_t unit, u_int32_t type, u_int32_t flags));
  static errval	st_mode_select __P((u_int32_t unit, u_int32_t flags, \
! 	struct tape_pages *page, u_int32_t pagelen));
  static errval	st_comp __P((u_int32_t unit, u_int32_t mode));
  static int32_t	st_chkeod __P((u_int32_t unit, boolean position, int32_t *nmarks,
  	u_int32_t flags));
--- 81,87 ----
  static errval	st_write_filemarks __P((u_int32_t unit, int32_t number, u_int32_t flags));
  static errval	st_load __P((u_int32_t unit, u_int32_t type, u_int32_t flags));
  static errval	st_mode_select __P((u_int32_t unit, u_int32_t flags, \
! 	struct tape_pages *page, u_int32_t pagelen, u_int32_t byte2));
  static errval	st_comp __P((u_int32_t unit, u_int32_t mode));
  static int32_t	st_chkeod __P((u_int32_t unit, boolean position, int32_t *nmarks,
  	u_int32_t flags));
***************
*** 579,585 ****
  			return errno;
  		}
  	}
! 	if ( (errno = st_mode_select(unit, 0, NULL, 0)) ) {
  		printf("st%ld: Cannot set selected mode", unit);
  		return errno;
  	}
--- 579,585 ----
  			return errno;
  		}
  	}
! 	if ( (errno = st_mode_select(unit, 0, NULL, 0, 0)) ) {
  		printf("st%ld: Cannot set selected mode", unit);
  		return errno;
  	}
***************
*** 1148,1154 ****
  	 * Check that the mode being asked for is aggreeable to the
  	 * drive. If not, put it back the way it was.
  	 */
! 	if ( (errcode = st_mode_select(unit, 0, NULL, 0)) ) {	/* put back as it was */
  		printf("st%ld: Cannot set selected mode", unit);
  		st->density = hold_density;
  		st->blksiz = hold_blksiz;
--- 1148,1154 ----
  	 * Check that the mode being asked for is aggreeable to the
  	 * drive. If not, put it back the way it was.
  	 */
! 	if ( (errcode = st_mode_select(unit, 0, NULL, 0, 0)) ) {	/* put back as it was */
  		printf("st%ld: Cannot set selected mode", unit);
  		st->density = hold_density;
  		st->blksiz = hold_blksiz;
***************
*** 1371,1380 ****
   * set it into the desire modes etc.
   */
  static	errval
! st_mode_select(unit, flags, page, pagelen)
  	u_int32_t unit, flags;
  	struct tape_pages *page;
  	u_int32_t pagelen;
  {
  	u_int32_t dat_len;
  	struct scsi_mode_select scsi_cmd;
--- 1371,1381 ----
   * set it into the desire modes etc.
   */
  static	errval
! st_mode_select(unit, flags, page, pagelen, byte2)
  	u_int32_t unit, flags;
  	struct tape_pages *page;
  	u_int32_t pagelen;
+ 	u_int32_t byte2;
  {
  	u_int32_t dat_len;
  	struct scsi_mode_select scsi_cmd;
***************
*** 1407,1412 ****
--- 1408,1414 ----
  	bzero(&scsi_cmd, sizeof(scsi_cmd));
  	scsi_cmd.op_code = MODE_SELECT;
  	scsi_cmd.length = dat_len;
+ 	scsi_cmd.byte2 = (u_char)byte2;
  	dat.header.blk_desc_len = sizeof(struct blk_desc);
  	dat.header.dev_spec |= SMH_DSP_BUFF_MODE_ON;
  	dat.blk_desc.density = st->density;
***************
*** 1475,1481 ****
  		printf("st%ld: bad value for compression mode\n",unit);
  		return EINVAL;
  	}
! 	if ( (retval = st_mode_select(unit, 0, &page, pagesize)) )
  	{
  		printf("select returned an error of %d\n",retval);
  		return retval;
--- 1477,1489 ----
  		printf("st%ld: bad value for compression mode\n",unit);
  		return EINVAL;
  	}
! 
! 	/*
! 	 * send ST_PAGE_CONFIGURATION page as SCSI-II command because it
! 	 * is a SCSI-II structure.  This requires the PF bit (0x10) to be
! 	 * set for byte2.
! 	 */
! 	if ( (retval = st_mode_select(unit, 0, &page, pagesize, 0x10)) )
  	{
  		printf("select returned an error of %d\n",retval);
  		return retval;
***************
*** 1934,1940 ****
  		default:
  			readsiz = 1;
  			st->flags &= ~ST_FIXEDBLOCKS;
! 		} if ( (errno = st_mode_select(unit, 0, NULL, 0)) ) {
  			goto bad;
  		}
  		st_read(unit, buf, readsiz, SCSI_SILENT);
--- 1942,1948 ----
  		default:
  			readsiz = 1;
  			st->flags &= ~ST_FIXEDBLOCKS;
! 		} if ( (errno = st_mode_select(unit, 0, NULL, 0, 0)) ) {
  			goto bad;
  		}
  		st_read(unit, buf, readsiz, SCSI_SILENT);
>Release-Note:
>Audit-Trail:
State-Changed-From-To: open->suspended 
State-Changed-By: phk 
State-Changed-When: Wed May 27 02:43:17 PDT 1998 
State-Changed-Why:  
This will probably be a "CAM" thing before it gets fixed. 


Responsible-Changed-From-To: freebsd-bugs->gibbs 
Responsible-Changed-By: phk 
Responsible-Changed-When: Wed May 27 02:43:17 PDT 1998 
Responsible-Changed-Why:  
. 
State-Changed-From-To: suspended->closed 
State-Changed-By: gibbs 
State-Changed-When: Mon Nov 2 11:43:48 PST 1998 
State-Changed-Why:  
The SA driver in CAM has support for this feature. 
>Unformatted:
