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

📄 eata.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
      else if (c == 'y' || c == 'Y') val = TRUE;      else val = (int) simple_strtoul(pc, NULL, 0);      if (!strncmp(cur, "lc:", 3)) linked_comm = val;      else if (!strncmp(cur, "tc:", 3)) tagged_comm = val;      else if (!strncmp(cur, "tm:", 3)) tag_mode = val;      else if (!strncmp(cur, "mq:", 3))  max_queue_depth = val;      else if (!strncmp(cur, "ls:", 3))  link_statistics = val;      else if (!strncmp(cur, "eh:", 3))  use_new_eh_code = val;      else if (!strncmp(cur, "et:", 3))  ext_tran = val;      else if (!strncmp(cur, "rs:", 3))  rev_scan = val;      if ((cur = strchr(cur, ','))) ++cur;      }   return;}__initfunc (static void add_pci_ports(void)) {#if defined(CONFIG_PCI)   unsigned int addr, k;#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,93)   struct pci_dev *dev = NULL;   if (!pci_present()) return;   for (k = 0; k < MAX_PCI; k++) {      if (!(dev = pci_find_class(PCI_CLASS_STORAGE_SCSI << 8, dev))) break;      if (pci_read_config_dword(dev, PCI_BASE_ADDRESS_0, &addr)) continue;#if defined(DEBUG_PCI_DETECT)      printk("%s: detect, seq. %d, bus %d, devfn 0x%x, addr 0x%x.\n",             driver_name, k, dev->bus->number, dev->devfn, addr);#endif      if ((addr & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO)             continue;      /* Order addresses according to rev_scan value */      io_port[MAX_INT_PARAM + (rev_scan ? (MAX_PCI - k) : (1 + k))] =             (addr & PCI_BASE_ADDRESS_IO_MASK) + PCI_BASE_ADDRESS_0;      }#else  /* else old style PCI code */   unsigned short i = 0;   unsigned char bus, devfn;   if (!pcibios_present()) return;   for (k = 0; k < MAX_PCI; k++) {      if (pcibios_find_class(PCI_CLASS_STORAGE_SCSI << 8, i++, &bus, &devfn)             != PCIBIOS_SUCCESSFUL) break;      if (pcibios_read_config_dword(bus, devfn, PCI_BASE_ADDRESS_0, &addr)             != PCIBIOS_SUCCESSFUL) continue;#if defined(DEBUG_PCI_DETECT)      printk("%s: detect, seq. %d, bus %d, devfn 0x%x, addr 0x%x.\n",             driver_name, k, bus, devfn, addr);#endif      if ((addr & PCI_BASE_ADDRESS_SPACE) != PCI_BASE_ADDRESS_SPACE_IO)             continue;      /* Order addresses according to rev_scan value */      io_port[MAX_INT_PARAM + (rev_scan ? (MAX_PCI - k) : (1 + k))] =             (addr & PCI_BASE_ADDRESS_IO_MASK) + PCI_BASE_ADDRESS_0;      }#endif /* end old style PCI code */#endif /* end CONFIG_PCI */   return;}__initfunc (int eata2x_detect(Scsi_Host_Template *tpnt)) {   unsigned int j = 0, k;   IRQ_FLAGS   IRQ_LOCK_SAVE   tpnt->proc_dir = &proc_scsi_eata2x;#if defined(MODULE)   /* io_port could have been modified when loading as a module */   if(io_port[0] != SKIP) {      setup_done = TRUE;      io_port[MAX_INT_PARAM] = 0;      }#endif   for (k = 0; k < MAX_BOARDS + 1; k++) sh[k] = NULL;   if (!setup_done) add_pci_ports();   for (k = 0; io_port[k]; k++) {      if (io_port[k] == SKIP) continue;      if (j < MAX_BOARDS && port_detect(io_port[k], j, tpnt)) j++;      }   num_boards = j;   IRQ_UNLOCK_RESTORE   return j;}static inline void build_sg_list(struct mscp *cpp, Scsi_Cmnd *SCpnt) {   unsigned int k;   struct scatterlist *sgpnt;   sgpnt = (struct scatterlist *) SCpnt->request_buffer;   for (k = 0; k < SCpnt->use_sg; k++) {      cpp->sglist[k].address = V2DEV(sgpnt[k].address);      cpp->sglist[k].num_bytes = H2DEV(sgpnt[k].length);      }   cpp->data_address = V2DEV(cpp->sglist);   cpp->data_len = H2DEV((SCpnt->use_sg * sizeof(struct sg_list)));}static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {   unsigned int i, j, k;   struct mscp *cpp;   struct mssp *spp;   static const unsigned char data_out_cmds[] = {      0x0a, 0x2a, 0x15, 0x55, 0x04, 0x07, 0x18, 0x1d, 0x24, 0x2e,      0x30, 0x31, 0x32, 0x38, 0x39, 0x3a, 0x3b, 0x3d, 0x3f, 0x40,      0x41, 0x4c, 0xaa, 0xae, 0xb0, 0xb1, 0xb2, 0xb6, 0xea, 0x1b      };   static const unsigned char data_none_cmds[] = {      0x01, 0x0b, 0x10, 0x11, 0x13, 0x16, 0x17, 0x19, 0x2b, 0x1e,      0x2c, 0xac, 0x2f, 0xaf, 0x33, 0xb3, 0x35, 0x36, 0x45, 0x47,      0x48, 0x49, 0xa9, 0x4b, 0xa5, 0xa6, 0xb5      };   /* j is the board number */   j = ((struct hostdata *) SCpnt->host->hostdata)->board_number;   if (SCpnt->host_scribble)      panic("%s: qcomm, pid %ld, SCpnt %p already active.\n",            BN(j), SCpnt->pid, SCpnt);   /* i is the mailbox number, look for the first free mailbox      starting from last_cp_used */   i = HD(j)->last_cp_used + 1;   for (k = 0; k < sh[j]->can_queue; k++, i++) {      if (i >= sh[j]->can_queue) i = 0;      if (HD(j)->cp_stat[i] == FREE) {         HD(j)->last_cp_used = i;         break;         }      }   if (k == sh[j]->can_queue) {      printk("%s: qcomm, no free mailbox.\n", BN(j));      return 1;      }   /* Set pointer to control packet structure */   cpp = &HD(j)->cp[i];   memset(cpp, 0, sizeof(struct mscp) - sizeof(struct sg_list *));   /* Set pointer to status packet structure */   spp = &HD(j)->sp[0];   /* The EATA protocol uses Big Endian format */   cpp->sp_addr = V2DEV(spp);   cpp->cpp = cpp;   SCpnt->scsi_done = done;   cpp->index = i;   SCpnt->host_scribble = (unsigned char *) &cpp->index;   if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n",                        BN(j), i, SCpnt->channel, SCpnt->target,                        SCpnt->lun, SCpnt->pid);   for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)     if (SCpnt->cmnd[0] == data_out_cmds[k]) {        cpp->dout = TRUE;        break;        }   if ((cpp->din = !cpp->dout))      for (k = 0; k < ARRAY_SIZE(data_none_cmds); k++)        if (SCpnt->cmnd[0] == data_none_cmds[k]) {           cpp->din = FALSE;           break;           }   cpp->reqsen = TRUE;   cpp->dispri = TRUE;#if 0   if (SCpnt->device->type == TYPE_TAPE) cpp->hbaci = TRUE;#endif   cpp->one = TRUE;   cpp->channel = SCpnt->channel;   cpp->target = SCpnt->target;   cpp->lun = SCpnt->lun;   cpp->SCpnt = SCpnt;   cpp->sense_addr = V2DEV(SCpnt->sense_buffer);   cpp->sense_len = sizeof SCpnt->sense_buffer;   if (SCpnt->device->tagged_queue) {      if (HD(j)->target_redo[SCpnt->target][SCpnt->channel] ||            HD(j)->target_to[SCpnt->target][SCpnt->channel])         cpp->mess[0] = ORDERED_QUEUE_TAG;      else if (tag_mode == TAG_SIMPLE)  cpp->mess[0] = SIMPLE_QUEUE_TAG;      else if (tag_mode == TAG_HEAD)    cpp->mess[0] = HEAD_OF_QUEUE_TAG;      else if (tag_mode == TAG_ORDERED) cpp->mess[0] = ORDERED_QUEUE_TAG;      else if (SCpnt->device->current_tag == 0)         cpp->mess[0] = ORDERED_QUEUE_TAG;      else if (SCpnt->device->current_tag == 1)         cpp->mess[0] = HEAD_OF_QUEUE_TAG;      else         cpp->mess[0] = SIMPLE_QUEUE_TAG;      cpp->mess[1] = SCpnt->device->current_tag++;      }   if (SCpnt->use_sg) {      cpp->sg = TRUE;      build_sg_list(cpp, SCpnt);      }   else {      cpp->data_address = V2DEV(SCpnt->request_buffer);      cpp->data_len = H2DEV(SCpnt->request_bufflen);      }   memcpy(cpp->cdb, SCpnt->cmnd, SCpnt->cmd_len);   if (linked_comm && SCpnt->device->queue_depth > 2                                     && TLDEV(SCpnt->device->type)) {      HD(j)->cp_stat[i] = READY;      flush_dev(SCpnt->device, SCpnt->request.sector, j, FALSE);      return 0;      }   /* Send control packet to the board */   if (do_dma(sh[j]->io_port, (unsigned int) cpp, SEND_CP_DMA)) {      SCpnt->host_scribble = NULL;      printk("%s: qcomm, target %d.%d:%d, pid %ld, adapter busy.\n",             BN(j), SCpnt->channel, SCpnt->target, SCpnt->lun, SCpnt->pid);      return 1;      }   HD(j)->cp_stat[i] = IN_USE;   return 0;}int eata2x_queuecommand(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {   int rtn;   IRQ_FLAGS   IRQ_LOCK_SAVE   rtn = do_qcomm(SCpnt, done);   IRQ_UNLOCK_RESTORE   return rtn;}static inline int do_old_abort(Scsi_Cmnd *SCarg) {   unsigned int i, j;   j = ((struct hostdata *) SCarg->host->hostdata)->board_number;   if (SCarg->host_scribble == NULL ||       (SCarg->serial_number_at_timeout &&       (SCarg->serial_number != SCarg->serial_number_at_timeout))) {      printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",             BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);      return SCSI_ABORT_NOT_RUNNING;      }   i = *(unsigned int *)SCarg->host_scribble;   printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n",          BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);   if (i >= sh[j]->can_queue)      panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));   if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {      printk("%s: abort, timeout error.\n", BN(j));      return SCSI_ABORT_ERROR;      }   if (HD(j)->cp_stat[i] == FREE) {      printk("%s: abort, mbox %d is free.\n", BN(j), i);      return SCSI_ABORT_NOT_RUNNING;      }   if (HD(j)->cp_stat[i] == IN_USE) {      printk("%s: abort, mbox %d is in use.\n", BN(j), i);      if (SCarg != HD(j)->cp[i].SCpnt)         panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n",               BN(j), i, SCarg, HD(j)->cp[i].SCpnt);      if (inb(sh[j]->io_port + REG_AUX_STATUS) & IRQ_ASSERTED)         printk("%s: abort, mbox %d, interrupt pending.\n", BN(j), i);      return SCSI_ABORT_SNOOZE;      }   if (HD(j)->cp_stat[i] == IN_RESET) {      printk("%s: abort, mbox %d is in reset.\n", BN(j), i);      return SCSI_ABORT_ERROR;      }   if (HD(j)->cp_stat[i] == LOCKED) {      printk("%s: abort, mbox %d is locked.\n", BN(j), i);      return SCSI_ABORT_NOT_RUNNING;      }   if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) {      SCarg->result = DID_ABORT << 16;      SCarg->host_scribble = NULL;      HD(j)->cp_stat[i] = FREE;      printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n",             BN(j), i, SCarg->pid);      SCarg->scsi_done(SCarg);      return SCSI_ABORT_SUCCESS;      }   panic("%s: abort, mbox %d, invalid cp_stat.\n", BN(j), i);}int eata2x_old_abort(Scsi_Cmnd *SCarg) {   int rtn;   IRQ_FLAGS   IRQ_LOCK_SAVE   rtn = do_old_abort(SCarg);   IRQ_UNLOCK_RESTORE   return rtn;}#if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,101)static inline int do_abort(Scsi_Cmnd *SCarg) {   unsigned int i, j;   j = ((struct hostdata *) SCarg->host->hostdata)->board_number;   if (SCarg->host_scribble == NULL) {      printk("%s: abort, target %d.%d:%d, pid %ld inactive.\n",             BN(j), SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);      return SUCCESS;      }   i = *(unsigned int *)SCarg->host_scribble;   printk("%s: abort, mbox %d, target %d.%d:%d, pid %ld.\n",          BN(j), i, SCarg->channel, SCarg->target, SCarg->lun, SCarg->pid);   if (i >= sh[j]->can_queue)      panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j));   if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {      printk("%s: abort, timeout error.\n", BN(j));      return FAILED;      }   if (HD(j)->cp_stat[i] == FREE) {      printk("%s: abort, mbox %d is free.\n", BN(j), i);      return SUCCESS;      }   if (HD(j)->cp_stat[i] == IN_USE) {      printk("%s: abort, mbox %d is in use.\n", BN(j), i);      if (SCarg != HD(j)->cp[i].SCpnt)         panic("%s: abort, mbox %d, SCarg %p, cp SCpnt %p.\n",               BN(j), i, SCarg, HD(j)->cp[i].SCpnt);

⌨️ 快捷键说明

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