PERFORCE change 94360 for review
Marcel Moolenaar
marcel at FreeBSD.org
Fri Mar 31 18:02:23 UTC 2006
http://perforce.freebsd.org/chv.cgi?CH=94360
Change 94360 by marcel at 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 <sys/cdefs.h>
-__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 <sys/param.h>
@@ -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 <sys/cdefs.h>
-__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 <sys/param.h>
@@ -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 <sys/cdefs.h>
-__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 <sys/param.h>
@@ -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 <sys/cdefs.h>
-__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 <sys/param.h>
@@ -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 <sys/cdefs.h>
-__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 <sys/param.h>
#include <sys/systm.h>
@@ -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 <sys/cdefs.h>
-__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 <sys/param.h>
@@ -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 <sys/cdefs.h>
-__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 <sys/param.h>
#include <sys/systm.h>
@@ -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) <<<
More information about the p4-projects
mailing list