コード例 #1
0
/* Send an ADB retransmit (Talk, appended to the request queue) */
static void macii_retransmit(int device)
{
	static int in_retransmit = 0;
	static struct adb_request rt;
	unsigned long flags;
	
	if (in_retransmit) printk("macii_retransmit: double retransmit!\n");

	in_retransmit++;

	adb_request(&rt, NULL, ADBREQ_REPLY|ADBREQ_NOSEND, 1,
		    ADB_READREG(device, 0));

	save_flags(flags);
	cli();

	if (current_req != NULL) {
		last_req->next = &rt;
		last_req = &rt;
	} else {
		current_req = &rt;
		last_req = &rt;
	}

	if (macii_state == idle) macii_start();

	restore_flags(flags);
	in_retransmit--;
}
コード例 #2
0
/* Send an ADB poll (Talk Register 0 command, tagged on the front of the request queue) */
static void macii_queue_poll(void)
{
	static int device = 0;
	static int in_poll=0;
	static struct adb_request req;
	unsigned long flags;
	
	if (in_poll) printk("macii_queue_poll: double poll!\n");

	in_poll++;
	if (++device > 15) device = 1;

	adb_request(&req, NULL, ADBREQ_REPLY|ADBREQ_NOSEND, 1,
		    ADB_READREG(device, 0));

	save_flags(flags);
	cli();

	req.next = current_req;
	current_req = &req;

	restore_flags(flags);
	macii_start();
	in_poll--;
}
コード例 #3
0
ファイル: adb.c プロジェクト: CTU-IIG/qemu
/* XXX: move that to cuda ? */
int adb_poll(ADBBusState *s, uint8_t *obuf, uint16_t poll_mask)
{
    ADBDevice *d;
    int olen, i;
    uint8_t buf[1];

    olen = 0;
    for(i = 0; i < s->nb_devices; i++) {
        if (s->poll_index >= s->nb_devices)
            s->poll_index = 0;
        d = s->devices[s->poll_index];
        if ((1 << d->devaddr) & poll_mask) {
            buf[0] = ADB_READREG | (d->devaddr << 4);
            olen = adb_request(s, obuf + 1, buf, 1);
            /* if there is data, we poll again the same device */
            if (olen > 0) {
                obuf[0] = buf[0];
                olen++;
                break;
            }
        }
        s->poll_index++;
    }
    return olen;
}
コード例 #4
0
/* Reset the bus */
static int macii_reset_bus(void)
{
	static struct adb_request req;
	
	/* Command = 0, Address = ignored */
	adb_request(&req, NULL, 0, 1, ADB_BUSRESET);

	return 0;
}
コード例 #5
0
ファイル: adb.c プロジェクト: kzlin129/tt-gpl
/* Try to change handler to new_id. Will return 1 if successful. */
static int try_handler_change(int address, int new_id)
{
	struct adb_request req;

	if (adb_handler[address].handler_id == new_id)
	    return 1;
	adb_request(&req, NULL, ADBREQ_SYNC, 3,
	    ADB_WRITEREG(address, 3), address | 0x20, new_id);
	adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
	    ADB_READREG(address, 3));
	if (req.reply_len < 2)
	    return 0;
	if (req.reply[2] != new_id)
	    return 0;
	adb_handler[address].handler_id = req.reply[2];

	return 1;
}
コード例 #6
0
ファイル: adb.c プロジェクト: kzlin129/tt-gpl
static int adb_scan_bus(void)
{
	int i, highFree=0, noMovement;
	int devmask = 0;
	struct adb_request req;
	
	/* assumes adb_handler[] is all zeroes at this point */
	for (i = 1; i < 16; i++) {
		/* see if there is anything at address i */
		adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
                            (i << 4) | 0xf);
		if (req.reply_len > 1)
			/* one or more devices at this address */
			adb_handler[i].original_address = i;
		else if (i > highFree)
			highFree = i;
	}

	/* Note we reset noMovement to 0 each time we move a device */
	for (noMovement = 1; noMovement < 2 && highFree > 0; noMovement++) {
		for (i = 1; i < 16; i++) {
			if (adb_handler[i].original_address == 0)
				continue;
			/*
			 * Send a "talk register 3" command to address i
			 * to provoke a collision if there is more than
			 * one device at this address.
			 */
			adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
				    (i << 4) | 0xf);
			/*
			 * Move the device(s) which didn't detect a
			 * collision to address `highFree'.  Hopefully
			 * this only moves one device.
			 */
			adb_request(&req, NULL, ADBREQ_SYNC, 3,
				    (i<< 4) | 0xb, (highFree | 0x60), 0xfe);
			/*
			 * See if anybody actually moved. This is suggested
			 * by HW TechNote 01:
			 *
			 * http://developer.apple.com/technotes/hw/hw_01.html
			 */
			adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
				    (highFree << 4) | 0xf);
			if (req.reply_len <= 1) continue;
			/*
			 * Test whether there are any device(s) left
			 * at address i.
			 */
			adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
				    (i << 4) | 0xf);
			if (req.reply_len > 1) {
				/*
				 * There are still one or more devices
				 * left at address i.  Register the one(s)
				 * we moved to `highFree', and find a new
				 * value for highFree.
				 */
				adb_handler[highFree].original_address =
					adb_handler[i].original_address;
				while (highFree > 0 &&
				       adb_handler[highFree].original_address)
					highFree--;
				if (highFree <= 0)
					break;

				noMovement = 0;
			}
			else {
				/*
				 * No devices left at address i; move the
				 * one(s) we moved to `highFree' back to i.
				 */
				adb_request(&req, NULL, ADBREQ_SYNC, 3,
					    (highFree << 4) | 0xb,
					    (i | 0x60), 0xfe);
			}
		}	
	}

	/* Now fill in the handler_id field of the adb_handler entries. */
	printk(KERN_DEBUG "adb devices:");
	for (i = 1; i < 16; i++) {
		if (adb_handler[i].original_address == 0)
			continue;
		adb_request(&req, NULL, ADBREQ_SYNC | ADBREQ_REPLY, 1,
			    (i << 4) | 0xf);
		adb_handler[i].handler_id = req.reply[2];
		printk(" [%d]: %d %x", i, adb_handler[i].original_address,
		       adb_handler[i].handler_id);
		devmask |= 1 << i;
	}
	printk("\n");
	return devmask;
}