From owner-p4-projects@FreeBSD.ORG Fri Mar 31 18:02:23 2006 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 32D2E16A424; Fri, 31 Mar 2006 18:02:23 +0000 (UTC) X-Original-To: perforce@freebsd.org Delivered-To: perforce@freebsd.org Received: from mx1.FreeBSD.org (mx1.freebsd.org [216.136.204.125]) by hub.freebsd.org (Postfix) with ESMTP id 0A35916A422 for ; Fri, 31 Mar 2006 18:02:23 +0000 (UTC) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (repoman.freebsd.org [216.136.204.115]) by mx1.FreeBSD.org (Postfix) with ESMTP id 5529443D6A for ; Fri, 31 Mar 2006 18:02:03 +0000 (GMT) (envelope-from marcel@freebsd.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.1/8.13.1) with ESMTP id k2VI2267000192 for ; Fri, 31 Mar 2006 18:02:02 GMT (envelope-from marcel@freebsd.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.1/8.13.1/Submit) id k2VI22jK000189 for perforce@freebsd.org; Fri, 31 Mar 2006 18:02:02 GMT (envelope-from marcel@freebsd.org) Date: Fri, 31 Mar 2006 18:02:02 GMT Message-Id: <200603311802.k2VI22jK000189@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to marcel@freebsd.org using -f From: Marcel Moolenaar To: Perforce Change Reviews Cc: Subject: PERFORCE change 94360 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 31 Mar 2006 18:02:23 -0000 http://perforce.freebsd.org/chv.cgi?CH=94360 Change 94360 by marcel@marcel_nfs on 2006/03/31 18:01:36 IFC @94359 Affected files ... .. //depot/projects/uart/conf/files#56 integrate .. //depot/projects/uart/conf/files.powerpc#7 integrate .. //depot/projects/uart/dev/ata/ata-all.c#20 integrate .. //depot/projects/uart/dev/ata/ata-all.h#14 integrate .. //depot/projects/uart/dev/ata/ata-disk.c#14 integrate .. //depot/projects/uart/dev/ata/ata-queue.c#17 integrate .. //depot/projects/uart/dev/ata/ata-usb.c#3 integrate .. //depot/projects/uart/dev/ata/atapi-cam.c#11 integrate .. //depot/projects/uart/dev/ata/atapi-cd.c#18 integrate .. //depot/projects/uart/dev/scc/scc_bfe_sbus.c#6 integrate .. //depot/projects/uart/dev/sound/pcm/sound.c#10 integrate .. //depot/projects/uart/dev/sound/pcm/vchan.c#9 integrate .. //depot/projects/uart/dev/uart/uart_cpu_powerpc.c#1 branch .. //depot/projects/uart/kern/subr_taskqueue.c#8 integrate .. //depot/projects/uart/kern/vfs_bio.c#22 integrate .. //depot/projects/uart/kern/vfs_default.c#16 integrate .. //depot/projects/uart/kern/vfs_lookup.c#11 integrate .. //depot/projects/uart/kern/vfs_mount.c#21 integrate .. //depot/projects/uart/kern/vfs_subr.c#25 integrate .. //depot/projects/uart/kern/vfs_syscalls.c#24 integrate .. //depot/projects/uart/kern/vfs_vnops.c#17 integrate .. //depot/projects/uart/modules/Makefile#31 integrate .. //depot/projects/uart/nfsserver/nfs_serv.c#11 integrate .. //depot/projects/uart/nfsserver/nfs_srvsubs.c#8 integrate .. //depot/projects/uart/powerpc/include/bus.h#8 integrate .. //depot/projects/uart/sys/ata.h#10 integrate .. //depot/projects/uart/sys/buf.h#15 integrate .. //depot/projects/uart/sys/mount.h#16 integrate .. //depot/projects/uart/ufs/ffs/ffs_snapshot.c#14 integrate .. //depot/projects/uart/ufs/ffs/ffs_vfsops.c#19 integrate Differences ... ==== //depot/projects/uart/conf/files#56 (text+ko) ==== @@ -1,4 +1,4 @@ -# $FreeBSD: src/sys/conf/files,v 1.1106 2006/03/30 18:39:24 marcel Exp $ +# $FreeBSD: src/sys/conf/files,v 1.1107 2006/03/30 21:39:36 marcel Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -831,7 +831,7 @@ dev/sbsh/if_sbsh.c optional sbsh dev/scc/scc_if.m optional scc dev/scc/scc_bfe_ebus.c optional scc ebus -dev/scc/scc_bfe_sbus.c optional scc sbus +dev/scc/scc_bfe_sbus.c optional scc fhc | scc sbus dev/scc/scc_core.c optional scc dev/scc/scc_dev_sab82532.c optional scc dev/scc/scc_dev_z8530.c optional scc ==== //depot/projects/uart/conf/files.powerpc#7 (text+ko) ==== @@ -1,7 +1,7 @@ # This file tells config what files go into building a kernel, # files marked standard are always included. # -# $FreeBSD: src/sys/conf/files.powerpc,v 1.49 2006/03/05 22:52:16 yar Exp $ +# $FreeBSD: src/sys/conf/files.powerpc,v 1.50 2006/03/31 01:42:55 marcel Exp $ # # The long compile-with and dependency lines are required because of # limitations in config: backslash-newline doesn't work in strings, and @@ -27,6 +27,7 @@ dev/syscons/scvtb.c optional sc dev/syscons/syscons.c optional sc dev/syscons/sysmouse.c optional sc +dev/uart/uart_cpu_powerpc.c optional uart geom/geom_apple.c standard kern/syscalls.c optional ktr powerpc/powerpc/atomic.S standard ==== //depot/projects/uart/dev/ata/ata-all.c#20 (text+ko) ==== @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/ata/ata-all.c,v 1.270 2006/03/10 12:20:53 sos Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/ata/ata-all.c,v 1.271 2006/03/31 08:09:04 sos Exp $"); #include "opt_ata.h" #include @@ -485,7 +485,11 @@ if (ioc_request->flags & ATA_CMD_WRITE) request->flags |= ATA_R_WRITE; ata_queue_request(request); - if (!(request->flags & ATA_R_ATAPI)) { + if (request->flags & ATA_R_ATAPI) { + bcopy(&request->u.atapi.sense, &ioc_request->u.atapi.sense, + sizeof(struct atapi_sense)); + } + else { ioc_request->u.ata.command = request->u.ata.command; ioc_request->u.ata.feature = request->u.ata.feature; ioc_request->u.ata.lba = request->u.ata.lba; ==== //depot/projects/uart/dev/ata/ata-all.h#14 (text+ko) ==== @@ -23,7 +23,7 @@ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * - * $FreeBSD: src/sys/dev/ata/ata-all.h,v 1.116 2006/03/08 16:39:01 sos Exp $ + * $FreeBSD: src/sys/dev/ata/ata-all.h,v 1.117 2006/03/31 08:09:04 sos Exp $ */ /* ATA register defines */ @@ -53,24 +53,7 @@ #define ATA_E_MC 0x20 /* media changed */ #define ATA_E_UNC 0x40 /* uncorrectable data */ #define ATA_E_ICRC 0x80 /* UDMA crc error */ -#define ATA_E_MASK 0x0f /* error mask */ -#define ATA_SK_MASK 0xf0 /* sense key mask */ -#define ATA_SK_NO_SENSE 0x00 /* no specific sense key info */ -#define ATA_SK_RECOVERED_ERROR 0x10 /* command OK, data recovered */ -#define ATA_SK_NOT_READY 0x20 /* no access to drive */ -#define ATA_SK_MEDIUM_ERROR 0x30 /* non-recovered data error */ -#define ATA_SK_HARDWARE_ERROR 0x40 /* non-recoverable HW failure */ -#define ATA_SK_ILLEGAL_REQUEST 0x50 /* invalid command param(s) */ -#define ATA_SK_UNIT_ATTENTION 0x60 /* media changed */ -#define ATA_SK_DATA_PROTECT 0x70 /* write protect */ -#define ATA_SK_BLANK_CHECK 0x80 /* blank check */ -#define ATA_SK_VENDOR_SPECIFIC 0x90 /* vendor specific skey */ -#define ATA_SK_COPY_ABORTED 0xa0 /* copy aborted */ -#define ATA_SK_ABORTED_COMMAND 0xb0 /* command aborted, try again */ -#define ATA_SK_EQUAL 0xc0 /* equal */ -#define ATA_SK_VOLUME_OVERFLOW 0xd0 /* volume overflow */ -#define ATA_SK_MISCOMPARE 0xe0 /* data dont match the medium */ -#define ATA_SK_RESERVED 0xf0 +#define ATA_E_ATAPI_SENSE_MASK 0xf0 /* ATAPI sense key mask */ #define ATA_IREASON 9 /* (R) interrupt reason */ #define ATA_I_CMD 0x01 /* cmd (1) | data (0) */ @@ -284,7 +267,8 @@ #define ATA_PC98_BANKADDR_RID 9 #define ATA_IRQ_RID 0 #define ATA_DEV(device) ((device == ATA_MASTER) ? 0 : 1) -#define ATA_CFA_MAGIC 0x848A +#define ATA_CFA_MAGIC1 0x844A +#define ATA_CFA_MAGIC2 0x848A #define ATAPI_MAGIC_LSB 0x14 #define ATAPI_MAGIC_MSB 0xeb #define ATAPI_P_READ (ATA_S_DRQ | ATA_I_IN) @@ -298,28 +282,6 @@ #define ATA_OP_FINISHED 1 #define ATA_MAX_28BIT_LBA 268435455UL -/* ATAPI request sense structure */ -struct atapi_sense { - u_int8_t error_code :7; /* current or deferred errors */ - u_int8_t valid :1; /* follows ATAPI spec */ - u_int8_t segment; /* Segment number */ - u_int8_t sense_key :4; /* sense key */ - u_int8_t reserved2_4 :1; /* reserved */ - u_int8_t ili :1; /* incorrect length indicator */ - u_int8_t eom :1; /* end of medium */ - u_int8_t filemark :1; /* filemark */ - u_int32_t cmd_info __packed; /* cmd information */ - u_int8_t sense_length; /* additional sense len (n-7) */ - u_int32_t cmd_specific_info __packed; /* additional cmd spec info */ - u_int8_t asc; /* additional sense code */ - u_int8_t ascq; /* additional sense code qual */ - u_int8_t replaceable_unit_code; /* replaceable unit code */ - u_int8_t sk_specific :7; /* sense key specific */ - u_int8_t sksv :1; /* sense key specific info OK */ - u_int8_t sk_specific1; /* sense key specific */ - u_int8_t sk_specific2; /* sense key specific */ -}; - /* structure used for composite atomic operations */ #define MAX_COMPOSITES 32 /* u_int32_t bits */ struct ata_composite { @@ -348,9 +310,8 @@ } ata; struct { u_int8_t ccb[16]; /* ATAPI command block */ - struct atapi_sense sense_data; /* ATAPI request sense data */ - u_int8_t sense_key; /* ATAPI request sense key */ - u_int8_t sense_cmd; /* ATAPI saved command */ + struct atapi_sense sense; /* ATAPI request sense data */ + u_int8_t saved_cmd; /* ATAPI saved command */ } atapi; } u; u_int32_t bytecount; /* bytes to transfer */ ==== //depot/projects/uart/dev/ata/ata-disk.c#14 (text+ko) ==== @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/ata/ata-disk.c,v 1.196 2006/03/09 08:34:44 sos Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/ata/ata-disk.c,v 1.197 2006/03/31 08:09:04 sos Exp $"); #include "opt_ata.h" #include @@ -71,7 +71,8 @@ struct ata_device *atadev = device_get_softc(dev); if (!(atadev->param.config & ATA_PROTO_ATAPI) || - (atadev->param.config == ATA_CFA_MAGIC)) + (atadev->param.config == ATA_CFA_MAGIC1) || + (atadev->param.config == ATA_CFA_MAGIC2)) return 0; else return ENXIO; @@ -295,8 +296,14 @@ struct bio bp; /* length zero is special and really means flush buffers to media */ - if (!length) - return ata_controlcmd(dp->d_drv1, ATA_FLUSHCACHE, 0, 0, 0); + if (!length) { + struct ata_device *atadev = device_get_softc(dp->d_drv1); + int error = 0; + + if (atadev->param.support.command2 & ATA_SUPPORT_FLUSHCACHE) + error = ata_controlcmd(dp->d_drv1, ATA_FLUSHCACHE, 0, 0, 0); + return error; + } bzero(&bp, sizeof(struct bio)); bp.bio_disk = dp; ==== //depot/projects/uart/dev/ata/ata-queue.c#17 (text+ko) ==== @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/ata/ata-queue.c,v 1.62 2006/03/09 10:25:35 sos Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/ata/ata-queue.c,v 1.63 2006/03/31 08:09:05 sos Exp $"); #include "opt_ata.h" #include @@ -51,13 +51,20 @@ void ata_queue_request(struct ata_request *request) { - struct ata_channel *ch = device_get_softc(device_get_parent(request->dev)); + struct ata_channel *ch; - /* mark request as virgin (this might be a ATA_R_REQUEUE) */ + /* treat request as virgin (this might be an ATA_R_REQUEUE) */ request->result = request->status = request->error = 0; - request->parent = device_get_parent(request->dev); + + /* check that that the device is still valid */ + if (!(request->parent = device_get_parent(request->dev))) { + request->result = ENXIO; + if (request->callback) + (request->callback)(request); + return; + } + ch = device_get_softc(request->parent); callout_init_mtx(&request->callout, &ch->state_mtx, CALLOUT_RETURNUNLOCKED); - if (!request->callback && !(request->flags & ATA_R_REQUEUE)) sema_init(&request->done, 0, "ATA request done"); @@ -368,16 +375,15 @@ break; /* if we have a sensekey -> request sense from device */ - if (request->error & ATA_SK_MASK && - request->u.atapi.ccb[0] != ATAPI_REQUEST_SENSE) { + if ((request->error & ATA_E_ATAPI_SENSE_MASK) && + (request->u.atapi.ccb[0] != ATAPI_REQUEST_SENSE)) { static u_int8_t ccb[16] = { ATAPI_REQUEST_SENSE, 0, 0, 0, sizeof(struct atapi_sense), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; - request->u.atapi.sense_key = request->error; - request->u.atapi.sense_cmd = request->u.atapi.ccb[0]; + request->u.atapi.saved_cmd = request->u.atapi.ccb[0]; bcopy(ccb, request->u.atapi.ccb, 16); - request->data = (caddr_t)&request->u.atapi.sense_data; + request->data = (caddr_t)&request->u.atapi.sense; request->bytecount = sizeof(struct atapi_sense); request->donecount = 0; request->transfersize = sizeof(struct atapi_sense); @@ -389,21 +395,21 @@ return; } - switch (request->u.atapi.sense_key & ATA_SK_MASK) { - case ATA_SK_RECOVERED_ERROR: + switch (request->u.atapi.sense.key & ATA_SENSE_KEY_MASK) { + case ATA_SENSE_RECOVERED_ERROR: device_printf(request->dev, "WARNING - %s recovered error\n", ata_cmd2str(request)); /* FALLTHROUGH */ - case ATA_SK_NO_SENSE: + case ATA_SENSE_NO_SENSE: request->result = 0; break; - case ATA_SK_NOT_READY: + case ATA_SENSE_NOT_READY: request->result = EBUSY; break; - case ATA_SK_UNIT_ATTENTION: + case ATA_SENSE_UNIT_ATTENTION: atadev->flags |= ATA_D_MEDIA_CHANGED; request->result = EIO; break; @@ -416,22 +422,19 @@ device_printf(request->dev, "FAILURE - %s %s asc=0x%02x ascq=0x%02x ", ata_cmd2str(request), ata_skey2str( - (request->u.atapi.sense_key & ATA_SK_MASK) >> 4), - request->u.atapi.sense_data.asc, - request->u.atapi.sense_data.ascq); - if (request->u.atapi.sense_data.sksv) - printf("sks=0x%02x 0x%02x 0x%02x ", - request->u.atapi.sense_data.sk_specific, - request->u.atapi.sense_data.sk_specific1, - request->u.atapi.sense_data.sk_specific2); - printf("error=%b\n", - (request->u.atapi.sense_key & ATA_E_MASK), - "\20\4MEDIA_CHANGE_REQUEST\3ABORTED" - "\2NO_MEDIA\1ILLEGAL_LENGTH"); + (request->u.atapi.sense.key & ATA_SENSE_KEY_MASK)), + request->u.atapi.sense.asc, + request->u.atapi.sense.ascq); + if (request->u.atapi.sense.specific & ATA_SENSE_SPEC_VALID) + printf("sks=0x%02x 0x%02x 0x%02x\n", + request->u.atapi.sense.specific & ATA_SENSE_SPEC_MASK, + request->u.atapi.sense.specific1, + request->u.atapi.sense.specific2); } - if ((request->u.atapi.sense_key ? - request->u.atapi.sense_key : request->error) & ATA_E_MASK) + if ((request->u.atapi.sense.key & ATA_SENSE_KEY_MASK ? + request->u.atapi.sense.key & ATA_SENSE_KEY_MASK : + request->error)) request->result = EIO; } @@ -625,8 +628,8 @@ static char buffer[20]; if (request->flags & ATA_R_ATAPI) { - switch (request->u.atapi.sense_key ? - request->u.atapi.sense_cmd : request->u.atapi.ccb[0]) { + switch (request->u.atapi.sense.key ? + request->u.atapi.saved_cmd : request->u.atapi.ccb[0]) { case 0x00: return ("TEST_UNIT_READY"); case 0x01: return ("REZERO"); case 0x03: return ("REQUEST_SENSE"); ==== //depot/projects/uart/dev/ata/ata-usb.c#3 (text) ==== @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/ata/ata-usb.c,v 1.3 2006/03/18 13:14:38 sos Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/ata/ata-usb.c,v 1.4 2006/03/31 08:09:05 sos Exp $"); #include "opt_ata.h" #include @@ -683,8 +683,7 @@ else if (sc->csw.status == CSWSTATUS_FAILED) { if (atausbdebug) device_printf(sc->dev, "CSWSTATUS_FAILED\n"); - //request->result = ENODEV; - request->error = ATA_SK_RESERVED; + request->error = ATA_E_ATAPI_SENSE_MASK ; sc->state = ATAUSB_S_IDLE; ata_interrupt(device_get_softc(request->parent)); return; @@ -824,9 +823,6 @@ *ptr = ntohs(*ptr); request->result = 0; } - if ((request->flags & ATA_R_ATAPI) && - (request->u.atapi.ccb[0] == ATAPI_REQUEST_SENSE)) - request->u.atapi.sense_key = request->u.atapi.sense_data.sense_key << 4; return ATA_OP_FINISHED; } ==== //depot/projects/uart/dev/ata/atapi-cam.c#11 (text+ko) ==== @@ -27,7 +27,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/ata/atapi-cam.c,v 1.43 2005/10/31 15:41:18 rwatson Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/ata/atapi-cam.c,v 1.44 2006/03/31 08:09:05 sos Exp $"); #include #include @@ -661,7 +661,7 @@ csio = &hcb->ccb->csio; #ifdef CAMDEBUG -# define err (request->u.atapi.sense_key) +# define err (request->u.atapi.sense.key) if (CAM_DEBUGGED(csio->ccb_h.path, CAM_DEBUG_CDB)) { printf("atapi_cb: hcb@%p error = %02x: (sk = %02x%s%s%s)\n", hcb, err, err >> 4, @@ -704,7 +704,7 @@ /* The ATA driver has already requested sense for us. */ if (request->error == 0) { /* The ATA autosense suceeded. */ - bcopy (&request->u.atapi.sense_data, &csio->sense_data, sizeof(struct atapi_sense)); + bcopy (&request->u.atapi.sense, &csio->sense_data, sizeof(struct atapi_sense)); csio->ccb_h.status |= CAM_AUTOSNS_VALID; } #endif ==== //depot/projects/uart/dev/ata/atapi-cd.c#18 (text+ko) ==== @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/ata/atapi-cd.c,v 1.187 2006/03/08 10:14:39 sos Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/ata/atapi-cd.c,v 1.188 2006/03/31 08:09:05 sos Exp $"); #include "opt_ata.h" #include @@ -702,10 +702,10 @@ request->timeout = 5; ata_queue_request(request); if (!request->error && - (request->u.atapi.sense_data.sense_key == 2 || - request->u.atapi.sense_data.sense_key == 7) && - request->u.atapi.sense_data.asc == 4 && - request->u.atapi.sense_data.ascq == 1) + (request->u.atapi.sense.key == 2 || + request->u.atapi.sense.key == 7) && + request->u.atapi.sense.asc == 4 && + request->u.atapi.sense.ascq == 1) tsleep(&timeout, PRIBIO, "acdld", hz / 2); else break; @@ -1008,7 +1008,7 @@ cdp->disk_size, cdp->block_size, cdp->toc.hdr.ending_track-cdp->toc.hdr.starting_track+1); if (cdp->toc.tab[0].control & 4) - printf("%dMB\n", cdp->disk_size / 512); + printf("%dMB\n", cdp->disk_size * cdp->block_size / 1048576); else printf("%d:%d audio\n", cdp->disk_size / 75 / 60, cdp->disk_size / 75 % 60); @@ -1234,9 +1234,9 @@ request->flags = ATA_R_ATAPI | ATA_R_READ; request->timeout = 30; ata_queue_request(request); - if (!request->error && request->u.atapi.sense_data.sksv) - *finished = ((request->u.atapi.sense_data.sk_specific2 | - (request->u.atapi.sense_data.sk_specific1<<8))*100)/65535; + if (!request->error && request->u.atapi.sense.error & ATA_SENSE_VALID) + *finished = ((request->u.atapi.sense.specific2 | + (request->u.atapi.sense.specific1 << 8)) * 100) / 65535; else *finished = 0; ata_free_request(request); ==== //depot/projects/uart/dev/scc/scc_bfe_sbus.c#6 (text+ko) ==== @@ -25,7 +25,7 @@ */ #include -__FBSDID("$FreeBSD: src/sys/dev/scc/scc_bfe_sbus.c,v 1.1 2006/03/30 18:33:22 marcel Exp $"); +__FBSDID("$FreeBSD: src/sys/dev/scc/scc_bfe_sbus.c,v 1.2 2006/03/31 17:39:49 marcel Exp $"); #include #include @@ -81,4 +81,5 @@ sizeof(struct scc_softc), }; +DRIVER_MODULE(puc, fhc, puc_sbus_driver, puc_devclass, 0, 0); DRIVER_MODULE(scc, sbus, scc_sbus_driver, scc_devclass, 0, 0); ==== //depot/projects/uart/dev/sound/pcm/sound.c#10 (text+ko) ==== @@ -32,7 +32,7 @@ #include "feeder_if.h" -SND_DECLARE_FILE("$FreeBSD: src/sys/dev/sound/pcm/sound.c,v 1.102 2006/03/22 20:50:04 ariff Exp $"); +SND_DECLARE_FILE("$FreeBSD: src/sys/dev/sound/pcm/sound.c,v 1.103 2006/03/31 10:36:36 ariff Exp $"); devclass_t pcm_devclass; @@ -53,7 +53,7 @@ struct sysctl_ctx_list * snd_sysctl_tree(device_t dev) { - struct snddev_info *d = device_get_softc(dev); + struct snddev_info *d = device_get_softc(dev); return &d->sysctl_tree; } @@ -61,7 +61,7 @@ struct sysctl_oid * snd_sysctl_tree_top(device_t dev) { - struct snddev_info *d = device_get_softc(dev); + struct snddev_info *d = device_get_softc(dev); return d->sysctl_tree_top; } @@ -158,22 +158,128 @@ return d->fakechan; } +static int +pcm_setvchans(struct snddev_info *d, int newcnt) +{ + struct snddev_channel *sce = NULL; + struct pcm_channel *c = NULL; + int err = 0, vcnt, dcnt, i; + + pcm_inprog(d, 1); + + if (!(d->flags & SD_F_AUTOVCHAN)) { + err = EINVAL; + goto setvchans_out; + } + + vcnt = d->vchancount; + dcnt = d->playcount + d->reccount; + + if (newcnt < 0 || (dcnt + newcnt) > (PCMMAXCHAN + 1)) { + err = E2BIG; + goto setvchans_out; + } + + dcnt += vcnt; + + if (newcnt > vcnt) { + /* add new vchans - find a parent channel first */ + SLIST_FOREACH(sce, &d->channels, link) { + c = sce->channel; + CHN_LOCK(c); + if (c->direction == PCMDIR_PLAY && + ((c->flags & CHN_F_HAS_VCHAN) || + (vcnt == 0 && + !(c->flags & (CHN_F_BUSY | CHN_F_VIRTUAL))))) + goto addok; + CHN_UNLOCK(c); + } + err = EBUSY; + goto setvchans_out; +addok: + c->flags |= CHN_F_BUSY; + while (err == 0 && newcnt > vcnt) { + if (dcnt > PCMMAXCHAN) { + device_printf(d->dev, "%s: Maximum channel reached.\n", __func__); + break; + } + err = vchan_create(c); + if (err == 0) { + vcnt++; + dcnt++; + } else if (err == E2BIG && newcnt > vcnt) + device_printf(d->dev, "%s: err=%d Maximum channel reached.\n", __func__, err); + } + if (vcnt == 0) + c->flags &= ~CHN_F_BUSY; + CHN_UNLOCK(c); + } else if (newcnt < vcnt) { +#define ORPHAN_CDEVT(cdevt) \ + ((cdevt) == NULL || ((cdevt)->si_drv1 == NULL && \ + (cdevt)->si_drv2 == NULL)) + while (err == 0 && newcnt < vcnt) { + i = 0; + SLIST_FOREACH(sce, &d->channels, link) { + c = sce->channel; + CHN_LOCK(c); + if (c->direction == PCMDIR_PLAY && + (c->flags & CHN_F_VIRTUAL) && + (i++ == newcnt)) { + if (!(c->flags & CHN_F_BUSY) && + ORPHAN_CDEVT(sce->dsp_devt) && + ORPHAN_CDEVT(sce->dspW_devt) && + ORPHAN_CDEVT(sce->audio_devt) && + ORPHAN_CDEVT(sce->dspr_devt)) + goto remok; + /* + * Either we're busy, or our cdev + * has been stolen by dsp_clone(). + * Skip, and increase newcnt. + */ + if (!(c->flags & CHN_F_BUSY)) + device_printf(d->dev, + "%s: <%s> somebody steal my cdev!\n", + __func__, c->name); + newcnt++; + } + CHN_UNLOCK(c); + } + if (vcnt != newcnt) + err = EBUSY; + break; +remok: + CHN_UNLOCK(c); + err = vchan_destroy(c); + if (err == 0) + vcnt--; + else + device_printf(d->dev, + "%s: WARNING: vchan_destroy() failed!", + __func__); + } + } + +setvchans_out: + pcm_inprog(d, -1); + return err; +} + /* return error status and a locked channel */ int pcm_chnalloc(struct snddev_info *d, struct pcm_channel **ch, int direction, pid_t pid, int chnum) { struct pcm_channel *c; - struct snddev_channel *sce; - int err, ret; + struct snddev_channel *sce; + int err; retry_chnalloc: - ret = ENODEV; + err = ENODEV; /* scan for a free channel */ SLIST_FOREACH(sce, &d->channels, link) { c = sce->channel; CHN_LOCK(c); - if ((c->direction == direction) && !(c->flags & CHN_F_BUSY)) { + if (c->direction == direction && !(c->flags & CHN_F_BUSY)) { if (chnum < 0 || sce->chan_num == chnum) { c->flags |= CHN_F_BUSY; c->pid = pid; @@ -191,7 +297,7 @@ CHN_UNLOCK(c); return err; } else if (c->direction == direction && (c->flags & CHN_F_BUSY)) - ret = EBUSY; + err = EBUSY; CHN_UNLOCK(c); } @@ -199,25 +305,14 @@ if (chnum == -1 && direction == PCMDIR_PLAY && d->vchancount > 0 && d->vchancount < snd_maxautovchans && d->devcount <= PCMMAXCHAN) { - /* try to create a vchan */ - SLIST_FOREACH(sce, &d->channels, link) { - c = sce->channel; - CHN_LOCK(c); - if ((c->flags & CHN_F_HAS_VCHAN) && - !SLIST_EMPTY(&c->children)) { - err = vchan_create(c); - CHN_UNLOCK(c); - if (!err) { - chnum = -2; - goto retry_chnalloc; - } else - device_printf(d->dev, "%s: vchan_create(%s) == %d\n", __func__, c->name, err); - } else - CHN_UNLOCK(c); + err = pcm_setvchans(d, d->vchancount + 1); + if (err == 0) { + chnum = -2; + goto retry_chnalloc; } } - return ret; + return err; } /* release a locked channel and unlock it */ @@ -261,66 +356,10 @@ static void pcm_setmaxautovchans(struct snddev_info *d, int num) { - struct pcm_channel *c, *ch; - struct snddev_channel *sce; - int err, done; - - /* - * XXX WOAH... NEED SUPER CLEANUP!!! - * Robust, yet confusing. Understanding these will - * cause your brain spinning like a Doki Doki Dynamo. - */ - if (num > 0 && d->vchancount == 0) { - SLIST_FOREACH(sce, &d->channels, link) { - c = sce->channel; - CHN_LOCK(c); - if ((c->direction == PCMDIR_PLAY) && - (c->flags & (CHN_F_BUSY | CHN_F_VIRTUAL)) == 0 && - SLIST_EMPTY(&c->children)) { - c->flags |= CHN_F_BUSY; - err = vchan_create(c); - if (err) { - c->flags &= ~CHN_F_BUSY; - device_printf(d->dev, "%s: vchan_create(%s) == %d\n", __func__, c->name, err); - } else { - CHN_UNLOCK(c); - return; - } - } - CHN_UNLOCK(c); - } - return; - } - if (num == 0 && d->vchancount > 0) { - /* - * XXX Keep retrying... - */ - for (done = 0; done < 1024; done++) { - ch = NULL; - SLIST_FOREACH(sce, &d->channels, link) { - c = sce->channel; - CHN_LOCK(c); - if (c->direction == PCMDIR_PLAY && - !(c->flags & CHN_F_BUSY) && - (c->flags & CHN_F_VIRTUAL)) { - ch = c; - break; - } - CHN_UNLOCK(c); - } - if (ch != NULL) { - CHN_UNLOCK(ch); - snd_mtxlock(d->lock); - err = vchan_destroy(ch); - if (err) - device_printf(d->dev, "vchan_destroy(%s) == %d\n", - ch->name, err); - snd_mtxunlock(d->lock); - } else - return; - } - return; - } + if (num > 0 && d->vchancount == 0) + pcm_setvchans(d, 1); + else if (num == 0 && d->vchancount > 0) + pcm_setvchans(d, 0); } #ifdef USING_DEVFS @@ -355,18 +394,14 @@ v = snd_maxautovchans; error = sysctl_handle_int(oidp, &v, sizeof(v), req); if (error == 0 && req->newptr != NULL) { - if (v < 0 || v > (PCMMAXCHAN + 1)) - return EINVAL; + if (v < 0 || v > PCMMAXCHAN) + return E2BIG; if (pcm_devclass != NULL && v != snd_maxautovchans) { for (i = 0; i < devclass_get_maxunit(pcm_devclass); i++) { d = devclass_get_softc(pcm_devclass, i); if (!d) continue; - if (d->flags & SD_F_AUTOVCHAN) { - if (pcm_inprog(d, 1) == 1) - pcm_setmaxautovchans(d, v); - pcm_inprog(d, -1); - } + pcm_setmaxautovchans(d, v); } } snd_maxautovchans = v; @@ -380,9 +415,9 @@ pcm_chn_create(struct snddev_info *d, struct pcm_channel *parent, kobj_class_t cls, int dir, void *devinfo) { struct snddev_channel *sce; - struct pcm_channel *ch, *tmpch; + struct pcm_channel *ch, *c; char *dirs; - u_int32_t flsearch = 0; + uint32_t flsearch = 0; int direction, err, rpnum, *pnum; switch(dir) { @@ -424,23 +459,18 @@ ch->num = 0; rpnum = 0; SLIST_FOREACH(sce, &d->channels, link) { - if (sce == NULL || sce->channel == NULL) + c = sce->channel; + if (direction != c->direction || + (c->flags & CHN_F_VIRTUAL) != flsearch) continue; - tmpch = sce->channel; - if (direction != tmpch->direction || - (tmpch->flags & CHN_F_VIRTUAL) != flsearch) - continue; - if (ch->num == tmpch->num) + if (ch->num == c->num) ch->num++; else { - /* - * Channel numbering screwed. Bail out, and do the - * hard way lookup. - */ +#if 0 device_printf(d->dev, - "%s: channel numbering dirs=%s screwed.\n", - __func__, dirs); - ch->num = 0; + "%s: %s channel numbering screwed (Expect: %d, Got: %d)\n", + __func__, dirs, ch->num, c->num); +#endif goto retry_num_search; } rpnum++; @@ -449,13 +479,11 @@ retry_num_search: rpnum = 0; SLIST_FOREACH(sce, &d->channels, link) { - if (sce == NULL || sce->channel == NULL) + c = sce->channel; + if (direction != c->direction || + (c->flags & CHN_F_VIRTUAL) != flsearch) continue; - tmpch = sce->channel; - if (direction != tmpch->direction || - (tmpch->flags & CHN_F_VIRTUAL) != flsearch) - continue; - if (ch->num == tmpch->num) { + if (ch->num == c->num) { ch->num++; goto retry_num_search; } @@ -464,7 +492,7 @@ retry_num_search_out: if (*pnum != rpnum) { device_printf(d->dev, - "%s: pnum screwed : dirs=%s, pnum=%d, rpnum=%d\n", + "%s: WARNING: pnum screwed : dirs=%s, pnum=%d, rpnum=%d\n", __func__, dirs, *pnum, rpnum); *pnum = rpnum; } @@ -514,17 +542,16 @@ int pcm_chn_add(struct snddev_info *d, struct pcm_channel *ch) { - struct snddev_channel *sce, *tmp, *after; + struct snddev_channel *sce, *tmp, *after; unsigned rdevcount; - int device = device_get_unit(d->dev); - int stop; + int device = device_get_unit(d->dev); size_t namelen; /* * Note it's confusing nomenclature. * dev_t * device -> pcm_device - * unit -> pcm_channel + * unit -> pcm_channel * channel -> snddev_channel * device_t * unit -> pcm_device @@ -538,48 +565,42 @@ snd_mtxlock(d->lock); sce->channel = ch; sce->chan_num = 0; + rdevcount = 0; after = NULL; - stop = 0; + SLIST_FOREACH(tmp, &d->channels, link) { + if (sce->chan_num == tmp->chan_num) + sce->chan_num++; + else { +#if 0 + device_printf(d->dev, + "%s: cdev numbering screwed (Expect: %d, Got: %d)\n", + __func__, sce->chan_num, tmp->chan_num); +#endif + goto retry_chan_num_search; + } + after = tmp; + rdevcount++; + } + goto retry_chan_num_search_out; retry_chan_num_search: /* * Look for possible channel numbering collision. This may not * be optimized, but it will ensure that no collision occured. - * Creating maximum possible channels (256 channels) will cost - * us at most 32895 cycles, but this can be considered cheap - * since none of the locking/unlocking operations involved. - * - * Micro optimization, channel ordering: - * hw,hw,hw,vch,vch,vch,rec + * Can be considered cheap since none of the locking/unlocking + * operations involved. */ rdevcount = 0; + after = NULL; SLIST_FOREACH(tmp, &d->channels, link) { - if (tmp == NULL || tmp->channel == NULL) - continue; if (sce->chan_num == tmp->chan_num) { sce->chan_num++; - after = NULL; - stop = 0; goto retry_chan_num_search; } - if (stop == 0) { - if (ch->flags & CHN_F_VIRTUAL) { - if (tmp->channel->direction == PCMDIR_REC) - stop = 1; - else - after = tmp; - } else if (ch->direction == PCMDIR_REC) { - after = tmp; - } else { - if (tmp->channel->direction != PCMDIR_PLAY || - (tmp->channel->flags & CHN_F_VIRTUAL)) { - stop = 1; - } else { - after = tmp; - } - } - } + if (sce->chan_num > tmp->chan_num) + after = tmp; rdevcount++; } +retry_chan_num_search_out: /* * Don't overflow PCMMKMINOR / PCMMAXCHAN. */ @@ -603,6 +624,18 @@ } else { SLIST_INSERT_AFTER(after, sce, link); } +#if 0 + if (1) { + int cnum = 0; + SLIST_FOREACH(tmp, &d->channels, link) { + if (cnum != tmp->chan_num) + device_printf(d->dev, + "%s: WARNING: inconsistent cdev numbering! (Expect: %d, Got: %d)\n", + __func__, cnum, tmp->chan_num); + cnum++; + } + } +#endif namelen = strlen(ch->name); if ((CHN_NAMELEN - namelen) > 10) { /* ":dspXX.YYY" */ @@ -611,6 +644,10 @@ device, sce->chan_num); } snd_mtxunlock(d->lock); + + /* + * I will revisit these someday, and nuke it mercilessly.. + */ sce->dsp_devt = make_dev(&dsp_cdevsw, PCMMKMINOR(device, SND_DEV_DSP, sce->chan_num), UID_ROOT, GID_WHEEL, 0666, "dsp%d.%d", @@ -638,7 +675,7 @@ int pcm_chn_remove(struct snddev_info *d, struct pcm_channel *ch) { - struct snddev_channel *sce; + struct snddev_channel *sce; #if 0 int ourlock; @@ -680,9 +717,9 @@ int pcm_addchan(device_t dev, int dir, kobj_class_t cls, void *devinfo) { - struct snddev_info *d = device_get_softc(dev); + struct snddev_info *d = device_get_softc(dev); struct pcm_channel *ch; - int err; + int err; ch = pcm_chn_create(d, NULL, cls, dir, devinfo); if (!ch) { @@ -703,8 +740,8 @@ static int >>> TRUNCATED FOR MAIL (1000 lines) <<<