if (fd_mcs_select(shpnt, current_SC->device->id)) { 
if (fd_mcs_select(shpnt, scmd_id(current_SC))) { 
static irqreturn_t fd_mcs_intr(int irq, void *dev_id, struct pt_regs *regs){	unsigned long flags;	int status;	int done = 0;	unsigned data_count, tmp_count;	int i = 0;	struct Scsi_Host *shpnt;	TOTAL_INTR++;	/* search for one adapter-response on shared interrupt */	while ((shpnt = hosts[i++])) {		if ((inb(TMC_Status_port)) & 1)			break;	}	/* return if some other device on this IRQ caused the interrupt */	if (!shpnt) {		return IRQ_NONE;	}	INTR_Processed++;	outb(0x00, Interrupt_Cntl_port);	/* Abort calls my_done, so we do nothing here. */	if (current_SC->SCp.phase & aborted) {#if DEBUG_ABORT		printk("Interrupt after abort, ignoring\n");#endif		/* return IRQ_HANDLED; */	}#if DEBUG_RACE	++in_interrupt_flag;#endif	if (current_SC->SCp.phase & in_arbitration) {		status = inb(TMC_Status_port);	/* Read adapter status */		if (!(status & 0x02)) {#if EVERY_ACCESS			printk(" AFAIL ");#endif			spin_lock_irqsave(shpnt->host_lock, flags);			my_done(shpnt, DID_BUS_BUSY << 16);			spin_unlock_irqrestore(shpnt->host_lock, flags);			return IRQ_HANDLED;		}		current_SC->SCp.phase = in_selection;		outb(0x40 | FIFO_COUNT, Interrupt_Cntl_port);		outb(0x82, SCSI_Cntl_port);	/* Bus Enable + Select */		outb(adapter_mask | (1 << current_SC->device->id), SCSI_Data_NoACK_port);		/* Stop arbitration and enable parity */		outb(0x10 | PARITY_MASK, TMC_Cntl_port);#if DEBUG_RACE		in_interrupt_flag = 0;#endif		return IRQ_HANDLED;	} else if (current_SC->SCp.phase & in_selection) {		status = inb(SCSI_Status_port);		if (!(status & 0x01)) {			/* Try again, for slow devices */			if (fd_mcs_select(shpnt, current_SC->device->id)) {#if EVERY_ACCESS				printk(" SFAIL ");#endif				spin_lock_irqsave(shpnt->host_lock, flags);				my_done(shpnt, DID_NO_CONNECT << 16);				spin_unlock_irqrestore(shpnt->host_lock, flags);				return IRQ_HANDLED;			} else {#if EVERY_ACCESS				printk(" AltSel ");#endif				/* Stop arbitration and enable parity */				outb(0x10 | PARITY_MASK, TMC_Cntl_port);			}		}		current_SC->SCp.phase = in_other;		outb(0x90 | FIFO_COUNT, Interrupt_Cntl_port);		outb(0x80, SCSI_Cntl_port);#if DEBUG_RACE		in_interrupt_flag = 0;#endif		return IRQ_HANDLED;	}	/* current_SC->SCp.phase == in_other: this is the body of the routine */	status = inb(SCSI_Status_port);	if (status & 0x10) {	/* REQ */		switch (status & 0x0e) {		case 0x08:	/* COMMAND OUT */			outb(current_SC->cmnd[current_SC->SCp.sent_command++], Write_SCSI_Data_port);#if EVERY_ACCESS			printk("CMD = %x,", current_SC->cmnd[current_SC->SCp.sent_command - 1]);#endif			break;		case 0x00:	/* DATA OUT -- tmc18c50/tmc18c30 only */			if (chip != tmc1800 && !current_SC->SCp.have_data_in) {				current_SC->SCp.have_data_in = -1;				outb(0xd0 | PARITY_MASK, TMC_Cntl_port);			}			break;		case 0x04:	/* DATA IN -- tmc18c50/tmc18c30 only */			if (chip != tmc1800 && !current_SC->SCp.have_data_in) {				current_SC->SCp.have_data_in = 1;				outb(0x90 | PARITY_MASK, TMC_Cntl_port);			}			break;		case 0x0c:	/* STATUS IN */			current_SC->SCp.Status = inb(Read_SCSI_Data_port);#if EVERY_ACCESS			printk("Status = %x, ", current_SC->SCp.Status);#endif#if ERRORS_ONLY			if (current_SC->SCp.Status && current_SC->SCp.Status != 2 && current_SC->SCp.Status != 8) {				printk("ERROR fd_mcs: target = %d, command = %x, status = %x\n", current_SC->device->id, current_SC->cmnd[0], current_SC->SCp.Status);			}#endif			break;		case 0x0a:	/* MESSAGE OUT */			outb(MESSAGE_REJECT, Write_SCSI_Data_port);	/* Reject */			break;		case 0x0e:	/* MESSAGE IN */			current_SC->SCp.Message = inb(Read_SCSI_Data_port);#if EVERY_ACCESS			printk("Message = %x, ", current_SC->SCp.Message);#endif			if (!current_SC->SCp.Message)				++done;#if DEBUG_MESSAGES || EVERY_ACCESS			if (current_SC->SCp.Message) {				printk("fd_mcs: message = %x\n", current_SC->SCp.Message);			}#endif			break;		}	}	if (chip == tmc1800 && !current_SC->SCp.have_data_in && (current_SC->SCp.sent_command >= current_SC->cmd_len)) {		/* We have to get the FIFO direction		   correct, so I've made a table based		   on the SCSI Standard of which commands		   appear to require a DATA OUT phase.		 */		/*		   p. 94: Command for all device types		   CHANGE DEFINITION            40 DATA OUT		   COMPARE                      39 DATA OUT		   COPY                         18 DATA OUT		   COPY AND VERIFY              3a DATA OUT		   INQUIRY                      12 		   LOG SELECT                   4c DATA OUT		   LOG SENSE                    4d		   MODE SELECT (6)              15 DATA OUT		   MODE SELECT (10)             55 DATA OUT		   MODE SENSE (6)               1a		   MODE SENSE (10)              5a		   READ BUFFER                  3c		   RECEIVE DIAGNOSTIC RESULTS   1c		   REQUEST SENSE                03		   SEND DIAGNOSTIC              1d DATA OUT		   TEST UNIT READY              00		   WRITE BUFFER                 3b DATA OUT		   p.178: Commands for direct-access devices (not listed on p. 94)		   FORMAT UNIT                  04 DATA OUT		   LOCK-UNLOCK CACHE            36		   PRE-FETCH                    34		   PREVENT-ALLOW MEDIUM REMOVAL 1e		   READ (6)/RECEIVE             08		   READ (10)                    3c		   READ CAPACITY                25		   READ DEFECT DATA (10)        37		   READ LONG                    3e		   REASSIGN BLOCKS              07 DATA OUT		   RELEASE                      17		   RESERVE                      16 DATA OUT		   REZERO UNIT/REWIND           01		   SEARCH DATA EQUAL (10)       31 DATA OUT		   SEARCH DATA HIGH (10)        30 DATA OUT		   SEARCH DATA LOW (10)         32 DATA OUT		   SEEK (6)                     0b		   SEEK (10)                    2b		   SET LIMITS (10)              33		   START STOP UNIT              1b		   SYNCHRONIZE CACHE            35		   VERIFY (10)                  2f		   WRITE (6)/PRINT/SEND         0a DATA OUT		   WRITE (10)/SEND              2a DATA OUT		   WRITE AND VERIFY (10)        2e DATA OUT		   WRITE LONG                   3f DATA OUT		   WRITE SAME                   41 DATA OUT ?		   p. 261: Commands for sequential-access devices (not previously listed)		   ERASE                        19		   LOAD UNLOAD                  1b		   LOCATE                       2b		   READ BLOCK LIMITS            05		   READ POSITION                34		   READ REVERSE                 0f		   RECOVER BUFFERED DATA        14		   SPACE                        11		   WRITE FILEMARKS              10 ?		   p. 298: Commands for printer devices (not previously listed)		   ****** NOT SUPPORTED BY THIS DRIVER, since 0b is SEEK (6) *****		   SLEW AND PRINT               0b DATA OUT  -- same as seek		   STOP PRINT                   1b		   SYNCHRONIZE BUFFER           10		   p. 315: Commands for processor devices (not previously listed)		   p. 321: Commands for write-once devices (not previously listed)		   MEDIUM SCAN                  38		   READ (12)                    a8		   SEARCH DATA EQUAL (12)       b1 DATA OUT		   SEARCH DATA HIGH (12)        b0 DATA OUT		   SEARCH DATA LOW (12)         b2 DATA OUT		   SET LIMITS (12)              b3		   VERIFY (12)                  af		   WRITE (12)                   aa DATA OUT		   WRITE AND VERIFY (12)        ae DATA OUT		   p. 332: Commands for CD-ROM devices (not previously listed)		   PAUSE/RESUME                 4b		   PLAY AUDIO (10)              45		   PLAY AUDIO (12)              a5		   PLAY AUDIO MSF               47		   PLAY TRACK RELATIVE (10)     49		   PLAY TRACK RELATIVE (12)     a9		   READ HEADER                  44		   READ SUB-CHANNEL             42		   READ TOC                     43		   p. 370: Commands for scanner devices (not previously listed)		   GET DATA BUFFER STATUS       34		   GET WINDOW                   25		   OBJECT POSITION              31		   SCAN                         1b		   SET WINDOW                   24 DATA OUT		   p. 391: Commands for optical memory devices (not listed)		   ERASE (10)                   2c		   ERASE (12)                   ac		   MEDIUM SCAN                  38 DATA OUT		   READ DEFECT DATA (12)        b7		   READ GENERATION              29		   READ UPDATED BLOCK           2d		   UPDATE BLOCK                 3d DATA OUT		   p. 419: Commands for medium changer devices (not listed)		   EXCHANGE MEDIUM              46		   INITIALIZE ELEMENT STATUS    07		   MOVE MEDIUM                  a5		   POSITION TO ELEMENT          2b		   READ ELEMENT STATUS          b8		   REQUEST VOL. ELEMENT ADDRESS b5		   SEND VOLUME TAG              b6 DATA OUT		   p. 454: Commands for communications devices (not listed previously)		   GET MESSAGE (6)              08		   GET MESSAGE (10)             28		   GET MESSAGE (12)             a8		 */		switch (current_SC->cmnd[0]) {		case CHANGE_DEFINITION:		case COMPARE:		case COPY:		case COPY_VERIFY:		case LOG_SELECT:		case MODE_SELECT:		case MODE_SELECT_10:		case SEND_DIAGNOSTIC:		case WRITE_BUFFER:		case FORMAT_UNIT:		case REASSIGN_BLOCKS:		case RESERVE:		case SEARCH_EQUAL:		case SEARCH_HIGH:		case SEARCH_LOW:		case WRITE_6:		case WRITE_10:		case WRITE_VERIFY:		case 0x3f:		case 0x41:		case 0xb1:		case 0xb0:		case 0xb2:		case 0xaa:		case 0xae:		case 0x24:		case 0x38:		case 0x3d:		case 0xb6:		case 0xea:	/* alternate number for WRITE LONG */			current_SC->SCp.have_data_in = -1;			outb(0xd0 | PARITY_MASK, TMC_Cntl_port);			break;		case 0x00:		default:			current_SC->SCp.have_data_in = 1;			outb(0x90 | PARITY_MASK, TMC_Cntl_port);			break;		}	}	if (current_SC->SCp.have_data_in == -1) {	/* DATA OUT */		while ((data_count = FIFO_Size - inw(FIFO_Data_Count_port)) > 512) {#if EVERY_ACCESS			printk("DC=%d, ", data_count);#endif			if (data_count > current_SC->SCp.this_residual)				data_count = current_SC->SCp.this_residual;			if (data_count > 0) {#if EVERY_ACCESS				printk("%d OUT, ", data_count);#endif				if (data_count == 1) {					Bytes_Written++;					outb(*current_SC->SCp.ptr++, Write_FIFO_port);					--current_SC->SCp.this_residual;				} else {					data_count >>= 1;					tmp_count = data_count << 1;					outsw(Write_FIFO_port, current_SC->SCp.ptr, data_count);					current_SC->SCp.ptr += tmp_count;					Bytes_Written += tmp_count;					current_SC->SCp.this_residual -= tmp_count;				}			}			if (!current_SC->SCp.this_residual) {				if (current_SC->SCp.buffers_residual) {					--current_SC->SCp.buffers_residual;					++current_SC->SCp.buffer;					current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;					current_SC->SCp.this_residual = current_SC->SCp.buffer->length;				} else					break;			}		}	} else if (current_SC->SCp.have_data_in == 1) {	/* DATA IN */		while ((data_count = inw(FIFO_Data_Count_port)) > 0) {#if EVERY_ACCESS			printk("DC=%d, ", data_count);#endif			if (data_count > current_SC->SCp.this_residual)				data_count = current_SC->SCp.this_residual;			if (data_count) {#if EVERY_ACCESS				printk("%d IN, ", data_count);#endif				if (data_count == 1) {					Bytes_Read++;					*current_SC->SCp.ptr++ = inb(Read_FIFO_port);					--current_SC->SCp.this_residual;				} else {					data_count >>= 1;	/* Number of words */					tmp_count = data_count << 1;					insw(Read_FIFO_port, current_SC->SCp.ptr, data_count);					current_SC->SCp.ptr += tmp_count;					Bytes_Read += tmp_count;					current_SC->SCp.this_residual -= tmp_count;				}			}			if (!current_SC->SCp.this_residual && current_SC->SCp.buffers_residual) {				--current_SC->SCp.buffers_residual;				++current_SC->SCp.buffer;				current_SC->SCp.ptr = page_address(current_SC->SCp.buffer->page) + current_SC->SCp.buffer->offset;				current_SC->SCp.this_residual = current_SC->SCp.buffer->length;			}		}	}	if (done) {#if EVERY_ACCESS		printk(" ** IN DONE %d ** ", current_SC->SCp.have_data_in);#endif#if ERRORS_ONLY		if (current_SC->cmnd[0] == REQUEST_SENSE && !current_SC->SCp.Status) {			if ((unsigned char) (*((char *) current_SC->request_buffer + 2)) & 0x0f) {				unsigned char key;				unsigned char code;				unsigned char qualifier;				key = (unsigned char) (*((char *) current_SC->request_buffer + 2)) & 0x0f;				code = (unsigned char) (*((char *) current_SC->request_buffer + 12));				qualifier = (unsigned char) (*((char *) current_SC->request_buffer + 13));				if (key != UNIT_ATTENTION && !(key == NOT_READY && code == 0x04 && (!qualifier || qualifier == 0x02 || qualifier == 0x01))				    && !(key == ILLEGAL_REQUEST && (code == 0x25 || code == 0x24 || !code)))					printk("fd_mcs: REQUEST SENSE " "Key = %x, Code = %x, Qualifier = %x\n", key, code, qualifier);			}		}#endif#if EVERY_ACCESS		printk("BEFORE MY_DONE. . .");#endif		spin_lock_irqsave(shpnt->host_lock, flags);		my_done(shpnt, (current_SC->SCp.Status & 0xff)			| ((current_SC->SCp.Message & 0xff) << 8) | (DID_OK << 16));		spin_unlock_irqrestore(shpnt->host_lock, flags);#if EVERY_ACCESS		printk("RETURNING.\n");#endif	} else {		if (current_SC->SCp.phase & disconnect) {			outb(0xd0 | FIFO_COUNT, Interrupt_Cntl_port);			outb(0x00, SCSI_Cntl_port);		} else {			outb(0x90 | FIFO_COUNT, Interrupt_Cntl_port);		}	}#if DEBUG_RACE	in_interrupt_flag = 0;#endif	return IRQ_HANDLED;}
4520	/local/tlutelli/issta_data/temp/c/2005_temp/2005/4520/422c0d61d591cbfb70f029e13505fb437e169d68/fd_mcs.c/clean/drivers/scsi/fd_mcs.c