kernels/linux-2.4.0/drivers/ide/ide-dma.c
/*
 * ide_build_dmatable() prepares a dma request.
 * Returns 0 if all went okay, returns 1 otherwise.
 * May also be invoked from trm290.c
 */
ide_build_dmatable() prepares a dma request.
Returns 0 if all went okay, returns 1 otherwise.
May also be invoked from trm290.c
ide_build_dmatable () prepares a dma request . Returns 0 if all went okay returns 1 otherwise . May also be invoked from trm290 . c
int ide_build_dmatable (ide_drive_t *drive, ide_dma_action_t func)
{
	unsigned int *table = HWIF(drive)->dmatable_cpu;
#ifdef CONFIG_BLK_DEV_TRM290
	unsigned int is_trm290_chipset = (HWIF(drive)->chipset == ide_trm290);
#else
	const int is_trm290_chipset = 0;
#endif
	unsigned int count = 0;
	int i;
	struct scatterlist *sg;
	HWIF(drive)->sg_nents = i = ide_build_sglist(HWIF(drive), HWGROUP(drive)->rq);
	sg = HWIF(drive)->sg_table;
	while (i && sg_dma_len(sg)) {
		u32 cur_addr;
		u32 cur_len;
		cur_addr = sg_dma_address(sg);
		cur_len = sg_dma_len(sg);
		while (cur_len) {
			if (++count >= PRD_ENTRIES) {
				printk("%s: DMA table too small\n", drive->name);
				pci_unmap_sg(HWIF(drive)->pci_dev,
					     HWIF(drive)->sg_table,
					     HWIF(drive)->sg_nents,
					     HWIF(drive)->sg_dma_direction);
				return 0; 
			} else {
				u32 xcount, bcount = 0x10000 - (cur_addr & 0xffff);
				if (bcount > cur_len)
					bcount = cur_len;
				*table++ = cpu_to_le32(cur_addr);
				xcount = bcount & 0xffff;
				if (is_trm290_chipset)
					xcount = ((xcount >> 2) - 1) << 16;
				*table++ = cpu_to_le32(xcount);
				cur_addr += bcount;
				cur_len -= bcount;
			}
		}
		sg++;
		i--;
	}
	if (!count)
		printk("%s: empty DMA table?\n", drive->name);
	else if (!is_trm290_chipset)
		*--table |= cpu_to_le32(0x80000000);
	return count;
}
int ide_build_dmatable ( ide_drive_t * drive , ide_dma_action_t func ) { unsigned int * table = HWIF ( drive ) -> dmatable_cpu ; #ifdef CONFIG_BLK_DEV_TRM290 unsigned int is_trm290_chipset = ( HWIF ( drive ) -> chipset == ide_trm290 ) ; #else const int is_trm290_chipset = 0 ; #endif unsigned int count = 0 ; int i ; struct scatterlist * sg ; HWIF ( drive ) -> sg_nents = i = ide_build_sglist ( HWIF ( drive ) , HWGROUP ( drive ) -> rq ) ; sg = HWIF ( drive ) -> sg_table ; while ( i && sg_dma_len ( sg ) ) { u32 cur_addr ; u32 cur_len ; cur_addr = sg_dma_address ( sg ) ; cur_len = sg_dma_len ( sg ) ; while ( cur_len ) { if ( ++ count >= PRD_ENTRIES ) { printk ( " \n " , drive -> name ) ; pci_unmap_sg ( HWIF ( drive ) -> pci_dev , HWIF ( drive ) -> sg_table , HWIF ( drive ) -> sg_nents , HWIF ( drive ) -> sg_dma_direction ) ; return 0 ; } else { u32 xcount , bcount = 0x10000 - ( cur_addr & 0xffff ) ; if ( bcount > cur_len ) bcount = cur_len ; * table ++ = cpu_to_le32 ( cur_addr ) ; xcount = bcount & 0xffff ; if ( is_trm290_chipset ) xcount = ( ( xcount >> 2 ) - 1 ) << 16 ; * table ++ = cpu_to_le32 ( xcount ) ; cur_addr += bcount ; cur_len -= bcount ; } } sg ++ ; i -- ; } if ( ! count ) printk ( " \n " , drive -> name ) ; else if ( ! is_trm290_chipset ) * -- table |= cpu_to_le32 ( 0x80000000 ) ; return count ; }
ide_build_dmatable() prepares a dma request.
ide_build_dmatable () prepares a dma request .
/*
		 * Fill in the dma table, without crossing any 64kB boundaries.
		 * Most hardware requires 16-bit alignment of all blocks,
		 * but the trm290 requires 32-bit alignment.
		 */ /* revert to PIO for this request */