示例#1
0
static int
fdc_acpi_probe_children(device_t bus, device_t dev, void *fde)
{
    struct fdc_walk_ctx *ctx;
    devclass_t fd_dc;
    int i;

    /* Setup the context and walk all child devices. */
    ctx = malloc(sizeof(struct fdc_walk_ctx), M_TEMP, M_NOWAIT);
    if (ctx == NULL) {
        device_printf(dev, "no memory for walking children\n");
        return (ENOMEM);
    }
    bcopy(fde, ctx->fd_present, sizeof(ctx->fd_present));
    ctx->index = 0;
    ctx->dev = dev;
    ctx->acpi_dev = bus;
    ACPI_SCAN_CHILDREN(ctx->acpi_dev, dev, 1, fdc_acpi_probe_child,
                       ctx);

    /* Add any devices not represented by an AML Device handle/node. */
    fd_dc = devclass_find("fd");
    for (i = 0; i < ACPI_FDC_MAXDEVS; i++)
        if (ctx->fd_present[i] == ACPI_FD_PRESENT &&
                devclass_get_device(fd_dc, i) == NULL) {
            if (fdc_add_child(dev, "fd", i) == NULL)
                device_printf(dev, "fd add failed\n");
        }
    free(ctx, M_TEMP);

    /* Attach any children found during the probe. */
    return (bus_generic_attach(dev));
}
示例#2
0
static int
fdc_pccard_attach(device_t dev)
{
	int error;
	struct	fdc_data *fdc;
	device_t child;

	fdc = device_get_softc(dev);
	fdc->flags = FDC_NODMA | FDC_NOFAST;
	fdc->fdct = FDC_NE765;
	error = fdc_pccard_alloc_resources(dev, fdc);
	if (error == 0)
		error = fdc_attach(dev);
	if (error == 0) {
		child = fdc_add_child(dev, "fd", -1);
		device_set_flags(child, 0x24);
		error = bus_generic_attach(dev);
	}
	if (error)
		fdc_release_resources(fdc);
	return (error);
}
示例#3
0
static ACPI_STATUS
fdc_acpi_probe_child(ACPI_HANDLE h, device_t *dev, int level, void *arg)
{
    struct fdc_walk_ctx *ctx;
    device_t child, old_child;
    ACPI_BUFFER buf;
    ACPI_OBJECT *pkg, *obj;
    ACPI_STATUS status;

    ctx = (struct fdc_walk_ctx *)arg;
    buf.Pointer = NULL;

    /*
     * The first four ints are booleans that indicate whether fd0-3 are
     * present or not.  The last is for a tape device, which we don't
     * bother supporting for now.
     */
    if (ctx->index > 3)
        return (AE_OK);

    /* This device is not present, move on to the next. */
    if (ctx->fd_present[ctx->index] != ACPI_FD_PRESENT)
        goto out;

    /* Create a device for the child with the given index. */
    child = fdc_add_child(ctx->dev, "fd", ctx->index);
    if (child == NULL)
        goto out;
    old_child = *dev;
    *dev = child;

    /* Get temporary buffer for _FDI probe. */
    buf.Length = ACPI_FDC_BUFLEN;
    buf.Pointer = malloc(buf.Length, M_TEMP, M_NOWAIT | M_ZERO);
    if (buf.Pointer == NULL)
        goto out;

    /*
     * Evaluate _FDI to get drive type to pass to the child.  We use the
     * old child here since it has a valid ACPI_HANDLE since it is a
     * child of acpi.  A better way to implement this would be to make fdc
     * support the ACPI handle ivar for its children.
     */
    status = ACPI_EVALUATE_OBJECT(ctx->acpi_dev, old_child, "_FDI", NULL,
                                  &buf);
    if (ACPI_FAILURE(status)) {
        if (status != AE_NOT_FOUND)
            device_printf(ctx->dev, "_FDI failed - %#x\n", status);
        goto out;
    }
    pkg = (ACPI_OBJECT *)buf.Pointer;
    if (!ACPI_PKG_VALID(pkg, 16)) {
        device_printf(ctx->dev, "invalid _FDI package\n");
        goto out;
    }
    obj = &pkg->Package.Elements[1];
    if (obj == NULL || obj->Type != ACPI_TYPE_INTEGER) {
        device_printf(ctx->dev, "invalid type object in _FDI\n");
        goto out;
    }
    fdc_set_fdtype(child, obj->Integer.Value);

out:
    ctx->index++;
    if (buf.Pointer)
        free(buf.Pointer, M_TEMP);
    return (AE_OK);
}