diff options
-rw-r--r-- | sys/cam/scsi/scsi_cd.c | 233 | ||||
-rw-r--r-- | sys/cam/scsi/scsi_da.c | 113 |
2 files changed, 147 insertions, 199 deletions
diff --git a/sys/cam/scsi/scsi_cd.c b/sys/cam/scsi/scsi_cd.c index d240f5f..73cacc4 100644 --- a/sys/cam/scsi/scsi_cd.c +++ b/sys/cam/scsi/scsi_cd.c @@ -24,7 +24,7 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_cd.c,v 1.3 1998/09/20 22:48:15 ken Exp $ + * $Id: scsi_cd.c,v 1.4 1998/09/23 03:17:08 ken Exp $ */ /* * Portions of this driver taken from the original FreeBSD cd driver. @@ -46,23 +46,18 @@ * from: cd.c,v 1.83 1997/05/04 15:24:22 joerg Exp $ */ +#include "opt_cd.h" #include <sys/param.h> -#include <sys/queue.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/types.h> #include <sys/buf.h> #include <sys/dkbad.h> #include <sys/disklabel.h> #include <sys/diskslice.h> #include <sys/malloc.h> -#include <sys/fcntl.h> -#include <sys/stat.h> #include <sys/conf.h> -#include <sys/buf.h> #include <sys/cdio.h> -#include <sys/errno.h> #include <sys/devicestat.h> #include <sys/sysctl.h> @@ -72,20 +67,11 @@ #include <cam/cam_periph.h> #include <cam/cam_xpt_periph.h> #include <cam/cam_queue.h> -#include <cam/cam_debug.h> -#include <cam/scsi/scsi_all.h> #include <cam/scsi/scsi_message.h> #include <cam/scsi/scsi_da.h> #include <cam/scsi/scsi_cd.h> -#include "opt_cd.h" -#define ESUCCESS 0 - -#define CDUNIT(DEV) ((minor(DEV)&0xF8) >> 3) /* 5 bit unit */ -#define CDSETUNIT(DEV, U) makedev(major(DEV), ((U) << 3)) -#define PARTITION(z) (minor(z) & 0x07) -#define RAW_PART 2 #define LEADOUT 0xaa /* leadout toc entry */ struct cd_params { @@ -144,7 +130,6 @@ struct cd_softc { struct buf_queue_head buf_queue; LIST_HEAD(, ccb_hdr) pending_ccbs; struct cd_params params; - struct disklabel disklabel; struct diskslices *cd_slices; union ccb saved_ccb; cd_quirks quirks; @@ -153,13 +138,6 @@ struct cd_softc { struct cdchanger *changer; int bufs_left; struct cam_periph *periph; -#ifdef DEVFS - void *ra_devfs_token; - void *rc_devfs_token; - void *a_devfs_token; - void *c_devfs_token; - void *ctl_devfs_token; -#endif }; struct cd_quirk_entry { @@ -199,6 +177,7 @@ static d_read_t cdread; static d_close_t cdclose; static d_ioctl_t cdioctl; static d_strategy_t cdstrategy; +static d_strategy_t cdstrategy1; static periph_init_t cdinit; static periph_ctor_t cdregister; @@ -223,7 +202,6 @@ static int cderror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags); static void cdprevent(struct cam_periph *periph, int action); static int cdsize(dev_t dev, u_int32_t *size); -static int cdgetdisklabel (dev_t dev); static int cdreadtoc(struct cam_periph *periph, u_int32_t mode, u_int32_t start, struct cd_toc_entry *data, u_int32_t len); @@ -885,13 +863,13 @@ cdregisterexit: static int cdopen(dev_t dev, int flags, int fmt, struct proc *p) { + struct disklabel label; struct cam_periph *periph; struct cd_softc *softc; + struct ccb_getdev cgd; u_int32_t size; int unit, error; - error = 0; /* default to no error */ - unit = dkunit(dev); periph = cam_extend_get(cdperiphs, unit); @@ -910,40 +888,70 @@ cdopen(dev_t dev, int flags, int fmt, struct proc *p) if (cam_periph_acquire(periph) != CAM_REQ_CMP) return(ENXIO); softc->flags |= CD_FLAG_OPEN; - } - /* lock the cd */ - cdprevent(periph, PR_PREVENT); + cdprevent(periph, PR_PREVENT); + } /* find out the size */ if ((error = cdsize(dev, &size)) != 0) { - cdprevent(periph, PR_ALLOW); - softc->flags &= ~CD_FLAG_OPEN; + if (dsisopen(softc->cd_slices) == 0) { + cdprevent(periph, PR_ALLOW); + softc->flags &= ~CD_FLAG_OPEN; + } cam_periph_unlock(periph); - cam_periph_release(periph); - return(error); - } - /* get a disklabel */ - if ((error = cdgetdisklabel(dev)) != 0) { - printf("error getting disklabel\n"); - cdprevent(periph, PR_ALLOW); - softc->flags &= ~CD_FLAG_OPEN; - cam_periph_unlock(periph); - cam_periph_release(periph); + if ((softc->flags & CD_FLAG_OPEN) == 0) + cam_periph_release(periph); + return(error); } - if (error == 0) { - /* Initialize slice tables. */ - error = dsopen("cd", dev, fmt, DSO_NOLABELS | DSO_ONESLICE, - &softc->cd_slices, &softc->disklabel, - cdstrategy, (ds_setgeom_t *)NULL, &cd_cdevsw); + /* + * Build prototype label for whole disk. + * Should take information about different data tracks from the + * TOC and put it in the partition table. + */ + bzero(&label, sizeof(label)); + label.d_type = DTYPE_SCSI; + /* + * Grab the inquiry data to get the vendor and product names. + * Put them in the typename and packname for the label. + */ + xpt_setup_ccb(&cgd.ccb_h, periph->path, /*priority*/ 1); + cgd.ccb_h.func_code = XPT_GDEV_TYPE; + xpt_action((union ccb *)&cgd); + + strncpy(label.d_typename, cgd.inq_data.vendor, + min(SID_VENDOR_SIZE, sizeof(label.d_typename))); + strncpy(label.d_packname, cgd.inq_data.product, + min(SID_PRODUCT_SIZE, sizeof(label.d_packname))); + + label.d_secsize = softc->params.blksize; + label.d_secperunit = softc->params.disksize; + label.d_flags = D_REMOVABLE; + /* + * Make partition 'a' cover the whole disk. This is a temporary + * compatibility hack. The 'a' partition should not exist, so + * the slice code won't create it. The slice code will make + * partition (RAW_PART + 'a') cover the whole disk and fill in + * some more defaults. + */ + label.d_partitions[0].p_size = label.d_secperunit; + label.d_partitions[0].p_fstype = FS_OTHER; + + /* Initialize slice tables. */ + error = dsopen("cd", dev, fmt, DSO_NOLABELS | DSO_ONESLICE, + &softc->cd_slices, &label, cdstrategy, + (ds_setgeom_t *)NULL, &cd_cdevsw); + + if (error == 0) { /* * We unconditionally (re)set the blocksize each time the * CD device is opened. This is because the CD can change, * and therefore the blocksize might change. + * XXX problems here if some slice or partition is still + * open with the old size? */ if ((softc->device_stats.flags & DEVSTAT_BS_UNAVAILABLE) != 0) softc->device_stats.flags &= ~DEVSTAT_BS_UNAVAILABLE; @@ -979,6 +987,10 @@ cdclose(dev_t dev, int flag, int fmt, struct proc *p) return (error); dsclose(dev, fmt, softc->cd_slices); + if (dsisopen(softc->cd_slices)) { + cam_periph_unlock(periph); + return (0); + } if ((softc->flags & CD_FLAG_DISC_REMOVABLE) != 0) cdprevent(periph, PR_ALLOW); @@ -1417,6 +1429,16 @@ done: } static void +cdstrategy1(struct buf *bp) +{ + /* + * XXX - do something to make cdstrategy() but not this block while + * we're doing dsopen() and dsioctl(). + */ + cdstrategy(bp); +} + +static void cdstart(struct cam_periph *periph, union ccb *start_ccb) { struct cd_softc *softc; @@ -1651,8 +1673,8 @@ cddone(struct cam_periph *periph, union ccb *done_ccb) if ((csio->ccb_h.status & CAM_STATUS_MASK) == CAM_REQ_CMP) { sprintf(announce_buf, - "cd present [%ld x %d byte records]", - cdp->disksize, cdp->blksize); + "cd present [%lu x %lu byte records]", + cdp->disksize, (u_long)cdp->blksize); } else { int error; @@ -1736,58 +1758,47 @@ cddone(struct cam_periph *periph, union ccb *done_ccb) * Otherwise, just say that we * couldn't attach. */ - if ((have_sense) && (asc || ascq) - && (error_code == SSD_CURRENT_ERROR)) - sprintf(announce_buf, - "fatal error: %s, %s " - "-- failed to attach " - "to device", - scsi_sense_key_text[sense_key], - scsi_sense_desc(asc,ascq, - &cgd.inq_data)); - else - sprintf(announce_buf, - "fatal error, failed" - " to attach to device"); /* * Just print out the error, not * the full probe message, when we * don't attach. */ - printf("%s%d: %s\n", - periph->periph_name, - periph->unit_number, - announce_buf); - scsi_sense_print(&done_ccb->csio); + if (have_sense) + scsi_sense_print( + &done_ccb->csio); + else { + xpt_print_path(periph->path); + printf("got CAM status %#x\n", + done_ccb->ccb_h.status); + } + xpt_print_path(periph->path); + printf("fatal error, failed" + " to attach to device"); /* * Free up resources. */ - cam_extend_release(cdperiphs, - periph->unit_number); cam_periph_invalidate(periph); - periph = NULL; + + announce_buf[0] = '\0'; } else { /* * Free up resources. */ - cam_extend_release(cdperiphs, - periph->unit_number); cam_periph_invalidate(periph); - periph = NULL; + announce_buf[0] = '\0'; } } } free(rdcap, M_TEMP); - if (periph != NULL) { + if (announce_buf[0] != '\0') xpt_announce_periph(periph, announce_buf); - softc->state = CD_STATE_NORMAL; - cam_periph_unlock(periph); - } - + softc->state = CD_STATE_NORMAL; if (softc->flags & CD_FLAG_CHANGER) cdchangerschedule(softc); + cam_periph_unlock(periph); + break; } case CD_CCB_WAITING: @@ -1809,11 +1820,9 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) struct cam_periph *periph; struct cd_softc *softc; - u_int8_t unit, part; - int error; + int error, unit; unit = dkunit(dev); - part = dkpart(dev); periph = cam_extend_get(cdperiphs, unit); if (periph == NULL) @@ -1824,9 +1833,12 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) softc = (struct cd_softc *)periph->softc; CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, - ("trying to do ioctl %#x\n", cmd)); + ("trying to do ioctl %#lx\n", cmd)); - error = 0; + error = cam_periph_lock(periph, PRIBIO | PCATCH); + + if (error != 0) + return(error); switch (cmd) { @@ -2451,6 +2463,8 @@ cdioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p) break; } + cam_periph_unlock(periph); + CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("leaving cdioctl\n")); return (error); @@ -2562,59 +2576,6 @@ cderror(union ccb *ccb, u_int32_t cam_flags, u_int32_t sense_flags) &softc->saved_ccb)); } -static int -cdgetdisklabel(dev_t dev) -{ - struct cam_periph *periph; - struct cd_softc *softc; - - periph = cam_extend_get(cdperiphs, dkunit(dev)); - - if (periph == NULL) - return (ENXIO); - - CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cdgetdisklabel\n")); - - softc = (struct cd_softc *)periph->softc; - - bzero(&softc->disklabel, sizeof(struct disklabel)); - - /* XXX Use the controller's geometry for this */ - softc->disklabel.d_type = DTYPE_SCSI; - sprintf(softc->disklabel.d_typename, "%s%d", periph->periph_name, - periph->unit_number); - strncpy(softc->disklabel.d_packname, "ficticious", 16); - softc->disklabel.d_secsize = softc->params.blksize; - softc->disklabel.d_nsectors = 100; - softc->disklabel.d_ntracks = 1; - softc->disklabel.d_ncylinders = (softc->params.disksize / 100) + 1; - softc->disklabel.d_secpercyl = 100; - softc->disklabel.d_secperunit = softc->params.disksize; - softc->disklabel.d_rpm = 300; - softc->disklabel.d_interleave = 1; - softc->disklabel.d_flags = D_REMOVABLE; - - /* - * Make partition 'a' cover the whole disk. This is a temporary - * compatibility hack. The 'a' partition should not exist, so - * the slice code won't create it. The slice code will make - * partition (RAW_PART + 'a') cover the whole disk and fill in - * some more defaults. - */ - softc->disklabel.d_npartitions = 1; - softc->disklabel.d_partitions[0].p_offset = 0; - softc->disklabel.d_partitions[0].p_size - = softc->params.disksize; - softc->disklabel.d_partitions[0].p_fstype = FS_OTHER; - - /* - * Signal to other users and routines that we now have a - * disklabel that represents the media (maybe) - */ - return (0); - -} - /* * Read table of contents */ diff --git a/sys/cam/scsi/scsi_da.c b/sys/cam/scsi/scsi_da.c index 3f3cd0f..de80c35 100644 --- a/sys/cam/scsi/scsi_da.c +++ b/sys/cam/scsi/scsi_da.c @@ -25,14 +25,14 @@ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * - * $Id: scsi_da.c,v 1.4 1998/09/19 04:59:35 gibbs Exp $ + * $Id: scsi_da.c,v 1.5 1998/09/20 07:17:11 gibbs Exp $ */ +#include "opt_hw_wdog.h" + #include <sys/param.h> -#include <sys/queue.h> #include <sys/systm.h> #include <sys/kernel.h> -#include <sys/types.h> #include <sys/buf.h> #include <sys/devicestat.h> #include <sys/dkbad.h> @@ -41,8 +41,8 @@ #include <sys/malloc.h> #include <sys/conf.h> -#include <machine/cons.h> /* For cncheckc */ -#include <machine/md_var.h> /* For Maxmem */ +#include <machine/cons.h> +#include <machine/md_var.h> #include <vm/vm.h> #include <vm/vm_prot.h> @@ -53,12 +53,8 @@ #include <cam/cam_extend.h> #include <cam/cam_periph.h> #include <cam/cam_xpt_periph.h> -#include <cam/cam_debug.h> -#include <cam/scsi/scsi_all.h> #include <cam/scsi/scsi_message.h> -#include <cam/scsi/scsi_da.h> - typedef enum { DA_STATE_PROBE, @@ -109,11 +105,6 @@ struct da_softc { struct disk_params params; struct diskslices *dk_slices; /* virtual drives */ union ccb saved_ccb; -#ifdef DEVFS - void *b_devfs_token; - void *c_devfs_token; - void *ctl_devfs_token; -#endif }; static d_open_t daopen; @@ -234,20 +225,17 @@ daopen(dev_t dev, int flags, int fmt, struct proc *p) } if ((softc->flags & DA_FLAG_PACK_INVALID) != 0) { - - if (softc->dk_slices != NULL) { - /* - * If any partition is open, but the disk has - * been invalidated, disallow further opens. - */ - if (dsisopen(softc->dk_slices)) { - cam_periph_unlock(periph); - return(ENXIO); - } - - /* Invalidate our pack information */ - dsgone(&softc->dk_slices); + /* + * If any partition is open, although the disk has + * been invalidated, disallow further opens. + */ + if (dsisopen(softc->dk_slices)) { + cam_periph_unlock(periph); + return (ENXIO); } + + /* Invalidate our pack information. */ + dsgone(&softc->dk_slices); softc->flags &= ~DA_FLAG_PACK_INVALID; } @@ -284,9 +272,25 @@ daopen(dev_t dev, int flags, int fmt, struct proc *p) } if (error == 0) { + struct ccb_getdev cgd; + /* Build label for whole disk. */ bzero(&label, sizeof(label)); label.d_type = DTYPE_SCSI; + + /* + * Grab the inquiry data to get the vendor and product names. + * Put them in the typename and packname for the label. + */ + xpt_setup_ccb(&cgd.ccb_h, periph->path, /*priority*/ 1); + cgd.ccb_h.func_code = XPT_GDEV_TYPE; + xpt_action((union ccb *)&cgd); + + strncpy(label.d_typename, cgd.inq_data.vendor, + min(SID_VENDOR_SIZE, sizeof(label.d_typename))); + strncpy(label.d_packname, cgd.inq_data.product, + min(SID_PRODUCT_SIZE, sizeof(label.d_packname))); + label.d_secsize = softc->params.secsize; label.d_nsectors = softc->params.secs_per_track; label.d_ntracks = softc->params.heads; @@ -347,6 +351,10 @@ daclose(dev_t dev, int flag, int fmt, struct proc *p) } dsclose(dev, fmt, softc->dk_slices); + if (dsisopen(softc->dk_slices)) { + cam_periph_unlock(periph); + return (0); + } ccb = cam_periph_getccb(periph, /*priority*/1); @@ -1210,53 +1218,32 @@ dadone(struct cam_periph *periph, union ccb *done_ccb) scsi_sense_desc(asc,ascq, &cgd.inq_data)); else { - /* - * If we have sense information, go - * ahead and print it out. - * Otherwise, just say that we - * couldn't attach. - */ - if ((have_sense) && (asc || ascq) - && (error_code == SSD_CURRENT_ERROR)) - sprintf(announce_buf, - "fatal error: %s, %s " - "-- failed to attach " - "to device", - scsi_sense_key_text[sense_key], - scsi_sense_desc(asc,ascq, - &cgd.inq_data)); - else - sprintf(announce_buf, - "fatal error, failed" - " to attach to device"); + if (have_sense) + scsi_sense_print( + &done_ccb->csio); + else { + xpt_print_path(periph->path); + printf("got CAM status %#x\n", + done_ccb->ccb_h.status); + } - /* - * Just print out the error, not - * the full probe message, when we - * don't attach. - */ - printf("%s%d: %s\n", - periph->periph_name, - periph->unit_number, - announce_buf); - scsi_sense_print(&done_ccb->csio); + xpt_print_path(periph->path); + printf("fatal error, failed" + " to attach to device"); /* * Free up resources. */ - cam_extend_release(daperiphs, - periph->unit_number); cam_periph_invalidate(periph); - periph = NULL; + announce_buf[0] = '\0'; } } } free(rdcap, M_TEMP); - if (periph != NULL) { + if (announce_buf[0] != '\0') xpt_announce_periph(periph, announce_buf); - softc->state = DA_STATE_NORMAL; - cam_periph_unlock(periph); - } + softc->state = DA_STATE_NORMAL; + cam_periph_unlock(periph); break; } case DA_CCB_WAITING: |