Beispiel #1
0
static int
acd_attach(device_t dev)
{
    struct acd_softc *cdp;

    if (!(cdp = malloc(sizeof(struct acd_softc), M_ACD, M_NOWAIT | M_ZERO))) {
	device_printf(dev, "out of memory\n");
	return ENOMEM;
    }
    cdp->block_size = 2048;
    device_set_ivars(dev, cdp);
    ata_setmode(dev);
    ata_controlcmd(dev, ATA_DEVICE_RESET, 0, 0, 0);
    acd_get_cap(dev);
    g_post_event(acd_geom_attach, dev, M_WAITOK, NULL);

    /* announce we are here */
    acd_describe(dev);
    return 0;
}
Beispiel #2
0
int
acdattach(struct atapi *ata, int unit, struct atapi_params *ap, int debug)
{
    struct acd *cdp;
    struct atapires result;
    struct changer *chp;
    int i, count;

    if (acdnlun >= NUNIT) {
        printf("wcd: too many units\n");
        return 0;
    }
    if (!atapi_request_immediate) {
        printf("wcd: configuration error, ATAPI code not present!\n");
        return 0;
    }
    if ((cdp = acd_init_lun(ata, unit, ap, acdnlun, NULL)) == NULL) {
        printf("wcd: out of memory\n");
        return 0;
    }
    acdtab[acdnlun] = cdp;

    if (debug) {
        cdp->flags |= F_DEBUG;
        atapi_dump(cdp->ata->ctrlr, cdp->lun, "info", ap, sizeof(*ap));
    }

    /* Get drive capabilities, some drives needs this repeated */
    for (count = 0 ; count < 5 ; count++) {
        result = atapi_request_immediate(ata, unit,
        				 ATAPI_MODE_SENSE,
        				 0, ATAPI_CDROM_CAP_PAGE,
        				 0, 0, 0, 0, 
					 sizeof(cdp->cap)>>8, sizeof(cdp->cap),
        				 0, 0, 0, 0, 0, 0, 0, 
					 (char *)&cdp->cap, sizeof(cdp->cap));
        if (result.code == 0 || result.code == RES_UNDERRUN)
            break;
    }

    /* Some drives have shorter capabilities page. */
    if (result.code == RES_UNDERRUN)
        result.code = 0;

    if (result.code == 0) {
    	cdp->cap.max_speed = ntohs(cdp->cap.max_speed);
    	cdp->cap.max_vol_levels = ntohs(cdp->cap.max_vol_levels);
    	cdp->cap.buf_size = ntohs(cdp->cap.buf_size);
    	cdp->cap.cur_speed = ntohs(cdp->cap.cur_speed);
        acd_describe(cdp);
        if (cdp->flags & F_DEBUG)
            atapi_dump(cdp->ata->ctrlr, cdp->lun, "cap", &cdp->cap,
		       sizeof(cdp->cap));
    }
    /* If this is a changer device, allocate the neeeded lun's */
    if (cdp->cap.mech == MST_MECH_CHANGER) {
	char string[16];
    	struct acd *tmpcdp = cdp;

        chp = malloc(sizeof(struct changer), M_TEMP, M_NOWAIT | M_ZERO);
        if (chp == NULL) {
            printf("wcd: out of memory\n");
            return 0;
        }
        result = atapi_request_immediate(ata, unit, ATAPI_MECH_STATUS,
            				 0, 0, 0, 0, 0, 0, 0,
            				 sizeof(struct changer)>>8,
					 sizeof(struct changer),
            				 0, 0, 0, 0, 0, 0,
            				 (char *)chp, sizeof(struct changer));
        if (cdp->flags & F_DEBUG) {
            printf("result.code=%d curr=%02x slots=%d len=%d\n",
                result.code, chp->current_slot, chp->slots,
                htons(chp->table_length));
        }
        if (result.code == RES_UNDERRUN)
            result.code = 0;

        if (result.code == 0) {
            chp->table_length = htons(chp->table_length);
            for (i = 0; i < chp->slots && acdnlun < NUNIT; i++) {
                if (i > 0) {
                    tmpcdp = acd_init_lun(ata, unit, ap, acdnlun, 
					  cdp->device_stats);
		    if (!tmpcdp) {
                        printf("wcd: out of memory\n");
                        return 0;
                    }
                }
                tmpcdp->slot = i;
                tmpcdp->changer_info = chp;
                printf("wcd%d: changer slot %d %s\n", acdnlun, i,
		       (chp->slot[i].present ? "disk present" : "no disk"));
                acdtab[acdnlun++] = tmpcdp;
            }
            if (acdnlun >= NUNIT) {
                printf("wcd: too many units\n");
                return 0;
            }
        }
	sprintf(string, "wcd%d-", cdp->lun);
        devstat_add_entry(cdp->device_stats, string, tmpcdp->lun, DEV_BSIZE,
                          DEVSTAT_NO_ORDERED_TAGS,
                          DEVSTAT_TYPE_CDROM | DEVSTAT_TYPE_IF_IDE,
			  DEVSTAT_PRIORITY_CD);
    }