⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 aha1542.c

📁 linux0.99源代码用于研究linux操作系统
💻 C
📖 第 1 页 / 共 2 页
字号:
    if (done)      printk("aha1542_queuecommand: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);    else      printk("aha1542_command: dev %d cmd %02x pos %d len %d ", target, *cmd, i, bufflen);    aha1542_stat();    printk("aha1542_queuecommand: dumping scsi cmd:");    for (i = 0; i < (*cmd<=0x1f?6:10); i++) printk("%02x ", cmd[i]);    printk("\n");    if (*cmd == WRITE_10 || *cmd == WRITE_6)      return 0; /* we are still testing, so *don't* write */#endif/* Use the outgoing mailboxes in a round-robin fashion, because this   is how the host adapter will scan for them */    cli();    mbo = aha1542_last_mbo_used + 1;    if (mbo >= AHA1542_MAILBOXES) mbo = 0;    do{      if(mb[mbo].status == 0 && SCint[mbo] == NULL)	break;      mbo++;      if (mbo >= AHA1542_MAILBOXES) mbo = 0;    } while (mbo != aha1542_last_mbo_used);    if(mb[mbo].status || SCint[mbo])      panic("Unable to find empty mailbox for aha1542.\n");    SCint[mbo] = SCpnt;  /* This will effectively prevent someone else from			    screwing with this cdb. */    aha1542_last_mbo_used = mbo;        sti();#ifdef DEBUG    printk("Sending command (%d %x)...",mbo, done);#endif    memset(&ccb[mbo], 0, sizeof(struct ccb));    ccb[mbo].cdblen = (*cmd<=0x1f)?6:10;	/* SCSI Command Descriptor Block Length */    direction = 0;    if (*cmd == READ_10 || *cmd == READ_6)	direction = 8;    else if (*cmd == WRITE_10 || *cmd == WRITE_6)	direction = 16;    memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen);    if (SCpnt->use_sg) {      struct scatterlist * sgpnt;      struct chain * cptr;#ifdef DEBUG      unsigned char * ptr;#endif      int i;      ccb[mbo].op = 2;	      /* SCSI Initiator Command  w/scatter-gather*/      SCpnt->host_scribble = scsi_malloc(512);      sgpnt = (struct scatterlist *) SCpnt->request_buffer;      cptr = (struct chain *) SCpnt->host_scribble;       if (cptr == NULL) panic("aha1542.c: unable to allocate DMA memory\n");      for(i=0; i<SCpnt->use_sg; i++) {	if(sgpnt[i].length == 0 || SCpnt->use_sg > 16 || 	   (((int)sgpnt[i].address) & 1) || (sgpnt[i].length & 1)){	  unsigned char * ptr;	  printk("Bad segment list supplied to aha1542.c (%d, %d)\n",SCpnt->use_sg,i);	  for(i=0;i<SCpnt->use_sg++;i++){	    printk("%d: %x %x %d\n",i,sgpnt[i].address, sgpnt[i].alt_address,		   sgpnt[i].length);	  };	  printk("cptr %x: ",cptr);	  ptr = (unsigned char *) &cptr[i];	  for(i=0;i<18;i++) printk("%02x ", ptr[i]);	  panic("Foooooooood fight!");	};	any2scsi(cptr[i].dataptr, sgpnt[i].address);	any2scsi(cptr[i].datalen, sgpnt[i].length);      };      any2scsi(ccb[mbo].datalen, SCpnt->use_sg * sizeof(struct chain));      any2scsi(ccb[mbo].dataptr, cptr);#ifdef DEBUG      printk("cptr %x: ",cptr);      ptr = (unsigned char *) cptr;      for(i=0;i<18;i++) printk("%02x ", ptr[i]);#endif    } else {      ccb[mbo].op = 0;	      /* SCSI Initiator Command */      SCpnt->host_scribble = NULL;      any2scsi(ccb[mbo].datalen, bufflen);      any2scsi(ccb[mbo].dataptr, buff);    };    ccb[mbo].idlun = (target&7)<<5 | direction | (lun & 7); /*SCSI Target Id*/    ccb[mbo].rsalen = 12;    ccb[mbo].linkptr[0] = ccb[mbo].linkptr[1] = ccb[mbo].linkptr[2] = 0;    ccb[mbo].commlinkid = 0;#ifdef DEBUGd    { int i;    printk("aha1542_command: sending.. ");    for (i = 0; i < sizeof(ccb[mbo])-10; i++)      printk("%02x ", ((unchar *)&ccb[mbo])[i]);    };#endif        if (done) {	DEB(printk("aha1542_queuecommand: now waiting for interrupt "); aha1542_stat());	SCpnt->scsi_done = done;	mb[mbo].status = 1;	aha1542_out(&ahacmd, 1);		/* start scsi command */	DEB(aha1542_stat());    }    else      printk("aha1542_queuecommand: done can't be NULL\n");        return 0;}static volatile int internal_done_flag = 0;static volatile int internal_done_errcode = 0;static void internal_done(Scsi_Cmnd * SCpnt){    internal_done_errcode = SCpnt->result;    ++internal_done_flag;}int aha1542_command(Scsi_Cmnd * SCpnt){    DEB(printk("aha1542_command: ..calling aha1542_queuecommand\n"));    aha1542_queuecommand(SCpnt, internal_done);    while (!internal_done_flag);    internal_done_flag = 0;    return internal_done_errcode;}/* Initialize mailboxes */static void setup_mailboxes(){    int i;    static unchar cmd[5] = {CMD_MBINIT, AHA1542_MAILBOXES};    for(i=0; i<AHA1542_MAILBOXES; i++){      mb[i].status = mb[AHA1542_MAILBOXES+i].status = 0;      any2scsi(mb[i].ccbptr, &ccb[i]);    };    aha1542_intr_reset();     /* reset interrupts, so they don't block */	    any2scsi((cmd+2), mb);    aha1542_out(cmd, 5);    WAIT(INTRFLAGS, INTRMASK, HACC, 0);    while (0) {      fail:	printk("aha1542_detect: failed setting up mailboxes\n");    }    aha1542_intr_reset();}/* Query the board to find out if it is a 1542 or a 1740, or whatever. */static int aha1542_getconfig(int hostnum){  static unchar inquiry_cmd[] = {CMD_RETCONF };  static unchar inquiry_result[3];  int i;  i = inb(STATUS);  if (i & DF) {    i = inb(DATA);  };  aha1542_out(inquiry_cmd, 1);  aha1542_in(inquiry_result, 3);  WAIT(INTRFLAGS, INTRMASK, HACC, 0);  while (0) {  fail:    printk("aha1542_detect: query board settings\n");  }  aha1542_intr_reset();  switch(inquiry_result[0]){  case 0x80:    dma_chan = 7;    break;  case 0x40:    dma_chan = 6;    break;  case 0x20:    dma_chan = 5;    break;  case 1:    printk("DMA priority 0 not available for Adaptec driver\n");    return -1;  default:    printk("Unable to determine Adaptec DMA priority.  Disabling board\n");    return -1;  };  switch(inquiry_result[1]){  case 0x40:    irq_level = 15;    break;  case 0x20:    irq_level = 14;    break;  case 0x8:    irq_level = 12;    break;  case 0x4:    irq_level = 11;    break;  case 0x2:    irq_level = 10;    break;  case 0x1:    irq_level = 9;    break;  default:    printk("Unable to determine Adaptec IRQ level.  Disabling board\n");    return -1;  };  return 0;}/* Query the board to find out if it is a 1542 or a 1740, or whatever. */static void aha1542_query(int hostnum){  static unchar inquiry_cmd[] = {CMD_INQUIRY };  static unchar inquiry_result[4];  int i;  i = inb(STATUS);  if (i & DF) {    i = inb(DATA);  };  aha1542_out(inquiry_cmd, 1);  aha1542_in(inquiry_result, 4);  WAIT(INTRFLAGS, INTRMASK, HACC, 0);  while (0) {  fail:    printk("aha1542_detect: query card type\n");  }  aha1542_intr_reset();/* For an AHA1740 series board, we ignore the board since there is a   hardware bug which can lead to wrong blocks being returned if the board   is operating in the 1542 emulation mode.  Since there is an extended mode   driver, we simply ignore the board and let the 1740 driver pick it up.*/  if (inquiry_result[0] == 0x43) {    printk("aha1542.c: Emulation mode not supported for AHA 174N hardware.\n");    aha_disable = 1;  };}/* return non-zero on detection */int aha1542_detect(int hostnum){    int i;    int indx;    DEB(printk("aha1542_detect: \n"));        indx = 0;    while(indx < sizeof(bases)/sizeof(bases[0])){      i = aha1542_test_port(bases[indx]);      if (i) break;      indx++;    }    if (indx == sizeof(bases)/sizeof(bases[0])) return 0;     /* Set the Bus on/off-times as not to ruin floppy performance */    {	static unchar oncmd[] = {CMD_BUSON_TIME, 7};	static unchar offcmd[] = {CMD_BUSOFF_TIME, 5};	aha1542_intr_reset();	aha1542_out(oncmd, 2);	WAIT(INTRFLAGS, INTRMASK, HACC, 0);	aha1542_intr_reset();	aha1542_out(offcmd, 2);	WAIT(INTRFLAGS, INTRMASK, HACC, 0);	while (0) {	  fail:	    printk("aha1542_detect: setting bus on/off-time failed\n");	}	aha1542_intr_reset();    }    aha1542_query(hostnum);    if (aha_disable) return 0;    if (aha1542_getconfig(hostnum) == -1) return 0;        printk("Configuring Adaptec at IO:%x, IRQ %d, DMA priority %d\n",base,	   irq_level, dma_chan);    DEB(aha1542_stat());    setup_mailboxes();    DEB(aha1542_stat());    DEB(printk("aha1542_detect: enable interrupt channel %d\n", irq_level));    if (request_irq(irq_level,aha1542_intr_handle)) {      printk("Unable to allocate IRQ for adaptec controller.\n");      return 0;    };    if(request_dma(dma_chan)){      printk("Unable to allocate DMA channel for Adaptec.\n");      free_irq(irq_level);      return 0;    };    if(dma_chan >= 5){      outb(((dma_chan - 4)|CASCADE),DMA_MODE_REG);      outb((dma_chan-4),DMA_MASK_REG);    };#if 0    DEB(printk(" *** READ CAPACITY ***\n"));    {	unchar buf[8];	static unchar cmd[] = {	READ_CAPACITY, 0, 0, 0, 0, 0, 0, 0, 0, 0};	int i;		for (i = 0; i < sizeof(buf); ++i) buf[i] = 0x87;	for (i = 0; i < 2; ++i)	  if (!aha1542_command(i, cmd, buf, sizeof(buf))) {	      printk("aha_detect: LU %d sector_size %d device_size %d\n",		     i, xscsi2int(buf+4), xscsi2int(buf));	  }    }    DEB(printk(" *** NOW RUNNING MY OWN TEST *** \n"));    for (i = 0; i < 4; ++i)      {	  unsigned char cmd[10];	  static buffer[512];	  	  cmd[0] = READ_10;	  cmd[1] = 0;	  xany2scsi(cmd+2, i);	  cmd[6] = 0;	  cmd[7] = 0;	  cmd[8] = 1;	  cmd[9] = 0;	  aha1542_command(0, cmd, buffer, 512);      }#endif    aha1542_host = hostnum;    return 1;}/* The abort command does not leave the device in a clean state where   it is available to be used again.  Until this gets worked out, we will   leave it commented out.  */int aha1542_abort(Scsi_Cmnd * SCpnt, int i){#if 0    unchar ahacmd = CMD_START_SCSI;    int mbo;#endif    DEB(printk("aha1542_abort\n"));#if 0    cli();    for(mbo = 0; mbo < AHA1542_MAILBOXES; mbo++)      if (SCpnt == SCint[mbo]){	mb[mbo].status = 2;  /* Abort command */	aha1542_out(&ahacmd, 1);		/* start scsi command */	sti();	break;      };#endif    return 0;}int aha1542_reset(void){    DEB(printk("aha1542_reset called\n"));    return 0;}int aha1542_biosparam(int size, int dev, int* info){  info[0] = 64;  info[1] = 32;  info[2] = size >> 11;  if (info[2] >= 1024) info[2] = 1024;  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -