Esempio n. 1
0
static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count,
                                 u32 dma_count, int write, u8 cmd)
{
    struct mac_esp_priv *mep = MAC_ESP_GET_PRIV(esp);
    u8 *fifo = esp->regs + ESP_FDATA * 16;

    cmd &= ~ESP_CMD_DMA;
    mep->error = 0;

    if (write) {
        scsi_esp_cmd(esp, cmd);

        while (1) {
            unsigned int n;

            n = mac_esp_wait_for_fifo(esp);
            if (!n)
                break;

            if (n > esp_count)
                n = esp_count;
            esp_count -= n;

            MAC_ESP_PIO_LOOP("%2@,%0@+", n);

            if (!esp_count)
                break;

            if (mac_esp_wait_for_intr(esp))
                break;

            if (((esp->sreg & ESP_STAT_PMASK) != ESP_DIP) &&
                    ((esp->sreg & ESP_STAT_PMASK) != ESP_MIP))
                break;

            esp->ireg = esp_read8(ESP_INTRPT);
            if ((esp->ireg & (ESP_INTR_DC | ESP_INTR_BSERV)) !=
                    ESP_INTR_BSERV)
                break;

            scsi_esp_cmd(esp, ESP_CMD_TI);
        }
    } else {
        scsi_esp_cmd(esp, ESP_CMD_FLUSH);

        if (esp_count >= MAC_ESP_FIFO_SIZE)
            MAC_ESP_PIO_FILL("%0@+,%2@", esp_count);
        else
            MAC_ESP_PIO_LOOP("%0@+,%2@", esp_count);

        scsi_esp_cmd(esp, cmd);

        while (esp_count) {
            unsigned int n;

            if (mac_esp_wait_for_intr(esp))
                break;

            if (((esp->sreg & ESP_STAT_PMASK) != ESP_DOP) &&
                    ((esp->sreg & ESP_STAT_PMASK) != ESP_MOP))
                break;

            esp->ireg = esp_read8(ESP_INTRPT);
            if ((esp->ireg & (ESP_INTR_DC | ESP_INTR_BSERV)) !=
                    ESP_INTR_BSERV)
                break;

            n = MAC_ESP_FIFO_SIZE -
                (esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES);
            if (n > esp_count)
                n = esp_count;

            if (n == MAC_ESP_FIFO_SIZE) {
                MAC_ESP_PIO_FILL("%0@+,%2@", esp_count);
            } else {
                esp_count -= n;
                MAC_ESP_PIO_LOOP("%0@+,%2@", n);
            }

            scsi_esp_cmd(esp, ESP_CMD_TI);
        }
    }
}
static void mac_esp_send_pio_cmd(struct esp *esp, u32 addr, u32 esp_count,
				 u32 dma_count, int write, u8 cmd)
{
	unsigned long flags;
	struct mac_esp_priv *mep = MAC_ESP_GET_PRIV(esp);
	u8 *fifo = esp->regs + ESP_FDATA * 16;

	local_irq_save(flags);

	cmd &= ~ESP_CMD_DMA;
	mep->error = 0;

	if (write) {
		scsi_esp_cmd(esp, cmd);

		if (!mac_esp_wait_for_intr(esp)) {
			if (mac_esp_wait_for_fifo(esp))
				esp_count = 0;
		} else {
			esp_count = 0;
		}
	} else {
		scsi_esp_cmd(esp, ESP_CMD_FLUSH);

		if (esp_count >= MAC_ESP_FIFO_SIZE)
			MAC_ESP_PIO_FILL("%0@+,%2@", esp_count);
		else
			MAC_ESP_PIO_LOOP("%0@+,%2@", esp_count);

		scsi_esp_cmd(esp, cmd);
	}

	while (esp_count) {
		unsigned int n;

		if (mac_esp_wait_for_intr(esp)) {
			mep->error = 1;
			break;
		}

		if (esp->sreg & ESP_STAT_SPAM) {
			printk(KERN_ERR PFX "gross error\n");
			mep->error = 1;
			break;
		}

		n = esp_read8(ESP_FFLAGS) & ESP_FF_FBYTES;

		if (write) {
			if (n > esp_count)
				n = esp_count;
			esp_count -= n;

			MAC_ESP_PIO_LOOP("%2@,%0@+", n);

			if ((esp->sreg & ESP_STAT_PMASK) == ESP_STATP)
				break;

			if (esp_count) {
				esp->ireg = esp_read8(ESP_INTRPT);
				if (esp->ireg & ESP_INTR_DC)
					break;

				scsi_esp_cmd(esp, ESP_CMD_TI);
			}
		} else {
			esp->ireg = esp_read8(ESP_INTRPT);
			if (esp->ireg & ESP_INTR_DC)
				break;

			n = MAC_ESP_FIFO_SIZE - n;
			if (n > esp_count)
				n = esp_count;

			if (n == MAC_ESP_FIFO_SIZE) {
				MAC_ESP_PIO_FILL("%0@+,%2@", esp_count);
			} else {
				esp_count -= n;
				MAC_ESP_PIO_LOOP("%0@+,%2@", n);
			}

			scsi_esp_cmd(esp, ESP_CMD_TI);
		}
	}

	local_irq_restore(flags);
}