 /* * The controller stops sending interrupts for * 'FIFO empty' under certain conditions. So we * need to be a bit more pro-active. */ tasklet_schedule(&host->fifo_tasklet); 
static void wbsd_fill_fifo(struct wbsd_host* host){	struct mmc_data* data = host->mrq->cmd->data;	char* buffer;	int i, fsr, fifo;		/*	 * Check that we aren't being called after the	 * entire buffer has been transfered.	 */	if (data->bytes_xfered == host->size)		return;	buffer = wbsd_kmap_sg(host) + host->offset;	/*	 * Fill the fifo. This has a tendency to loop longer	 * than the FIFO length (usually one block).	 */	while (!((fsr = inb(host->base + WBSD_FSR)) & WBSD_FIFO_FULL))	{		/*		 * The size field in the FSR is broken so we have to		 * do some guessing.		 */				if (fsr & WBSD_FIFO_EMPTY)			fifo = 0;		else if (fsr & WBSD_FIFO_EMTHRE)			fifo = 8;		else			fifo = 15;		for (i = 16;i > fifo;i--)		{			outb(*buffer, host->base + WBSD_DFR);			buffer++;			host->offset++;			host->remain--;						data->bytes_xfered++;						/*			 * Transfer done?			 */			if (data->bytes_xfered == host->size)			{				wbsd_kunmap_sg(host);				return;			}			/*			 * End of scatter list entry?			 */			if (host->remain == 0)			{				wbsd_kunmap_sg(host);								/*				 * Get next entry. Check if last.				 */				if (!wbsd_next_sg(host))				{					/*					 * We should never reach this point.					 * It means that we're trying to					 * transfer more blocks than can fit					 * into the scatter list.					 */					BUG_ON(1);										host->size = data->bytes_xfered;										return;				}								buffer = wbsd_kmap_sg(host);			}		}	}		wbsd_kunmap_sg(host);}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/85bcc13072c54592596c5b41d40d1c6a18b04e19/wbsd.c/clean/drivers/mmc/wbsd.c