static void au1xmmc_send_pio(struct au1xmmc_host *host) { struct mmc_data *data = 0; int sg_len, max, count = 0; unsigned char *sg_ptr; u32 status = 0; struct scatterlist *sg; data = host->mrq->data; if (!(host->flags & HOST_F_XMIT)) return; /* This is the pointer to the data buffer */ sg = &data->sg[host->pio.index]; sg_ptr = page_address(sg->page) + sg->offset + host->pio.offset; /* This is the space left inside the buffer */ sg_len = data->sg[host->pio.index].length - host->pio.offset; /* Check to if we need less then the size of the sg_buffer */ max = (sg_len > host->pio.len) ? host->pio.len : sg_len; if (max > AU1XMMC_MAX_TRANSFER) max = AU1XMMC_MAX_TRANSFER; for(count = 0; count < max; count++ ) { unsigned char val; status = au_readl(HOST_STATUS(host)); if (!(status & SD_STATUS_TH)) break; val = *sg_ptr++; au_writel((unsigned long) val, HOST_TXPORT(host)); au_sync(); } host->pio.len -= count; host->pio.offset += count; if (count == sg_len) { host->pio.index++; host->pio.offset = 0; } if (host->pio.len == 0) { IRQ_OFF(host, SD_CONFIG_TH); if (host->flags & HOST_F_STOP) SEND_STOP(host); tasklet_schedule(&host->data_task); } }
static void au1xmmc_send_pio(struct au1xmmc_host *host) { struct mmc_data *data; int sg_len, max, count; unsigned char *sg_ptr, val; u32 status; struct scatterlist *sg; data = host->mrq->data; if (!(host->flags & HOST_F_XMIT)) return; sg = &data->sg[host->pio.index]; sg_ptr = sg_virt(sg) + host->pio.offset; sg_len = data->sg[host->pio.index].length - host->pio.offset; max = (sg_len > host->pio.len) ? host->pio.len : sg_len; if (max > AU1XMMC_MAX_TRANSFER) max = AU1XMMC_MAX_TRANSFER; for (count = 0; count < max; count++) { status = au_readl(HOST_STATUS(host)); if (!(status & SD_STATUS_TH)) break; val = *sg_ptr++; au_writel((unsigned long)val, HOST_TXPORT(host)); au_sync(); } host->pio.len -= count; host->pio.offset += count; if (count == sg_len) { host->pio.index++; host->pio.offset = 0; } if (host->pio.len == 0) { IRQ_OFF(host, SD_CONFIG_TH); if (host->flags & HOST_F_STOP) SEND_STOP(host); tasklet_schedule(&host->data_task); } }