1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-15 10:17:20 +00:00

cd.c: Julian's CD audio cleanup

sd.c: Julian's removal of subdriver requests
st.c, scsi_tape.h: Julian's suport of compressed tape drives

Note: compressed tape drives are still not working fully.

scsiconf.h, scsi_base.c, scsi_driver.c: address problems in probes
and error console logs
This commit is contained in:
Peter Dufault 1995-03-21 11:21:08 +00:00
parent bc9ad24756
commit 3358f19c6e
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=7216
8 changed files with 362 additions and 185 deletions

View File

@ -14,7 +14,7 @@
*
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
* $Id: cd.c,v 1.35 1995/03/04 20:50:42 dufault Exp $
* $Id: cd.c,v 1.36 1995/03/15 14:22:03 dufault Exp $
*/
#define SPLCD splbio
@ -71,8 +71,6 @@ void cdstart(u_int32 unit);
struct scsi_data {
u_int32 flags;
#define CDINIT 0x04 /* device has been init'd */
u_int32 ad_info; /* info about the adapter */
u_int32 cmdscount; /* cmds allowed outstanding by board */
struct cd_parms {
u_int32 blksize;
u_long disksize; /* total number sectors */
@ -179,16 +177,8 @@ cdattach(struct scsi_link *sc_link)
unit = sc_link->dev_unit;
dp = &(cd->params);
if (sc_link->adapter->adapter_info) {
cd->ad_info = ((*(sc_link->adapter->adapter_info)) (sc_link->adapter_unit));
cd->cmdscount = cd->ad_info & AD_INF_MAX_CMDS;
if (cd->cmdscount > CDOUTSTANDING)
cd->cmdscount = CDOUTSTANDING;
} else {
cd->ad_info = 1;
cd->cmdscount = 1;
}
sc_link->opennings = cd->cmdscount;
if (sc_link->opennings > CDOUTSTANDING)
sc_link->opennings = CDOUTSTANDING;
/*
* Use the subdriver to request information regarding
* the drive. We cannot use interrupts yet, so the
@ -232,6 +222,15 @@ struct scsi_link *sc_link)
SC_DEBUG(sc_link, SDEV_DB1,
("cd_open: dev=0x%x (unit %d,partition %d)\n",
dev, unit, part));
/*
* Check that it is still responding and ok.
* if the media has been changed this will result in a
* "unit attention" error which the error code will
* disregard because the SDEV_OPEN flag is not yet set.
* Makes sure that we know it if the media has been changed..
*/
scsi_test_unit_ready(sc_link, SCSI_SILENT);
/*
* If it's been invalidated, and not everybody has closed it then
* forbid re-entry. (may have changed media)
@ -241,15 +240,7 @@ struct scsi_link *sc_link)
return (ENXIO);
/*
* Check that it is still responding and ok.
* if the media has been changed this will result in a
* "unit attention" error which the error code will
* disregard because the SDEV_OPEN flag is not yet set
*/
scsi_test_unit_ready(sc_link, SCSI_SILENT);
/*
* Next time actually take notice of error returns
* This time actually take notice of error returns
*/
sc_link->flags |= SDEV_OPEN; /* unit attn errors are now errors */
if (scsi_test_unit_ready(sc_link, SCSI_SILENT) != 0) {
@ -261,10 +252,11 @@ struct scsi_link *sc_link)
/*
* In case it is a funny one, tell it to start
* not needed for some drives
* failure here is ignored.
*/
scsi_start_unit(sc_link, CD_START);
scsi_prevent(sc_link, PR_PREVENT, SCSI_SILENT);
SC_DEBUG(sc_link, SDEV_DB3, ("started "));
SC_DEBUG(sc_link, SDEV_DB3, ("'start' attempted "));
/*
* Load the physical device parameters
*/
@ -281,28 +273,32 @@ struct scsi_link *sc_link)
/*
* Check the partition is legal
*/
if ((part >= cd->disklabel.d_npartitions)
&& (part != RAW_PART)) {
SC_DEBUG(sc_link, SDEV_DB3, ("partition %d > %d\n", part
,cd->disklabel.d_npartitions));
errcode = ENXIO;
goto bad;
}
/*
* Check that the partition exists
*/
if ((cd->disklabel.d_partitions[part].p_fstype == FS_UNUSED)
&& (part != RAW_PART)) {
SC_DEBUG(sc_link, SDEV_DB3, ("part %d type UNUSED\n", part));
errcode = ENXIO;
goto bad;
if(part != RAW_PART) {
/*
* Check that the partition CAN exist
*/
if (part >= cd->disklabel.d_npartitions) {
SC_DEBUG(sc_link, SDEV_DB3, ("partition %d > %d\n", part
,cd->disklabel.d_npartitions));
errcode = ENXIO;
goto bad;
}
/*
* and that it DOES exist
*/
if (cd->disklabel.d_partitions[part].p_fstype == FS_UNUSED) {
SC_DEBUG(sc_link, SDEV_DB3,
("part %d type UNUSED\n", part));
errcode = ENXIO;
goto bad;
}
}
cd->partflags[part] |= CDOPEN;
cd->openparts |= (1 << part);
SC_DEBUG(sc_link, SDEV_DB3, ("open complete\n"));
sc_link->flags |= SDEV_MEDIA_LOADED;
return 0;
bad:
bad:
/*
* if we would have been the only open

View File

@ -8,7 +8,7 @@
* file.
*
* Written by Julian Elischer (julian@dialix.oz.au)
* $Id: scsi_base.c,v 1.22 1995/03/15 14:22:05 dufault Exp $
* $Id: scsi_base.c,v 1.23 1995/03/15 14:44:01 dufault Exp $
*/
#define SPLSD splbio
@ -646,7 +646,7 @@ sc_err1(xs)
/*
* scsi_sense_print will decode the sense data into human
* readable form. Sense handlers can use this to generate
* a report. This DOES NOT send the closing "\n".
* a report. This NOW DOES send the closing "\n".
*/
void scsi_sense_print(xs)
struct scsi_xfer *xs;
@ -727,7 +727,15 @@ void scsi_sense_print(xs)
ascq = (ext->extra_len >= 6) ? ext->add_sense_code_qual : 0;
if (asc || ascq)
printf(" asc:%x,%x %s", asc, ascq, scsi_sense_desc(asc, ascq));
{
char *desc = scsi_sense_desc(asc, ascq);
printf(" asc:%x,%x", asc, ascq);
if (strlen(desc) > 40)
sc_print_addr(xs->sc_link);;
printf("%s", desc);
}
if (ext->extra_len >= 7 && ext->fru) {
printf(" fru:%x", ext->fru);
@ -754,6 +762,8 @@ void scsi_sense_print(xs)
((unsigned long)sense->ext.unextended.blocklow));
}
}
printf("\n");
}
/*
@ -840,7 +850,6 @@ scsi_interpret_sense(xs)
if (!silent) {
scsi_sense_print(xs);
printf("\n");
}
switch (sense->error_code & SSD_ERRCODE) {
@ -849,7 +858,6 @@ scsi_interpret_sense(xs)
*/
if (silent) {
scsi_sense_print(xs);
printf("\n");
}
/* BUG:
@ -999,6 +1007,21 @@ scsi_4btou(bytes)
return rc;
}
static sc_printing;
void
sc_print_start(sc_link)
struct scsi_link *sc_link;
{
sc_print_addr(sc_link);
sc_printing = 1;
}
void
sc_print_finish()
{
sc_printing = 0;
}
/*
* Print out the scsi_link structure's address info.
*/
@ -1007,6 +1030,9 @@ void
sc_print_addr(sc_link)
struct scsi_link *sc_link;
{
if (sc_printing)
printf("\n");
if (strcmp(sc_link->device->name, "probe") != 0)
printf("%s%d", sc_link->device->name, sc_link->dev_unit);

View File

@ -35,7 +35,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: scsi_driver.c,v 1.5 1995/03/15 14:22:06 dufault Exp $
* $Id: scsi_driver.c,v 1.6 1995/03/16 18:15:48 bde Exp $
*
*/
#include <sys/types.h>
@ -46,6 +46,8 @@
#include <sys/devconf.h>
#include <sys/malloc.h>
#include <machine/cpu.h> /* XXX For bootverbose (funny place) */
#include <scsi/scsi_all.h>
#include <scsi/scsiconf.h>
#include <scsi/scsi_driver.h>
@ -73,10 +75,14 @@ int scsi_device_attach(struct scsi_link *sc_link)
dev_t dev;
struct scsi_device *device = sc_link->device;
if (bootverbose) {
sc_link->flags |= SDEV_BOOTVERBOSE;
}
SC_DEBUG(sc_link, SDEV_DB2,
("%s%dattach: ", device->name, sc_link->dev_unit));
sc_print_addr(sc_link);
sc_print_start(sc_link);
printf("%s ", device->desc);
dev = scsi_dev_lookup(device->open);
@ -87,6 +93,7 @@ int scsi_device_attach(struct scsi_link *sc_link)
errcode = (device->attach) ? (*(device->attach))(sc_link) : 0;
sc_print_finish();
printf("\n");
if (errcode == 0)

View File

@ -21,7 +21,7 @@
/*
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
* $Id: scsi_tape.h,v 1.9 1994/09/28 20:16:42 se Exp $
* $Id: scsi_tape.h,v 1.10 1994/10/28 13:19:34 jkh Exp $
*/
#ifndef SCSI_SCSI_TAPE_H
#define SCSI_SCSI_TAPE_H 1
@ -156,6 +156,94 @@ struct blk_desc_cipher
#define SR150_AUI 0x02 /* autoload inhibit */
};
/*
* This structure defines the various mode pages that tapes know about.
*/
#define PAGE_HEADERLEN 2
struct tape_pages
{
u_char pg_code; /* page code */
#define ST_PAGE_CONFIGURATION 0x10
#define ST_PAGE_MEDIUM_PART 0x11
#define ST_PAGE_MEDIUM_PART2 0x12
#define ST_PAGE_MEDIUM_PART3 0x13
#define ST_PAGE_MEDIUM_PART4 0x14
#define ST_P_CODE 0x3F /* page code */
#define ST_P_PS 0x80 /* page savable */
u_char pg_length; /* page length */
union
{
struct
{
u_char active_format; /* active format for density*/
#define ST_P_CAP 0x40 /* change active Partition */
#define ST_P_CAF 0x20 /* change active format */
#define ST_P_AF 0x1F /* active format */
u_char active_partition; /* */
u_char write_buffer_full_ratio; /* highwater writing*/
u_char read_buffer_empty_ratio; /* lowwater reading*/
u_char write_delay_high; /* # 100mSecs before flush*/
u_char write_delay_low; /* of buffer to the media */
u_char flags1; /* various single bit flags */
#define ST_P_DBR 0x80 /* supports data-buffer recovery */
#define ST_P_BIS 0x40 /* supports Block_ID */
#define ST_P_RSmk 0x20 /* Reports setmarks during reads and spaces */
#define ST_P_AVC 0x10 /* Supports Automatic Velocity Control */
#define ST_P_SOCF 0x0C /* Stop On Consecutive Filemarks, */
#define ST_P_RBO 0x02 /* Recoverd Buffered Data order, 1 = LIFO */
#define ST_P_REW 0x01 /* Report Early Warning (see SEW) */
u_char gap_size; /*I/B gap, 1=min 0=default */
u_char flags2; /* various single bit flags */
#define ST_P_EOD 0xE0 /* What is and EOD....*/
#define ST_P_EOD_DEF 0x00 /* Drive's default */
#define ST_P_EOD_FMT 0x20 /* define by format */
#define ST_P_EOD_SOCF 0x40 /* define by SOCF (above) */
#define ST_P_EEG 0x10 /* use EOD above */
#define ST_P_SEW 0x04 /* Synchronise at Early warning.. flush buffers*/
u_char early_warn_high;/* buf size at early warning */
u_char early_warn_med; /* after early warning, only */
u_char early_warn_low; /* buufer this much data */
u_char data_compress_alg; /* 0 = off, 1 = default */
u_char reserved; /* The standard says so */
} configuration;
struct
{
#define ST_MAXPARTS 16 /*for now*/
u_char max_add_parts; /* that drive allows */
u_char parts_defined; /* max min(ST_MAXPARTS,max_add_parts) */
u_char flags;
#define ST_P_FDP 0x80
#define ST_P_SDP 0x40
#define ST_P_IDP 0x20
#define ST_P_PSUM 0x18 /* units of part defs.. */
#define ST_P_PSUM_BYTES 0x0 /* units of part defs.. */
#define ST_P_PSUM_KBYTES 0x08 /* units of part defs.. */
#define ST_P_PSUM_MBYTES 0x10 /* units of part defs.. */
u_char medium_format_recog;
#define ST_P_REC_NONE 0x00
#define ST_P_REC_FMT 0x01 /* can recognise format of new media */
#define ST_P_REC_PART 0x02 /* can recognise partitions of new media */
#define ST_P_REC_FMT_PART 0x03 /* can recognise format and parts */
u_char reserved1;
u_char reserved2;
struct
{
u_char high;
u_char low;
}part[ST_MAXPARTS];
} medium_partition;
struct
{
struct
{
u_char high;
u_char low;
}part[ST_MAXPARTS];
} medium_partition_extra;
}pages;
};
#ifndef NEW_SCSICONF

