diff options
author | dufault <dufault@FreeBSD.org> | 1995-03-21 11:21:08 +0000 |
---|---|---|
committer | dufault <dufault@FreeBSD.org> | 1995-03-21 11:21:08 +0000 |
commit | 274a8d5ee2f5e2f80b359cbb60feedce7879b4fe (patch) | |
tree | c976e70835fd9cfefdf009bac7ee768f44b8b8b0 /sys/scsi | |
parent | 0d274572e35245942a094cbb30772453c9a4c109 (diff) | |
download | FreeBSD-src-274a8d5ee2f5e2f80b359cbb60feedce7879b4fe.zip FreeBSD-src-274a8d5ee2f5e2f80b359cbb60feedce7879b4fe.tar.gz |
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
Diffstat (limited to 'sys/scsi')
-rw-r--r-- | sys/scsi/cd.c | 74 | ||||
-rw-r--r-- | sys/scsi/scsi_base.c | 36 | ||||
-rw-r--r-- | sys/scsi/scsi_driver.c | 11 | ||||
-rw-r--r-- | sys/scsi/scsi_tape.h | 90 | ||||
-rw-r--r-- | sys/scsi/scsiconf.c | 24 | ||||
-rw-r--r-- | sys/scsi/scsiconf.h | 62 | ||||
-rw-r--r-- | sys/scsi/sd.c | 36 | ||||
-rw-r--r-- | sys/scsi/st.c | 214 |
8 files changed, 362 insertions, 185 deletions
diff --git a/sys/scsi/cd.c b/sys/scsi/cd.c index 9b8241a..f8713ed 100644 --- a/sys/scsi/cd.c +++ b/sys/scsi/cd.c @@ -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 @@ -233,6 +223,15 @@ struct scsi_link *sc_link) ("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 diff --git a/sys/scsi/scsi_base.c b/sys/scsi/scsi_base.c index 5e50f7a..4cae78d 100644 --- a/sys/scsi/scsi_base.c +++ b/sys/scsi/scsi_base.c @@ -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 @@ retry: /* * 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); diff --git a/sys/scsi/scsi_driver.c b/sys/scsi/scsi_driver.c index b5f3fad..7f78661 100644 --- a/sys/scsi/scsi_driver.c +++ b/sys/scsi/scsi_driver.c @@ -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) diff --git a/sys/scsi/scsi_tape.h b/sys/scsi/scsi_tape.h index 3741136..ec852ea 100644 --- a/sys/scsi/scsi_tape.h +++ b/sys/scsi/scsi_tape.h @@ -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 diff --git a/sys/scsi/scsiconf.c b/sys/scsi/scsiconf.c index 5724c72..4aac5c6 100644 --- a/sys/scsi/scsiconf.c +++ b/sys/scsi/scsiconf.c @@ -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; diff --git a/sys/scsi/scsiconf.h b/sys/scsi/scsiconf.h index 47c963b..66c4fc2 100644 --- a/sys/scsi/scsiconf.h +++ b/sys/scsi/scsiconf.h @@ -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 */ diff --git a/sys/scsi/sd.c b/sys/scsi/sd.c index 62d05d2..bad3c72 100644 --- a/sys/scsi/sd.c +++ b/sys/scsi/sd.c @@ -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); diff --git a/sys/scsi/st.c b/sys/scsi/st.c index d57a7cf..c391b0a 100644 --- a/sys/scsi/st.c +++ b/sys/scsi/st.c @@ -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 @@ try_new_value: * 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); |