Beispiel #1
0
static void adapter_hard_reset(elp_device * adapter)

{
    int timeout;

    CHECK_NULL(adapter);

    /*
     * take FLSH and ATTN high
     */
    OUTB(CONTROL_ATTN|CONTROL_FLSH, adapter->io_addr+PORT_CONTROL);

    /*
     * wait for a little bit
     */
    for (timeout = jiffies + 20; jiffies <= timeout; )
        ;

    /*
     * now take them low
     */
    OUTB(0, adapter->io_addr+PORT_CONTROL);

    /*
     * wait for a little bit
     */
    for (timeout = jiffies + 20; jiffies <= timeout; )
        ;

    /*
     * now hang around until the board gets it's act together
     */
    for (timeout = jiffies + (100 * 15); jiffies <= timeout; )
        if (GET_ASF() != ASF_PCB_END)
            break;
}
Beispiel #2
0
static int send_pcb(struct net_device *dev, pcb_struct * pcb)
{
	int i;
	unsigned long timeout;
	elp_device *adapter = dev->priv;
	unsigned long flags;

	check_3c505_dma(dev);

	if (adapter->dmaing && adapter->current_dma.direction == 0)
		return FALSE;

	/* Avoid contention */
	if (test_and_set_bit(1, &adapter->send_pcb_semaphore)) {
		if (elp_debug >= 3) {
			printk(KERN_DEBUG "%s: send_pcb entered while threaded\n", dev->name);
		}
		return FALSE;
	}
	/*
	 * load each byte into the command register and
	 * wait for the HCRE bit to indicate the adapter
	 * had read the byte
	 */
	set_hsf(dev, 0);

	if (send_pcb_slow(dev->base_addr, pcb->command))
		goto abort;

	spin_lock_irqsave(&adapter->lock, flags);

	if (send_pcb_fast(dev->base_addr, pcb->length))
		goto sti_abort;

	for (i = 0; i < pcb->length; i++) {
		if (send_pcb_fast(dev->base_addr, pcb->data.raw[i]))
			goto sti_abort;
	}

	outb_control(adapter->hcr_val | 3, dev);	/* signal end of PCB */
	outb_command(2 + pcb->length, dev->base_addr);

	/* now wait for the acknowledgement */
	spin_unlock_irqrestore(&adapter->lock, flags);

	for (timeout = jiffies + 5*HZ/100; time_before(jiffies, timeout);) {
		switch (GET_ASF(dev->base_addr)) {
		case ASF_PCB_ACK:
			adapter->send_pcb_semaphore = 0;
			return TRUE;

		case ASF_PCB_NAK:
#ifdef ELP_DEBUG
			printk(KERN_DEBUG "%s: send_pcb got NAK\n", dev->name);
#endif
			goto abort;
		}
	}

	if (elp_debug >= 1)
		printk(KERN_DEBUG "%s: timeout waiting for PCB acknowledge (status %02x)\n", dev->name, inb_status(dev->base_addr));
	goto abort;

      sti_abort:
	spin_unlock_irqrestore(&adapter->lock, flags);
      abort:
	adapter->send_pcb_semaphore = 0;
	return FALSE;
}
Beispiel #3
0
static int send_pcb(elp_device * adapter, pcb_struct * pcb)

{
    int i;
    int cont;
    int retry = 0;
    int timeout;

    CHECK_NULL(pcb);
    CHECK_NULL(adapter);

    if (pcb->length > MAX_PCB_DATA)
        printk(invalid_pcb_msg, pcb->length, filename, __LINE__);

    while (1) {

        cont = 1;

        /*
         * load each byte into the command register and
         * wait for the HCRE bit to indicate the adapter
         * had read the byte
         */
        SET_HSF(0);
        OUTB(pcb->command, (adapter->io_addr)+PORT_COMMAND);
        cont = WAIT_HCRE(5);

        if (cont) {
            OUTB(pcb->length, (adapter->io_addr)+PORT_COMMAND);
            cont = WAIT_HCRE(2);
        }

        for (i = 0; cont && (i < pcb->length); i++) {
            OUTB(pcb->data.raw[i], (adapter->io_addr)+PORT_COMMAND);
            cont = WAIT_HCRE(2);
        }

        /* set the host status bits to indicate end of PCB */
        /* send the total packet length as well */
        /* wait for the adapter to indicate that it has read the PCB */
        if (cont) {
            SET_HSF(HSF_PCB_END);
            OUTB(2+pcb->length, adapter->io_addr+PORT_COMMAND);
            timeout = jiffies + 6;
            while (jiffies < timeout) {
                i = GET_ASF();
                if ((i == ASF_PCB_ACK) ||
                        (i == ASF_PCB_NAK))
                    break;
            }

            if (jiffies >= timeout)
                TIMEOUT_MSG();

            if (i == ASF_PCB_ACK) {
                SET_HSF(0);
                return TRUE;
            } else if (i == ASF_PCB_NAK) {
                SET_HSF(0);
                printk("%s: PCB send was NAKed\n", adapter->name);
                {
                    int to = jiffies + 5;
                    while (jiffies < to)
                        ;
                }
            }
        }

        if (elp_debug >= 2)
            printk("%s: NAK/timeout on send PCB\n", adapter->name);
        if ((retry++ & 7) == 0)
            printk("%s: retry #%i on send PCB\n", adapter->name, retry);
    }

    return FALSE;
}
static bool send_pcb(struct net_device *dev, pcb_struct * pcb)
{
	int i;
	unsigned long timeout;
	elp_device *adapter = netdev_priv(dev);
	unsigned long flags;

	check_3c505_dma(dev);

	if (adapter->dmaing && adapter->current_dma.direction == 0)
		return false;

	
	if (test_and_set_bit(1, &adapter->send_pcb_semaphore)) {
		if (elp_debug >= 3) {
			pr_debug("%s: send_pcb entered while threaded\n", dev->name);
		}
		return false;
	}
	set_hsf(dev, 0);

	if (send_pcb_slow(dev->base_addr, pcb->command))
		goto abort;

	spin_lock_irqsave(&adapter->lock, flags);

	if (send_pcb_fast(dev->base_addr, pcb->length))
		goto sti_abort;

	for (i = 0; i < pcb->length; i++) {
		if (send_pcb_fast(dev->base_addr, pcb->data.raw[i]))
			goto sti_abort;
	}

	outb_control(adapter->hcr_val | 3, dev);	
	outb_command(2 + pcb->length, dev->base_addr);

	
	spin_unlock_irqrestore(&adapter->lock, flags);

	for (timeout = jiffies + 5*HZ/100; time_before(jiffies, timeout);) {
		switch (GET_ASF(dev->base_addr)) {
		case ASF_PCB_ACK:
			adapter->send_pcb_semaphore = 0;
			return true;

		case ASF_PCB_NAK:
#ifdef ELP_DEBUG
			pr_debug("%s: send_pcb got NAK\n", dev->name);
#endif
			goto abort;
		}
	}

	if (elp_debug >= 1)
		pr_debug("%s: timeout waiting for PCB acknowledge (status %02x)\n",
			dev->name, inb_status(dev->base_addr));
	goto abort;

      sti_abort:
	spin_unlock_irqrestore(&adapter->lock, flags);
      abort:
	adapter->send_pcb_semaphore = 0;
	return false;
}