View File

@ -16,7 +16,7 @@
*
* New configuration setup: dufault@hda.com
*
* $Id: scsiconf.c,v 1.24 1995/03/16 18:15:49 bde Exp $
* $Id: scsiconf.c,v 1.25 1995/03/19 14:29:06 davidg Exp $
*/
#include <sys/types.h>
@ -473,9 +473,10 @@ scsi_init(void)
}
/* Feel free to take this out when everyone is sure this config
* code works well:
* code works well. For now it lets us tell new configurations from
* old ones.
*/
#define CONFIGD() printf(" is configured at ")
#define CONFIG_NOISE
/* scsi_bus_conf: Figure out which bus this is. If it is wired in config
* use that. Otherwise use the next free one.
@ -492,7 +493,6 @@ scsi_bus_conf(sc_link_proto)
* next available bus.
*/
printf("scbus");
bus = SCCONF_UNSPEC;
for (i = 0; scsi_cinit[i].driver; i++) {
if (IS_SPECIFIED(scsi_cinit[i].unit))
@ -500,8 +500,10 @@ scsi_bus_conf(sc_link_proto)
if (!strcmp(sc_link_proto->adapter->name, scsi_cinit[i].driver) &&
(sc_link_proto->adapter_unit == scsi_cinit[i].unit) )
{
CONFIGD();
bus = scsi_cinit[i].bus;
#ifdef CONFIG_NOISE
printf("Choosing drivers for scbus configured at %d\n", bus);
#endif
break;
}
}
@ -510,8 +512,6 @@ scsi_bus_conf(sc_link_proto)
if (bus == SCCONF_UNSPEC)
bus = free_bus++;
printf("%d: ", bus);
return bus;
}
@ -535,7 +535,7 @@ scsi_assign_unit(struct scsi_link *sc_link)
sc_link->scsibus == scsi_dinit[i].cunit) {
sc_link->dev_unit = scsi_dinit[i].unit;
found = 1;
#ifdef CONFIGD
#ifdef CONFIG_NOISE
printf("%s is configured at %d\n",
sc_link->device->name, sc_link->dev_unit);
#endif
@ -565,6 +565,13 @@ scsi_attachdevs(sc_link_proto)
if ( (scsibus = scsi_bus_conf(sc_link_proto)) == -1) {
return;
}
/*
* if the adapter didn't give us this, set a default
* (compatibility with old adapter drivers)
*/
if(!(sc_link_proto->opennings)) {
sc_link_proto->opennings = 1;
}
sc_link_proto->scsibus = scsibus;
scbus = malloc(sizeof(struct scsibus_data), M_TEMP, M_NOWAIT);
if(scbus == 0 || extend_set(scbusses, scsibus, scbus) == 0) {
@ -722,7 +729,6 @@ scsi_probe_bus(int bus, int targ, int lun)
sc_link = malloc(sizeof(*sc_link), M_TEMP, M_NOWAIT);
}
*sc_link = *sc_link_proto; /* struct copy */
sc_link->opennings = 1;
sc_link->device = &probe_switch;
sc_link->target = targ;
sc_link->lun = lun;

View File

@ -14,7 +14,7 @@
*
* Ported to run under 386BSD by Julian Elischer (julian@tfs.com) Sept 1992
*
* $Id: scsiconf.h,v 1.19 1995/03/04 20:51:00 dufault Exp $
* $Id: scsiconf.h,v 1.20 1995/03/16 18:15:50 bde Exp $
*/
#ifndef SCSI_SCSICONF_H
#define SCSI_SCSICONF_H 1
@ -138,8 +138,6 @@ struct scsi_adapter
* Format of adapter_info() response data
* e.g. maximum number of entries queuable to a device by the adapter
*/
#define AD_INF_MAX_CMDS 0x000000FF
/* 24 bits of other adapter characteristics go here */
/* Don't poke around inside of "scsi_data". Each low level
* driver has its own definition for it.
@ -341,21 +339,21 @@ struct scsi_link
/* 40*/ struct scsi_data *sd; /* Device data structure */
/* 44+*/struct scsi_inquiry_data inqbuf; /* Inquiry data */
};
#define SDEV_MEDIA_LOADED 0x00000001 /* device figures are still valid */
#define SDEV_WAITING 0x00000002 /* a process is waiting for this */
#define SDEV_OPEN 0x00000004 /* at least 1 open session */
/* XXX dufault@hda.com: SDEV_BOUNCE is set down in the adapter drivers
* in an sc_link structure to indicate that this host adapter requires
* ISA DMA bounce buffers. I think eventually the link structure should
* ISA DMA bounce buffers. I think the link structure should
* be associated only with the type drive and not the adapter driver,
* and the bounce flag should be in something associated with the
* adapter driver.
*/
#define SDEV_BOUNCE 0x00000008 /* unit requires DMA bounce buffer */
#define SDEV_DBX 0x000000F0 /* debuging flags (scsi_debug.h) */
#define SDEV_ONCE_ONLY 0x00010000 /* unit can only be opened once */
#define SDEV_MEDIA_LOADED 0x0001 /* device figures are still valid */
#define SDEV_WAITING 0x0002 /* a process is waiting for this */
#define SDEV_OPEN 0x0004 /* at least 1 open session */
#define SDEV_BOUNCE 0x0008 /* unit requires DMA bounce buffer */
#define SDEV_DBX 0x00F0 /* debugging flags (scsi_debug.h) */
#define SDEV_ONCE_ONLY 0x0100 /* unit can only be opened once */
#define SDEV_BOOTVERBOSE 0x0200 /* be noisy during boot */
/*
* One of these is allocated and filled in for each scsi bus.
@ -458,11 +456,11 @@ errval scsi_start_unit( struct scsi_link *sc_link, u_int32 flags);
errval scsi_stop_unit(struct scsi_link *sc_link, u_int32 eject, u_int32 flags);
void scsi_done(struct scsi_xfer *xs);
void scsi_user_done(struct scsi_xfer *xs);
errval scsi_scsi_cmd( struct scsi_link *sc_link, struct scsi_generic *scsi_cmd,
u_int32 cmdlen, u_char *data_addr,
u_int32 datalen, u_int32 retries,
u_int32 timeout, struct buf *bp,
u_int32 flags);
errval scsi_scsi_cmd __P(( struct scsi_link *, struct scsi_generic *,
u_int32, u_char *,
u_int32, u_int32,
u_int32, struct buf *,
u_int32));
int scsi_do_ioctl __P((dev_t dev, int cmd, caddr_t addr, int mode,
struct proc *p, struct scsi_link *sc_link));
@ -472,25 +470,27 @@ struct proc *p)));
int scsi_opened_ok __P((dev_t dev, int flag, int type, struct scsi_link *sc_link));
char *scsi_sense_desc(int asc, int ascq);
void scsi_sense_print(struct scsi_xfer *xs);
void show_scsi_xs(struct scsi_xfer *xs);
void show_scsi_cmd(struct scsi_xfer *xs);
void show_mem(unsigned char * , u_int32);
char *scsi_sense_desc __P((int, int));
void scsi_sense_print __P((struct scsi_xfer *));
void show_scsi_xs __P((struct scsi_xfer *));
void show_scsi_cmd __P((struct scsi_xfer *));
void show_mem __P((unsigned char * , u_int32));
void scsi_uto3b __P((u_int32 val, u_char *bytes));
u_int32 scsi_3btou __P((u_char *bytes));
int32 scsi_3btoi __P((u_char *bytes));
void scsi_uto4b __P((u_int32 val, u_char *bytes));
u_int32 scsi_4btou __P((u_char *bytes));
void scsi_uto2b __P((u_int32 val, u_char *bytes));
u_int32 scsi_2btou __P((u_char *bytes));
void scsi_uto3b __P((u_int32 , u_char *));
u_int32 scsi_3btou __P((u_char *));
int32 scsi_3btoi __P((u_char *));
void scsi_uto4b __P((u_int32, u_char *));
u_int32 scsi_4btou __P((u_char *));
void scsi_uto2b __P((u_int32, u_char *));
u_int32 scsi_2btou __P((u_char *));
extern void sc_print_addr(struct scsi_link *);
void sc_print_addr __P((struct scsi_link *));
void sc_print_start __P((struct scsi_link *));
void sc_print_finish __P((void));
extern int scsi_externalize(struct scsi_link *, void *, size_t *);
extern int scsi_externalize __P((struct scsi_link *, void *, size_t *));
void scsi_device_register(struct scsi_device *sd);
void scsi_device_register __P((struct scsi_device *sd));
extern struct kern_devconf kdc_scbus0; /* XXX should go away */

