diff options
author | mjacob <mjacob@FreeBSD.org> | 2001-01-15 22:28:11 +0000 |
---|---|---|
committer | mjacob <mjacob@FreeBSD.org> | 2001-01-15 22:28:11 +0000 |
commit | db0d9914f0f53d14887cd469375180dcece4c388 (patch) | |
tree | 2734e019e3000ce9fbc858ab2640cd8c9e2ad31a /sys/cam | |
parent | 14a2cceb124b20c6c38ec657d866c5865e67c350 (diff) | |
download | FreeBSD-src-db0d9914f0f53d14887cd469375180dcece4c388.zip FreeBSD-src-db0d9914f0f53d14887cd469375180dcece4c388.tar.gz |
Fix PR 24220 by using the periph private field0 for a CCB for not
only CCB type but also extra flags- one of which can be "position
updated".
In other changes: Add in a SA_QUIRK_NO_CPAGE quirk so that it's possible
to avoid using a (broken) device's implementation of he DEVICE COMPRESSION
page.
Also do a couple of printout cleanups.
As per some discussion on FreeBSD-scsi, skip doing tape flushing
if we're reading tape logical block location (MTIOCRDSPOS).
Diffstat (limited to 'sys/cam')
-rw-r--r-- | sys/cam/scsi/scsi_sa.c | 90 |
1 files changed, 50 insertions, 40 deletions
diff --git a/sys/cam/scsi/scsi_sa.c b/sys/cam/scsi/scsi_sa.c index d21e850..226ab99 100644 --- a/sys/cam/scsi/scsi_sa.c +++ b/sys/cam/scsi/scsi_sa.c @@ -100,13 +100,21 @@ typedef enum { SA_STATE_NORMAL, SA_STATE_ABNORMAL } sa_state; -typedef enum { - SA_CCB_BUFFER_IO, - SA_CCB_WAITING -} sa_ccb_types; +#define ccb_pflags ppriv_field0 +#define ccb_bp ppriv_ptr1 + +#define SA_CCB_BUFFER_IO 0x0 +#define SA_CCB_WAITING 0x1 +#define SA_CCB_TYPEMASK 0x1 +#define SA_POSITION_UPDATED 0x2 + +#define Set_CCB_Type(x, type) \ + x->ccb_h.ccb_pflags &= ~SA_CCB_TYPEMASK; \ + x->ccb_h.ccb_pflags |= type + +#define CCB_Type(x) (x->ccb_h.ccb_pflags & SA_CCB_TYPEMASK) + -#define ccb_type ppriv_field0 -#define ccb_bp ppriv_ptr1 typedef enum { SA_FLAG_OPEN = 0x0001, @@ -153,7 +161,8 @@ typedef enum { SA_QUIRK_2FM = 0x08, /* Needs Two File Marks at EOD */ SA_QUIRK_1FM = 0x10, /* No more than 1 File Mark at EOD */ SA_QUIRK_NODREAD = 0x20, /* Don't try and dummy read density */ - SA_QUIRK_NO_MODESEL = 0x40 /* Don't do mode select at all */ + SA_QUIRK_NO_MODESEL = 0x40, /* Don't do mode select at all */ + SA_QUIRK_NO_CPAGE = 0x80 /* Don't use DEVICE COMPRESSION page */ } sa_quirks; /* units are bits 4-7, 16-21 (1024 units) */ @@ -276,6 +285,12 @@ static struct sa_quirk_entry sa_quirk_table[] = { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "ARCHIVE", "VIPER 2525*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 1024 }, +#if 0 + { + { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP", + "C15*", "*"}, SA_QUIRK_VARIABLE|SA_QUIRK_NO_CPAGE, 0, + }, +#endif { { T_SEQUENTIAL, SIP_MEDIA_REMOVABLE, "HP", "T20*", "*"}, SA_QUIRK_FIXED|SA_QUIRK_1FM, 512 @@ -1470,6 +1485,7 @@ sastart(struct cam_periph *periph, union ccb *start_ccb) softc = (struct sa_softc *)periph->softc; CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("sastart")); + switch (softc->state) { case SA_STATE_NORMAL: @@ -1486,7 +1502,7 @@ sastart(struct cam_periph *periph, union ccb *start_ccb) if (periph->immediate_priority <= periph->pinfo.priority) { CAM_DEBUG_PRINT(CAM_DEBUG_SUBTRACE, ("queuing for immediate ccb\n")); - start_ccb->ccb_h.ccb_type = SA_CCB_WAITING; + Set_CCB_Type(start_ccb, SA_CCB_WAITING); SLIST_INSERT_HEAD(&periph->ccb_list, &start_ccb->ccb_h, periph_links.sle); periph->immediate_priority = CAM_PRIORITY_NONE; @@ -1540,8 +1556,8 @@ sastart(struct cam_periph *periph, union ccb *start_ccb) length = bp->bio_bcount >> softc->blk_shift; } else if (softc->media_blksize != 0) { - length = - bp->bio_bcount / softc->media_blksize; + length = bp->bio_bcount / + softc->media_blksize; } else { bp->bio_error = EIO; xpt_print_path(periph->path); @@ -1586,7 +1602,8 @@ sastart(struct cam_periph *periph, union ccb *start_ccb) FALSE, (softc->flags & SA_FLAG_FIXED) != 0, length, bp->bio_data, bp->bio_bcount, SSD_FULL_SIZE, 120 * 60 * 1000); - start_ccb->ccb_h.ccb_type = SA_CCB_BUFFER_IO; + start_ccb->ccb_h.ccb_pflags &= ~SA_POSITION_UPDATED; + Set_CCB_Type(start_ccb, SA_CCB_BUFFER_IO); start_ccb->ccb_h.ccb_bp = bp; bp = bioq_first(&softc->bio_queue); splx(s); @@ -1615,7 +1632,7 @@ sadone(struct cam_periph *periph, union ccb *done_ccb) softc = (struct sa_softc *)periph->softc; csio = &done_ccb->csio; - switch (csio->ccb_h.ccb_type) { + switch (CCB_Type(csio)) { case SA_CCB_BUFFER_IO: { struct bio *bp; @@ -1676,7 +1693,8 @@ sadone(struct cam_periph *periph, union ccb *done_ccb) softc->flags |= SA_FLAG_TAPE_WRITTEN; softc->filemarks = 0; } - if (softc->blkno != (daddr_t) -1) { + if (!(csio->ccb_h.ccb_pflags & SA_POSITION_UPDATED) && + (softc->blkno != (daddr_t) -1)) { if ((softc->flags & SA_FLAG_FIXED) != 0) { u_int32_t l; if (softc->blk_shift != 0) { @@ -2256,7 +2274,7 @@ saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs) info /= softc->media_blksize; } } - if (csio->ccb_h.ccb_type == SA_CCB_BUFFER_IO) { + if (CCB_Type(csio) == SA_CCB_BUFFER_IO) { bcopy((caddr_t) sense, (caddr_t) &softc->last_io_sense, sizeof (struct scsi_sense_data)); bcopy(csio->cdb_io.cdb_bytes, softc->last_io_cdb, @@ -2269,8 +2287,8 @@ saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs) (int) csio->cdb_len); softc->last_ctl_resid = resid; } - CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Key 0x%x ASC/ASCQ - 0x%x 0x%x flags 0x%x resid %d dxfer_len %d\n", sense_key, + CAM_DEBUG(periph->path, CAM_DEBUG_INFO, ("Key 0x%x ASC/ASCQ " + "0x%x 0x%x flags 0x%x resid %d dxfer_len %d\n", sense_key, asc, ascq, sense->flags & ~SSD_KEY_RESERVED, resid, csio->dxfer_len)); } else { @@ -2283,7 +2301,7 @@ saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs) * command, let the common code deal with it the error setting. */ if ((csio->ccb_h.status & CAM_STATUS_MASK) != CAM_SCSI_STATUS_ERROR || - (csio->ccb_h.ccb_type == SA_CCB_WAITING)) { + (CCB_Type(csio) == SA_CCB_WAITING)) { return (cam_periph_error(ccb, cflgs, sflgs, &softc->saved_ccb)); } @@ -2311,6 +2329,7 @@ saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs) if (softc->fileno != (daddr_t) -1) { softc->fileno++; softc->blkno = 0; + csio->ccb_h.ccb_pflags |= SA_POSITION_UPDATED; } } if (sense->flags & SSD_EOM) { @@ -2345,6 +2364,7 @@ saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs) if (softc->fileno != (daddr_t) -1) { softc->fileno++; softc->blkno = 0; + csio->ccb_h.ccb_pflags |= SA_POSITION_UPDATED; } } } @@ -2372,6 +2392,8 @@ saerror(union ccb *ccb, u_int32_t cflgs, u_int32_t sflgs) if ((sense->flags & SSD_FILEMARK) == 0) { if (softc->blkno != (daddr_t) -1) { softc->blkno++; + csio->ccb_h.ccb_pflags |= + SA_POSITION_UPDATED; } } } @@ -2404,7 +2426,10 @@ sagetparams(struct cam_periph *periph, sa_params params_to_get, softc = (struct sa_softc *)periph->softc; ccb = cam_periph_getccb(periph, 1); - cpage = SA_DATA_COMPRESSION_PAGE; + if (softc->quirks & SA_QUIRK_NO_CPAGE) + cpage = SA_DEVICE_CONFIGURATION_PAGE; + else + cpage = SA_DATA_COMPRESSION_PAGE; retry: mode_buffer_len = sizeof(*mode_hdr) + sizeof(*mode_blk); @@ -3044,15 +3069,16 @@ sardpos(struct cam_periph *periph, int hard, u_int32_t *blkptr) int error; /* - * We have to try and flush any buffered writes here if we were writing. + * We try and flush any buffered writes here if we were writing + * and we're trying to get hardware block position. It eats + * up performance substantially, but I'm wary of drive firmware. * - * The SCSI specification is vague enough about situations like - * different sized blocks in a tape drive buffer as to make one - * wary about trying to figure out the actual block location value - * if data is in the tape drive buffer. + * I think that *logical* block position is probably okay- + * but hardware block position might have to wait for data + * to hit media to be valid. Caveat Emptor. */ - if (softc->flags & SA_FLAG_TAPE_WRITTEN) { + if (hard && (softc->flags & SA_FLAG_TAPE_WRITTEN)) { error = sawritefilemarks(periph, 0, 0); if (error && error != EACCES) return (error); @@ -3071,23 +3097,7 @@ sardpos(struct cam_periph *periph, int hard, u_int32_t *blkptr) if (loc.flags & SA_RPOS_UNCERTAIN) { error = EINVAL; /* nothing is certain */ } else { -#if 0 - u_int32_t firstblk, lastblk, nbufblk, nbufbyte; - - firstblk = scsi_4btoul(loc.firstblk); - lastblk = scsi_4btoul(loc.lastblk); - nbufblk = scsi_4btoul(loc.nbufblk); - nbufbyte = scsi_4btoul(loc.nbufbyte); - if (lastblk || nbufblk || nbufbyte) { - xpt_print_path(periph->path); - printf("rdpos firstblk 0x%x lastblk 0x%x bufblk" - " 0x%x bufbyte 0x%x\n", firstblk, lastblk, - nbufblk, nbufbyte); - } - *blkptr = firstblk; -#else *blkptr = scsi_4btoul(loc.firstblk); -#endif } } |