From owner-freebsd-standards Mon Aug 26 21:17:21 2002 Delivered-To: freebsd-standards@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 7D0D037B400; Mon, 26 Aug 2002 21:16:47 -0700 (PDT) Received: from panzer.kdm.org (panzer.kdm.org [216.160.178.169]) by mx1.FreeBSD.org (Postfix) with ESMTP id 2A4AC43E42; Mon, 26 Aug 2002 21:16:46 -0700 (PDT) (envelope-from ken@panzer.kdm.org) Received: from panzer.kdm.org (localhost [127.0.0.1]) by panzer.kdm.org (8.12.5/8.12.5) with ESMTP id g7R4GhKD039962; Mon, 26 Aug 2002 22:16:43 -0600 (MDT) (envelope-from ken@panzer.kdm.org) Received: (from ken@localhost) by panzer.kdm.org (8.12.5/8.12.5/Submit) id g7R4GhWM039961; Mon, 26 Aug 2002 22:16:43 -0600 (MDT) (envelope-from ken) Date: Mon, 26 Aug 2002 22:16:42 -0600 From: "Kenneth D. Merry" To: Bruce Evans Cc: "M. Warner Losh" , johan@FreeBSD.ORG, nsayer@quack.kfu.com, freebsd-scsi@FreeBSD.ORG, freebsd-standards@FreeBSD.ORG, sos@FreeBSD.ORG Subject: Re: kern/15608: acd0 / cd0 give inconsistent errors on empty tray open() Message-ID: <20020826221642.A39886@panzer.kdm.org> References: <20020822223203.A13222@panzer.kdm.org> <20020825164629.H14756-100000@gamplex.bde.org> Mime-Version: 1.0 Content-Type: multipart/mixed; boundary="qMm9M+Fa2AknHoGS" Content-Disposition: inline User-Agent: Mutt/1.2.5.1i In-Reply-To: <20020825164629.H14756-100000@gamplex.bde.org>; from bde@zeta.org.au on Sun, Aug 25, 2002 at 05:07:32PM +1000 Sender: owner-freebsd-standards@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG --qMm9M+Fa2AknHoGS Content-Type: text/plain; charset=us-ascii Content-Disposition: inline [ freebsd-gnats-submit taken out for now, so we don't clutter up the PR database too much with in-progress patches ] On Sun, Aug 25, 2002 at 17:07:32 +1000, Bruce Evans wrote: > On Thu, 22 Aug 2002, Kenneth D. Merry wrote: > > On Fri, Aug 23, 2002 at 12:41:28 +1000, Bruce Evans wrote: > > > I think the bug is that the open doesn't succeed. The device is > > > reported as being there at boot time, and there is enough of it there > > > to tell which parts of it aren't there, so why not open() it so that > > > you do things like ioctl() on it to close its door and make it there? > > > > There is no ioctl in the interface for loading a CD. None of the other > > ioctls, I think, make much sense without media in the drive. > > There is a CDIOCCLOSE which seems to be supported by acd and by some > unmaintained cdrom drivers by not by the scsi cdrom driver. Ahh, I missed that. > > The reason we need to do a read capacity in the open() routine, which is > > why the open fails when there is no media, is so we can fill in the > > d_secsize and d_secperunit fields in the disklabel. > > acdopen() calls acd_read_toc() which does similar things. When there is > no media, acd_read_toc() fails with the not quite right error EBUSY, but > acdopen() ignores this error and the open succeeds and you can try > CDIOCCLOSE() to attempt to load media. So it seems that acdopen() already > works like I want, and the EIO error reported earlier doesn't actually > occur for acdopen(). Well, here is a first pass at it. Let me know what you think. > dsopen() has similar issues. It attempts to read MBRs and disk labels > and can probably return EIO for read errors when there is no media or > bad media. One reason why the fd driver doesn't use the slice layer > is that I never got this working well enough for floppies. It is hard > to issue formatting ioctls when the open fails because the MBR is > unreadable. FWIW, if the slice code is setup to attempt to read labels off the disk, but there is no media in the drive (i.e. sector size and sectors per unit are 0, or it could be because p_size for the first partition is 0), it panics. (DSO_COMPATLABEL is set, and DSO_NOLABELS is cleared) If the slice code is setup not to attempt to read labels off the disk, it doesn't panic at least. Behavior of things like dd(1) is different, obviously, because it no longer fails in open() with an empty drive. e.g., new behavior is: ================ {nargothrond:/usr/home/ken:2:0} dd if=/dev/cd0c of=/dev/null bs=2k dd: /dev/cd0c: Device not configured 0+0 records in 0+0 records out 0 bytes transferred in 0.004522 secs (0 bytes/sec) ================ current behavior is: ================ {gondolin:/usr/home/ken:6:1} dd if=/dev/cd0c of=/dev/null bs=2k dd: /dev/cd0c: Device not configured ================ cdcontrol seems to get a better idea of what is going on when open() fails: ================ {gondolin:/usr/home/ken:7:1} cdcontrol cdcontrol: no CD device name specified, defaulting to /dev/cd0c Compact Disc Control utility, version 2.0 Type `?' for command list cdcontrol> info cdcontrol: no disc in drive /dev/cd0c cdcontrol> quit ================ When the ioctl fails instead of the open, it isn't quite as clear about what is going on: ================ {nargothrond:/usr/home/ken:3:1} cdcontrol cdcontrol: no CD device name specified, defaulting to /dev/cd0c Compact Disc Control utility, version 2.0 Type `?' for command list cdcontrol> info cdcontrol: getting toc header: Device not configured cdcontrol: Device not configured cdcontrol> quit ================ Ken -- Kenneth Merry ken@kdm.org --qMm9M+Fa2AknHoGS Content-Type: text/plain; charset=us-ascii Content-Disposition: attachment; filename="scsi_cd.c.20020826" ==== //depot/FreeBSD-ken/src/sys/cam/scsi/scsi_cd.c#23 - /usr/home/ken/perforce/FreeBSD-ken/src/sys/cam/scsi/scsi_cd.c ==== --- /tmp/tmp.15286.0 Mon Aug 26 21:59:38 2002 +++ /usr/home/ken/perforce/FreeBSD-ken/src/sys/cam/scsi/scsi_cd.c Mon Aug 26 21:56:21 2002 @@ -1,6 +1,6 @@ /* * Copyright (c) 1997 Justin T. Gibbs. - * Copyright (c) 1997, 1998, 1999, 2000, 2001 Kenneth D. Merry. + * Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002 Kenneth D. Merry. * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -94,7 +94,8 @@ CD_FLAG_CHANGER = 0x040, CD_FLAG_ACTIVE = 0x080, CD_FLAG_SCHED_ON_COMP = 0x100, - CD_FLAG_RETRY_UA = 0x200 + CD_FLAG_RETRY_UA = 0x200, + CD_FLAG_VALID_MEDIA = 0x400 } cd_flags; typedef enum { @@ -204,7 +205,8 @@ 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 cdcheckmedia(struct cam_periph *periph); +static int cdsize(struct cam_periph *periph, u_int32_t *size); static int cdfirsttrackisdata(struct cam_periph *periph); static int cdreadtoc(struct cam_periph *periph, u_int32_t mode, u_int32_t start, struct cd_toc_entry *data, @@ -229,7 +231,7 @@ u_int32_t etrack, u_int32_t eindex); static int cdpause(struct cam_periph *periph, u_int32_t go); static int cdstopunit(struct cam_periph *periph, u_int32_t eject); -static int cdstartunit(struct cam_periph *periph); +static int cdstartunit(struct cam_periph *periph, int load); static int cdreportkey(struct cam_periph *periph, struct dvd_authinfo *authinfo); static int cdsendkey(struct cam_periph *periph, @@ -858,11 +860,8 @@ static int cdopen(dev_t dev, int flags, int fmt, struct thread *td) { - struct disklabel *label; struct cam_periph *periph; struct cd_softc *softc; - struct ccb_getdev cgd; - u_int32_t size; int error; int s; @@ -891,72 +890,12 @@ if (cam_periph_acquire(periph) != CAM_REQ_CMP) return(ENXIO); - cdprevent(periph, PR_PREVENT); - - /* find out the size */ - if ((error = cdsize(dev, &size)) != 0) { - cdprevent(periph, PR_ALLOW); - cam_periph_unlock(periph); - cam_periph_release(periph); - return(error); - } - - /* - * If we get a non-zero return, revert back to not reading the - * label off the disk. The first track is likely audio, which - * won't have a disklabel. - */ - if ((error = cdfirsttrackisdata(periph)) != 0) { - softc->disk.d_dsflags &= ~DSO_COMPATLABEL; - softc->disk.d_dsflags |= DSO_NOLABELS; - error = 0; - } - - /* - * Build prototype label for whole disk. - * Should take information about different data tracks from the - * TOC and put it in the partition table. - */ - label = &softc->disk.d_label; - 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; - /* - * 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? + * Check for media, and set the appropriate flags. We don't bail + * if we don't have media, but then we don't allow anything but the + * CDIOCEJECT/CDIOCCLOSE ioctls if there is no media. */ - if ((softc->device_stats.flags & DEVSTAT_BS_UNAVAILABLE) != 0) - softc->device_stats.flags &= ~DEVSTAT_BS_UNAVAILABLE; - softc->device_stats.block_size = softc->params.blksize; + cdcheckmedia(periph); cam_periph_unlock(periph); @@ -1373,6 +1312,21 @@ } /* + * If we don't have valid media, look for it before trying to + * schedule the I/O. + */ + if ((softc->flags & CD_FLAG_VALID_MEDIA) == 0) { + int error; + + error = cdcheckmedia(periph); + if (error != 0) { + splx(s); + biofinish(bp, NULL, error); + return; + } + } + + /* * Place it in the queue of disk activities for this disk */ bioqdisksort(&softc->bio_queue, bp); @@ -1804,6 +1758,20 @@ if (error != 0) return(error); + /* + * If we don't have media loaded, check for it. If still don't + * have media loaded, we can only do a load or eject. + */ + if (((softc->flags & CD_FLAG_VALID_MEDIA) == 0) + && ((cmd != CDIOCCLOSE) + && (cmd != CDIOCEJECT))) { + error = cdcheckmedia(periph); + if (error != 0) { + cam_periph_unlock(periph); + return (error); + } + } + switch (cmd) { case CDIOCPLAYTRACKS: @@ -2381,7 +2349,10 @@ error = cdpause(periph, 0); break; case CDIOCSTART: - error = cdstartunit(periph); + error = cdstartunit(periph, 0); + break; + case CDIOCCLOSE: + error = cdstartunit(periph, 1); break; case CDIOCSTOP: error = cdstopunit(periph, 0); @@ -2482,18 +2453,103 @@ } static int -cdsize(dev_t dev, u_int32_t *size) +cdcheckmedia(struct cam_periph *periph) +{ + struct disklabel *label; + struct cd_softc *softc; + struct ccb_getdev cgd; + u_int32_t size; + int error; + + softc = (struct cd_softc *)periph->softc; + + cdprevent(periph, PR_PREVENT); + + /* + * Get the disc size and block size. If we can't get it, we don't + * have media, most likely. So we clear the valid media flag and + * make sure we're setup to use fake labels. + */ + if ((error = cdsize(periph, &size)) != 0) { + softc->flags &= ~CD_FLAG_VALID_MEDIA; + softc->disk.d_dsflags &= ~DSO_COMPATLABEL; + softc->disk.d_dsflags |= DSO_NOLABELS; + cdprevent(periph, PR_ALLOW); + return (error); + } else + softc->flags |= CD_FLAG_VALID_MEDIA; + + /* + * If we get a non-zero return, revert back to not reading the + * label off the disk. The first track is likely audio, which + * won't have a disklabel. + */ + if ((error = cdfirsttrackisdata(periph)) != 0) { + softc->disk.d_dsflags &= ~DSO_COMPATLABEL; + softc->disk.d_dsflags |= DSO_NOLABELS; + error = 0; + } else { + softc->disk.d_dsflags |= DSO_COMPATLABEL; + softc->disk.d_dsflags &= ~DSO_NOLABELS; + } + + /* + * Build prototype label for whole disk. + * Should take information about different data tracks from the + * TOC and put it in the partition table. + */ + label = &softc->disk.d_label; + 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; + + /* + * 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; + softc->device_stats.block_size = softc->params.blksize; + + return (error); +} + +static int +cdsize(struct cam_periph *periph, u_int32_t *size) { - struct cam_periph *periph; struct cd_softc *softc; union ccb *ccb; struct scsi_read_capacity_data *rcap_buf; int error; - periph = (struct cam_periph *)dev->si_drv1; - if (periph == NULL) - return (ENXIO); - CAM_DEBUG(periph->path, CAM_DEBUG_TRACE, ("entering cdsize\n")); softc = (struct cd_softc *)periph->softc; @@ -2999,7 +3055,7 @@ } static int -cdstartunit(struct cam_periph *periph) +cdstartunit(struct cam_periph *periph, int load) { union ccb *ccb; int error; @@ -3013,7 +3069,7 @@ /* cbfcnp */ cddone, /* tag_action */ MSG_SIMPLE_Q_TAG, /* start */ TRUE, - /* load_eject */ FALSE, + /* load_eject */ load, /* immediate */ FALSE, /* sense_len */ SSD_FULL_SIZE, /* timeout */ 50000); --qMm9M+Fa2AknHoGS-- To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-standards" in the body of the message From owner-freebsd-standards Thu Aug 29 9:39:33 2002 Delivered-To: freebsd-standards@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id C444437B400 for ; Thu, 29 Aug 2002 09:39:31 -0700 (PDT) Received: from hotmail.com (f226.law9.hotmail.com [64.4.9.226]) by mx1.FreeBSD.org (Postfix) with ESMTP id CF7E343E65 for ; Thu, 29 Aug 2002 09:39:30 -0700 (PDT) (envelope-from afeick@hotmail.com) Received: from mail pickup service by hotmail.com with Microsoft SMTPSVC; Thu, 29 Aug 2002 09:39:29 -0700 Received: from 64.65.149.102 by lw9fd.law9.hotmail.msn.com with HTTP; Thu, 29 Aug 2002 16:39:29 GMT X-Originating-IP: [64.65.149.102] From: "Anthony Feick" To: libstdc++@gcc.gnu.org, freebsd-standards@FreeBSD.org Subject: Status of libstdc++ on FreeBSD Date: Thu, 29 Aug 2002 11:39:29 -0500 Mime-Version: 1.0 Content-Type: text/plain; format=flowed Message-ID: X-OriginalArrivalTime: 29 Aug 2002 16:39:29.0758 (UTC) FILETIME=[A54B5FE0:01C24F7A] Sender: owner-freebsd-standards@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG I noticed that Wide Character/String Support has been updated, and nearly completed for FreeBSD 5.0. ( http://www.freebsd.org/projects/c99/ ) Has anyone had success getting (or even tried) getting libstdc++ to compile with wide character support ( _GLIBCPP_USE_WCHAR_T ) on FreeBSD 5.0??? _________________________________________________________________ Join the world’s largest e-mail service with MSN Hotmail. http://www.hotmail.com To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-standards" in the body of the message From owner-freebsd-standards Thu Aug 29 16:29:18 2002 Delivered-To: freebsd-standards@freebsd.org Received: from mx1.FreeBSD.org (mx1.FreeBSD.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 33F9F37B400 for ; Thu, 29 Aug 2002 16:29:16 -0700 (PDT) Received: from dilbert.robbins.dropbear.id.au (072.c.002.mel.iprimus.net.au [203.134.135.72]) by mx1.FreeBSD.org (Postfix) with ESMTP id C619243E3B for ; Thu, 29 Aug 2002 16:29:13 -0700 (PDT) (envelope-from tim@robbins.dropbear.id.au) Received: from dilbert.robbins.dropbear.id.au (m8c39wndciok7qr6@localhost [127.0.0.1]) by dilbert.robbins.dropbear.id.au (8.12.3/8.12.3) with ESMTP id g7TNSmEa026508; Fri, 30 Aug 2002 09:28:55 +1000 (EST) (envelope-from tim@dilbert.robbins.dropbear.id.au) Received: (from tim@localhost) by dilbert.robbins.dropbear.id.au (8.12.3/8.12.3/Submit) id g7TNSYHp026507; Fri, 30 Aug 2002 09:28:34 +1000 (EST) Date: Fri, 30 Aug 2002 09:28:21 +1000 From: Tim Robbins To: Anthony Feick Cc: freebsd-standards@FreeBSD.ORG Subject: Re: Status of libstdc++ on FreeBSD Message-ID: <20020830092821.A25882@dilbert.robbins.dropbear.id.au> References: Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5.1i In-Reply-To: ; from afeick@hotmail.com on Thu, Aug 29, 2002 at 11:39:29AM -0500 Sender: owner-freebsd-standards@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG On Thu, Aug 29, 2002 at 11:39:29AM -0500, Anthony Feick wrote: > I noticed that Wide Character/String Support has been updated, and nearly > completed for FreeBSD 5.0. > ( http://www.freebsd.org/projects/c99/ ) > > Has anyone had success getting (or even tried) getting libstdc++ to compile > with wide character support ( _GLIBCPP_USE_WCHAR_T ) on FreeBSD 5.0??? The header tries to bring functions that don't exist (wprintf, wcstod, etc.) into the `std' namespace and fails. I'm pretty sure that if you removed these lines: using ::fwprintf; using ::fwscanf; using ::swprintf; using ::swscanf; using ::vfwprintf; using ::vfwscanf; using ::vswprintf; using ::vswscanf; using ::vwprintf; using ::vwscanf; using ::wcscoll; using ::wcsftime; using ::wcstod; using ::wcstof; using ::wcstol; using ::wcstoul; using ::wcsxfrm; using ::wprintf; using ::wscanf; .. it would work. There are basically 3 groups of functions that aren't implemented: - formatted input/output (wprintf, wscanf, ..., wcsftime) - locale sensitive ordering (wcscoll, wcsxfrm) - string to number conversion (wcstol, wcstod, ...) With the exception of wcscoll/wcsxfrm, these functions are all trivial to implement inelegantly by copying the single-byte versions and replacing `char' with `wchar_t'. I was hoping to avoid duplicating ~2000 lines of code in this way, so I've held off implementing them. Tim To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-standards" in the body of the message