drivers/scsi/pcmcia/sym53c500_cs.c

Source file repositories/reference/linux-study-clean/drivers/scsi/pcmcia/sym53c500_cs.c

File Facts

System
Linux kernel
Corpus path
drivers/scsi/pcmcia/sym53c500_cs.c
Extension
.c
Size
23057 bytes
Lines
883
Domain
Driver Families
Bucket
drivers/scsi
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

struct scsi_info_t {
	struct pcmcia_device	*p_dev;
	struct Scsi_Host *host;
	unsigned short manf_id;
};

/*
*  Repository for per-instance host data.
*/
struct sym53c500_data {
	struct scsi_cmnd *current_SC;
	int fast_pio;
};

struct sym53c500_cmd_priv {
	int status;
	int message;
	int phase;
};

enum Phase {
    idle,
    data_out,
    data_in,
    command_ph,
    status_ph,
    message_out,
    message_in
};

/* ================================================================== */

static void
chip_init(int io_port)
{
	REG1(io_port);
	outb(0x01, io_port + PIO_STATUS);
	outb(0x00, io_port + PIO_FLAG);

	outb(C4_IMG, io_port + CONFIG4);	/* REG0(io_port); */
	outb(C3_IMG, io_port + CONFIG3);
	outb(C2_IMG, io_port + CONFIG2);
	outb(C1_IMG, io_port + CONFIG1);

	outb(0x05, io_port + CLKCONV);	/* clock conversion factor */
	outb(0x9C, io_port + SRTIMOUT);	/* Selection timeout */
	outb(0x05, io_port + SYNCPRD);	/* Synchronous transfer period */
	outb(SYNC_MODE, io_port + SYNCOFF);	/* synchronous mode */  
}

static void
SYM53C500_int_host_reset(int io_port)
{
	outb(C4_IMG, io_port + CONFIG4);	/* REG0(io_port); */
	outb(CHIP_RESET, io_port + CMD_REG);
	outb(SCSI_NOP, io_port + CMD_REG);	/* required after reset */
	outb(SCSI_RESET, io_port + CMD_REG);
	chip_init(io_port);
}

static __inline__ int
SYM53C500_pio_read(int fast_pio, int base, unsigned char *request, unsigned int reqlen)
{
	int i;
	int len;	/* current scsi fifo size */

	REG1(base);
	while (reqlen) {
		i = inb(base + PIO_STATUS);
		/* VDEB(printk("pio_status=%x\n", i)); */
		if (i & 0x80) 
			return 0;

		switch (i & 0x1e) {
		default:
		case 0x10:	/* fifo empty */
			len = 0;
			break;
		case 0x0:
			len = 1;
			break; 
		case 0x8:	/* fifo 1/3 full */
			len = 42;
			break;
		case 0xc:	/* fifo 2/3 full */
			len = 84;
			break;
		case 0xe:	/* fifo full */
			len = 128;
			break;

Annotation

Implementation Notes