kernels/linux-2.4.0/drivers/block/xd.c
/* xd_readwrite: handle a read/write request */
handle a read/write request
handle a read / write request
static int xd_readwrite (u_char operation,u_char drive,char *buffer,u_int block,u_int count)
{
	u_char cmdblk[6],sense[4];
	u_short track,cylinder;
	u_char head,sector,control,mode = PIO_MODE,temp;
	char **real_buffer;
	register int i;
#ifdef DEBUG_READWRITE
	printk("xd_readwrite: operation = %s, drive = %d, buffer = 0x%X, block = %d, count = %d\n",operation == READ ? "read" : "write",drive,buffer,block,count);
#endif 
	control = xd_info[drive].control;
	if (!xd_dma_buffer)
		xd_dma_buffer = (char *)xd_dma_mem_alloc(xd_maxsectors * 0x200);
	while (count) {
		temp = count < xd_maxsectors ? count : xd_maxsectors;
		track = block / xd_info[drive].sectors;
		head = track % xd_info[drive].heads;
		cylinder = track / xd_info[drive].heads;
		sector = block % xd_info[drive].sectors;
#ifdef DEBUG_READWRITE
		printk("xd_readwrite: drive = %d, head = %d, cylinder = %d, sector = %d, count = %d\n",drive,head,cylinder,sector,temp);
#endif 
		if (xd_dma_buffer) {
			mode = xd_setup_dma(operation == READ ? DMA_MODE_READ : DMA_MODE_WRITE,(u_char *)(xd_dma_buffer),temp * 0x200);
			real_buffer = &xd_dma_buffer;
			for (i=0; i < (temp * 0x200); i++)
				xd_dma_buffer[i] = buffer[i];
		}
		else
			real_buffer = &buffer;
		xd_build(cmdblk,operation == READ ? CMD_READ : CMD_WRITE,drive,head,cylinder,sector,temp & 0xFF,control);
		switch (xd_command(cmdblk,mode,(u_char *)(*real_buffer),(u_char *)(*real_buffer),sense,XD_TIMEOUT)) {
			case 1:
				printk("xd%c: %s timeout, recalibrating drive\n",'a'+drive,(operation == READ ? "read" : "write"));
				xd_recalibrate(drive);
				return (0);
			case 2:
				if (sense[0] & 0x30) {
					printk("xd%c: %s - ",'a'+drive,(operation == READ ? "reading" : "writing"));
					switch ((sense[0] & 0x30) >> 4) {
					case 0: printk("drive error, code = 0x%X",sense[0] & 0x0F);
						break;
					case 1: printk("controller error, code = 0x%X",sense[0] & 0x0F);
						break;
					case 2: printk("command error, code = 0x%X",sense[0] & 0x0F);
						break;
					case 3: printk("miscellaneous error, code = 0x%X",sense[0] & 0x0F);
						break;
					}
				}
				if (sense[0] & 0x80)
					printk(" - CHS = %d/%d/%d\n",((sense[2] & 0xC0) << 2) | sense[3],sense[1] & 0x1F,sense[2] & 0x3F);
				else
					printk(" - no valid disk address\n");
				return (0);
		}
		if (xd_dma_buffer)
			for (i=0; i < (temp * 0x200); i++)
				buffer[i] = xd_dma_buffer[i];
		count -= temp, buffer += temp * 0x200, block += temp;
	}
	return (1);
}
static int xd_readwrite ( u_char operation , u_char drive , char * buffer , u_int block , u_int count ) { u_char cmdblk [ 6 ] , sense [ 4 ] ; u_short track , cylinder ; u_char head , sector , control , mode = PIO_MODE , temp ; char * * real_buffer ; register int i ; #ifdef DEBUG_READWRITE printk ( " \n " , operation == READ ? " " : " " , drive , buffer , block , count ) ; #endif control = xd_info [ drive ] . control ; if ( ! xd_dma_buffer ) xd_dma_buffer = ( char * ) xd_dma_mem_alloc ( xd_maxsectors * 0x200 ) ; while ( count ) { temp = count < xd_maxsectors ? count : xd_maxsectors ; track = block / xd_info [ drive ] . sectors ; head = track % xd_info [ drive ] . heads ; cylinder = track / xd_info [ drive ] . heads ; sector = block % xd_info [ drive ] . sectors ; #ifdef DEBUG_READWRITE printk ( " \n " , drive , head , cylinder , sector , temp ) ; #endif if ( xd_dma_buffer ) { mode = xd_setup_dma ( operation == READ ? DMA_MODE_READ : DMA_MODE_WRITE , ( u_char * ) ( xd_dma_buffer ) , temp * 0x200 ) ; real_buffer = & xd_dma_buffer ; for ( i = 0 ; i < ( temp * 0x200 ) ; i ++ ) xd_dma_buffer [ i ] = buffer [ i ] ; } else real_buffer = & buffer ; xd_build ( cmdblk , operation == READ ? CMD_READ : CMD_WRITE , drive , head , cylinder , sector , temp & 0xFF , control ) ; switch ( xd_command ( cmdblk , mode , ( u_char * ) ( * real_buffer ) , ( u_char * ) ( * real_buffer ) , sense , XD_TIMEOUT ) ) { case 1 : printk ( " \n " , ' ' + drive , ( operation == READ ? " " : " " ) ) ; xd_recalibrate ( drive ) ; return ( 0 ) ; case 2 : if ( sense [ 0 ] & 0x30 ) { printk ( " " , ' ' + drive , ( operation == READ ? " " : " " ) ) ; switch ( ( sense [ 0 ] & 0x30 ) >> 4 ) { case 0 : printk ( " " , sense [ 0 ] & 0x0F ) ; break ; case 1 : printk ( " " , sense [ 0 ] & 0x0F ) ; break ; case 2 : printk ( " " , sense [ 0 ] & 0x0F ) ; break ; case 3 : printk ( " " , sense [ 0 ] & 0x0F ) ; break ; } } if ( sense [ 0 ] & 0x80 ) printk ( " \n " , ( ( sense [ 2 ] & 0xC0 ) << 2 ) | sense [ 3 ] , sense [ 1 ] & 0x1F , sense [ 2 ] & 0x3F ) ; else printk ( " \n " ) ; return ( 0 ) ; } if ( xd_dma_buffer ) for ( i = 0 ; i < ( temp * 0x200 ) ; i ++ ) buffer [ i ] = xd_dma_buffer [ i ] ; count -= temp , buffer += temp * 0x200 , block += temp ; } return ( 1 ) ; }
xd_readwrite: handle a read/write request
xd_readwrite : handle a read / write request
/* DEBUG_READWRITE */ /* DEBUG_READWRITE */ /*	reported drive number = (sense[1] & 0xE0) >> 5 */