View File

@ -14,7 +14,7 @@
*
* Ported to run under 386BSD by Julian Elischer (julian@dialix.oz.au) Sept 1992
*
* $Id: sd.c,v 1.54 1995/03/15 14:22:10 dufault Exp $
* $Id: sd.c,v 1.55 1995/03/16 18:15:52 bde Exp $
*/
#define SPLSD splbio
@ -46,7 +46,7 @@
u_int32 sdstrats, sdqueues;
#define SECSIZE 512
#define SDOUTSTANDING 2
#define SDOUTSTANDING 4
#define SD_RETRIES 4
#define MAXTRANSFER 8 /* 1 page at a time */
@ -70,8 +70,6 @@ struct scsi_data {
#define SDHAVELABEL 0x10 /* have read the label */
#define SDDOSPART 0x20 /* Have read the DOS partition table */
#define SDWRITEPROT 0x40 /* Device in readonly mode (S/W) */
u_int32 ad_info; /* info about the adapter */
u_int32 cmdscount; /* cmds allowed outstanding by board */
boolean wlabel; /* label is writable */
struct disk_parms {
u_char heads; /* Number of heads */
@ -187,20 +185,8 @@ sdattach(struct scsi_link *sc_link)
dp = &(sd->params);
printf("\n");
sc_print_addr(sc_link);
if (sc_link->adapter->adapter_info) {
sd->ad_info = ((*(sc_link->adapter->adapter_info)) (sc_link->adapter_unit));
sd->cmdscount = sd->ad_info & AD_INF_MAX_CMDS;
if (sd->cmdscount > SDOUTSTANDING) {
sd->cmdscount = SDOUTSTANDING;
}
} else {
sd->ad_info = 1;
sd->cmdscount = 1;
}
sc_link->opennings = sd->cmdscount;
if (sc_link->opennings > SDOUTSTANDING)
sc_link->opennings = SDOUTSTANDING;
/*
* Use the subdriver to request information regarding
* the drive. We cannot use interrupts yet, so the
@ -213,13 +199,19 @@ sdattach(struct scsi_link *sc_link)
* -- this avoids the division below from falling over
*/
if(dp->secsiz == 0) dp->secsiz = 512;
printf("%ldMB (%ld sectors), %d C %d H %d S/T %d B/S",
printf("%ldMB (%ld %d byte sectors)",
dp->disksize / ((1024L * 1024L) / dp->secsiz),
dp->disksize,
dp->cyls,
dp->heads,
dp->sectors,
dp->secsiz);
if ( (sc_link->flags & SDEV_BOOTVERBOSE) )
{
printf("\n");
sc_print_addr(sc_link);
printf("with %d cyls, %d heads, and an average %d sectors/track",
dp->cyls, dp->heads, dp->sectors);
}
sd->flags |= SDINIT;
sd_registerdev(unit);

View File

@ -12,7 +12,7 @@
* on the understanding that TFS is not responsible for the correct
* functioning of this software in any circumstances.
*
* $Id: st.c,v 1.29 1995/03/04 20:51:05 dufault Exp $
* $Id: st.c,v 1.30 1995/03/15 14:22:11 dufault Exp $
*/
/*
@ -153,13 +153,16 @@ static struct rogues gallery[] = /* ends with an all-null entry */
errval st_space __P((u_int32 unit, int32 number, u_int32 what, u_int32 flags));
errval st_rewind __P((u_int32 unit, boolean immed, u_int32 flags));
errval st_erase __P((u_int32 unit, boolean immed, u_int32 flags)); /* AKL */
static errval st_mode_sense __P((u_int32 unit, u_int32 flags));
static errval st_mode_sense __P((u_int32 unit, u_int32 flags, \
struct tape_pages *page, u_int32 pagelen, u_int32 pagecode));
errval st_decide_mode __P((u_int32 unit, boolean first_read));
errval st_rd_blk_lim __P((u_int32 unit, u_int32 flags));
errval st_touch_tape __P((u_int32 unit));
errval st_write_filemarks __P((u_int32 unit, int32 number, u_int32 flags));
errval st_load __P((u_int32 unit, u_int32 type, u_int32 flags));
errval st_mode_select __P((u_int32 unit, u_int32 flags));
errval st_mode_select __P((u_int32 unit, u_int32 flags, \
struct tape_pages *page, u_int32 pagelen));
errval st_comp __P((u_int32 unit, u_int32 mode));
void ststrategy();
int32 st_chkeod();
void ststart(u_int32 unit);
@ -180,6 +183,7 @@ struct scsi_data {
u_int32 flags; /* see below */
u_int32 blksiz; /* blksiz we are using */
u_int32 density; /* present density */
u_int32 comp; /* present compression mode */
u_int32 quirks; /* quirks for the open mode */
u_int32 last_dsty; /* last density openned */
/*--------------------parameters reported by the device ----------------------*/
@ -205,8 +209,10 @@ struct scsi_data {
#define DENSITY_SET_BY_QUIRK 0x02
#define BLKSIZE_SET_BY_USER 0x04
#define BLKSIZE_SET_BY_QUIRK 0x08
#define COMPRES_SET_BY_USER 0x10
#define COMPRES_SET_BY_QUIRK 0x20
/*--------------------storage for sense data returned by the drive------------*/
unsigned char sense_data[12]; /*
unsigned char saved_page0[PAGE_0_SENSE_DATA_SIZE]; /*
* additional sense data needed
* for mode sense/select.
*/
@ -333,7 +339,8 @@ stattach(struct scsi_link *sc_link)
* the drive. We cannot use interrupts yet, so the
* request must specify this.
*/
if (st_mode_sense(unit, SCSI_NOSLEEP | SCSI_NOMASK | SCSI_SILENT)) {
if (st_mode_sense(unit, SCSI_NOSLEEP | SCSI_NOMASK | SCSI_SILENT,
NULL, 0, 0)) {
printf("drive offline");
} else {
printf("density code 0x%x, ", st->media_density);
@ -678,7 +685,7 @@ st_mount_tape(dev, flags)
* As we have a tape in, it should be reflected here.
* If not you may need the "quirk" above.
*/
if (errno = st_mode_sense(unit, 0)) {
if (errno = st_mode_sense(unit, 0, NULL, 0, 0)) {
return errno;
}
/*
@ -707,7 +714,7 @@ st_mount_tape(dev, flags)
return errno;
}
}
if (errno = st_mode_select(unit, 0)) {
if (errno = st_mode_select(unit, 0, NULL, 0)) {
printf("st%d: Cannot set selected mode", unit);
return errno;
}
@ -1141,6 +1148,7 @@ struct proc *p, struct scsi_link *sc_link)
g->mt_type = 0x7; /* Ultrix compat *//*? */
g->mt_density = st->density;
g->mt_blksiz = st->blksiz;
g->mt_comp = st->comp;
g->mt_density0 = st->modes[0].density;
g->mt_density1 = st->modes[1].density;
g->mt_density2 = st->modes[2].density;
@ -1149,6 +1157,10 @@ struct proc *p, struct scsi_link *sc_link)
g->mt_blksiz1 = st->modes[1].blksiz;
g->mt_blksiz2 = st->modes[2].blksiz;
g->mt_blksiz3 = st->modes[3].blksiz;
g->mt_comp0 = 0;
g->mt_comp1 = 0;
g->mt_comp2 = 0;
g->mt_comp3 = 0;
break;
}
case MTIOCTOP:
@ -1222,6 +1234,9 @@ struct proc *p, struct scsi_link *sc_link)
}
goto try_new_value;
case MTCOMP: /* enable default compression */
errcode = st_comp(unit,number);
break;
default:
errcode = EINVAL;
}
@ -1244,7 +1259,7 @@ struct proc *p, struct scsi_link *sc_link)
* 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)) { /* put it back as it was */
if (errcode = st_mode_select(unit, 0, NULL, 0)) { /* put it back as it was */
printf("st%d: Cannot set selected mode", unit);
st->density = hold_density;
st->blksiz = hold_blksiz;
@ -1379,86 +1394,83 @@ st_rd_blk_lim(unit, flags)
* ioctl (to reset original blksize)
*/
static errval
st_mode_sense(unit, flags)
st_mode_sense(unit, flags, page, pagelen, pagecode)
u_int32 unit, flags;
struct tape_pages *page;
u_int32 pagelen,pagecode;
{
u_int32 scsi_sense_len;
u_int32 dat_len;
errval errno;
char *scsi_sense_ptr;
struct scsi_mode_sense scsi_cmd;
struct scsi_sense {
struct {
struct scsi_mode_header header;
struct blk_desc blk_desc;
} scsi_sense;
struct tape_pages page;
} dat;
struct scsi_sense_page_0 {
struct scsi_mode_header header;
struct blk_desc blk_desc;
unsigned char sense_data[PAGE_0_SENSE_DATA_SIZE];
/* Tandberg tape drives returns page 00
* with the sense data, whether or not
* you want it( ie the don't like you
* saying you want anything less!!!!!
* They also expect page 00
* back when you issue a mode select
*/
} scsi_sense_page_0;
/* Tandberg tape drives returns page 00
* with the sense data, whether or not
* you want it( ie the don't like you
* saying you want anything less!!!!!
* They also expect page 00
* back when you issue a mode select
*/
struct scsi_link *sc_link = SCSI_LINK(&st_switch, unit);
struct scsi_data *st = sc_link->sd;
/*
* Define what sort of structure we're working with
* Check if we need to use a default page..
*/
if (st->quirks & ST_Q_NEEDS_PAGE_0) {
scsi_sense_len = sizeof(scsi_sense_page_0);
scsi_sense_ptr = (char *) &scsi_sense_page_0;
} else {
scsi_sense_len = sizeof(scsi_sense);
scsi_sense_ptr = (char *) &scsi_sense;
if ((st->quirks & ST_Q_NEEDS_PAGE_0) && (!page)) {
pagelen = PAGE_0_SENSE_DATA_SIZE;
page = (struct tape_pages *) st->saved_page0;
pagecode = 0;
}
/*
* Now work out the total dat size etc.
*/
dat_len = sizeof(struct scsi_mode_header)
+ sizeof(struct blk_desc)
+ (page ? pagelen : 0);
/*
* Set up a mode sense
*/
bzero(&scsi_cmd, sizeof(scsi_cmd));
scsi_cmd.op_code = MODE_SENSE;
scsi_cmd.length = scsi_sense_len;
scsi_cmd.page = (u_char) pagecode;
scsi_cmd.length = dat_len;
/*
* do the command, but we don't need the results
* just print them for our interest's sake, if asked,
* do the command,
* use the results to set blksiz, numblks and density
* or if we need it as a template for the mode select
* store it away.
*/
if (errno = scsi_scsi_cmd(sc_link,
(struct scsi_generic *) &scsi_cmd,
sizeof(scsi_cmd),
(u_char *) scsi_sense_ptr,
scsi_sense_len,
(u_char *) &dat,
dat_len,
ST_RETRIES,
5000,
NULL,
flags | SCSI_DATA_IN)) {
return errno;
}
st->numblks = scsi_3btou(((struct scsi_sense *)scsi_sense_ptr)->blk_desc.nblocks);
st->media_blksiz = scsi_3btou(((struct scsi_sense *)scsi_sense_ptr)->blk_desc.blklen);
st->media_density = ((struct scsi_sense *) scsi_sense_ptr)->blk_desc.density;
if (((struct scsi_sense *) scsi_sense_ptr)->header.dev_spec &
SMH_DSP_WRITE_PROT) {
st->numblks = scsi_3btou(dat.blk_desc.nblocks);
st->media_blksiz = scsi_3btou(dat.blk_desc.blklen);
st->media_density = dat.blk_desc.density;
if (dat.header.dev_spec & SMH_DSP_WRITE_PROT) {
st->flags |= ST_READONLY;
}
SC_DEBUG(sc_link, SDEV_DB3,
("density code 0x%x, %d-byte blocks, write-%s, ",
st->media_density, st->media_blksiz,
st->flags & ST_READONLY ? "protected" : "enabled"));
SC_DEBUG(sc_link, SDEV_DB3,
("%sbuffered\n",
((struct scsi_sense *) scsi_sense_ptr)->header.dev_spec
& SMH_DSP_BUFF_MODE ? "" : "un"));
if (st->quirks & ST_Q_NEEDS_PAGE_0) {
bcopy(((struct scsi_sense_page_0 *) scsi_sense_ptr)->sense_data,
st->sense_data,
sizeof(((struct scsi_sense_page_0 *) scsi_sense_ptr)->sense_data));
SC_DEBUG(sc_link, SDEV_DB3, ("%sbuffered\n",
((dat.header.dev_spec & SMH_DSP_BUFF_MODE) ? "" : "un")));
if (page) {
bcopy(&dat.page, page, pagelen);
}
sc_link->flags |= SDEV_MEDIA_LOADED;
return 0;
@ -1469,50 +1481,50 @@ st_mode_sense(unit, flags)
* set it into the desire modes etc.
*/
errval
st_mode_select(unit, flags)
st_mode_select(unit, flags, page, pagelen)
u_int32 unit, flags;
struct tape_pages *page;
u_int32 pagelen;
{
u_int32 dat_len;
char *dat_ptr;
struct scsi_mode_select scsi_cmd;
struct dat {
struct {
struct scsi_mode_header header;
struct blk_desc blk_desc;
struct tape_pages page;
} dat;
struct dat_page_0 {
struct scsi_mode_header header;
struct blk_desc blk_desc;
unsigned char sense_data[PAGE_0_SENSE_DATA_SIZE];
} dat_page_0;
struct scsi_link *sc_link = SCSI_LINK(&st_switch, unit);
struct scsi_data *st = sc_link->sd;
/*
* Define what sort of structure we're working with
* Check if we need to use a default page..
* Gee, hope we saved one before now........
*/
if (st->quirks & ST_Q_NEEDS_PAGE_0) {
dat_len = sizeof(dat_page_0);
dat_ptr = (char *) &dat_page_0;
} else {
dat_len = sizeof(dat);
dat_ptr = (char *) &dat;
if ((st->quirks & ST_Q_NEEDS_PAGE_0) && (!page)) {
pagelen = PAGE_0_SENSE_DATA_SIZE;
page = (struct tape_pages *) st->saved_page0;
}
/*
* Now work out the total dat size etc.
*/
dat_len = sizeof(struct scsi_mode_header)
+ sizeof(struct blk_desc)
+ (page ? pagelen : 0);
/*
* Set up for a mode select
*/
bzero(dat_ptr, dat_len);
bzero(&dat, dat_len);
bzero(&scsi_cmd, sizeof(scsi_cmd));
scsi_cmd.op_code = MODE_SELECT;
scsi_cmd.length = dat_len;
((struct dat *) dat_ptr)->header.blk_desc_len = sizeof(struct blk_desc);
((struct dat *) dat_ptr)->header.dev_spec |= SMH_DSP_BUFF_MODE_ON;
((struct dat *) dat_ptr)->blk_desc.density = st->density;
dat.header.blk_desc_len = sizeof(struct blk_desc);
dat.header.dev_spec |= SMH_DSP_BUFF_MODE_ON;
dat.blk_desc.density = st->density;
if (st->flags & ST_FIXEDBLOCKS) {
scsi_uto3b(st->blksiz, ((struct dat *) dat_ptr)->blk_desc.blklen);
scsi_uto3b(st->blksiz, dat.blk_desc.blklen);
}
if (st->quirks & ST_Q_NEEDS_PAGE_0) {
bcopy(st->sense_data, ((struct dat_page_0 *) dat_ptr)->sense_data,
sizeof(((struct dat_page_0 *) dat_ptr)->sense_data));
if (page) {
bcopy(page, &dat.page, pagelen);
/* the Tandberg tapes need the block size to */
/* be set on each mode sense/select. */
}
@ -1522,7 +1534,7 @@ st_mode_select(unit, flags)
return (scsi_scsi_cmd(sc_link,
(struct scsi_generic *) &scsi_cmd,
sizeof(scsi_cmd),
(u_char *) dat_ptr,
(u_char *) &dat,
dat_len,
ST_RETRIES,
5000,
@ -1530,6 +1542,56 @@ st_mode_select(unit, flags)
flags | SCSI_DATA_OUT));
}
int noisy_st = 0;
/***************************************************************\
* Set the compression mode of the drive to on (1) or off (0) *
still doesn't work! grrr!
\***************************************************************/
errval st_comp(unit,mode)
u_int32 unit,mode;
{
struct tape_pages page;
int pagesize;
int retval;
struct scsi_link *sc_link = SCSI_LINK(&st_switch, unit);
struct scsi_data *st = sc_link->sd;
bzero(&page, sizeof(page));
pagesize = sizeof(page.pages.configuration) + PAGE_HEADERLEN;
if ( retval = st_mode_sense(unit, 0,
&page, pagesize, ST_PAGE_CONFIGURATION))
{
printf("sense returned an error of %d\n",retval);
return retval;
}
if ( noisy_st)
printf("drive reports value of %d, setting %d\n",
page.pages.configuration.data_compress_alg,mode);
page.pg_code &= ST_P_CODE;
page.pg_length = sizeof(page.pages.configuration);
switch(mode)
{
case 0:
page.pages.configuration.data_compress_alg = 0;
break;
case 1:
page.pages.configuration.data_compress_alg = 1;
break;
default:
printf("st%d: 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;
}
st->comp = mode;
return 0;
}
/*
* skip N blocks/filemarks/seq filemarks/eom
*/
@ -1969,7 +2031,7 @@ st_touch_tape(unit)
if (!buf)
return (ENOMEM);
if (errno = st_mode_sense(unit, 0)) {
if (errno = st_mode_sense(unit, 0, NULL, 0, 0)) {
goto bad;
}
st->blksiz = 1024;
@ -1983,7 +2045,7 @@ st_touch_tape(unit)
default:
readsiz = 1;
st->flags &= ~ST_FIXEDBLOCKS;
} if (errno = st_mode_select(unit, 0)) {
} if (errno = st_mode_select(unit, 0, NULL, 0)) {
goto bad;
}
st_read(unit, buf, readsiz, SCSI_SILENT);