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

📄 u14-34f.c

📁 GNU Mach 微内核源代码, 基于美国卡内基美隆大学的 Mach 研究项目
💻 C
📖 第 1 页 / 共 5 页
字号:
   if (sh[j] == NULL) {      printk("%s: unable to register host, detaching.\n", name);      free_irq(irq, &sha[j]);      if (subversion == ISA) free_dma(dma_channel);      return FALSE;      }   sh[j]->io_port = port_base;   sh[j]->unique_id = port_base;   sh[j]->n_io_port = REGION_SIZE;   sh[j]->base = bios_segment_table[config_1.bios_segment];   sh[j]->irq = irq;   sh[j]->sg_tablesize = MAX_SGLIST;   sh[j]->this_id = config_2.ha_scsi_id;   sh[j]->can_queue = MAX_MAILBOXES;   sh[j]->cmd_per_lun = MAX_CMD_PER_LUN;   sh[j]->select_queue_depths = select_queue_depths;#if defined(DEBUG_DETECT)   {   unsigned char sys_mask, lcl_mask;   sys_mask = inb(sh[j]->io_port + REG_SYS_MASK);   lcl_mask = inb(sh[j]->io_port + REG_LCL_MASK);   printk("SYS_MASK 0x%x, LCL_MASK 0x%x.\n", sys_mask, lcl_mask);   }#endif   /* Probably a bogus host scsi id, set it to the dummy value */   if (sh[j]->this_id == 0) sh[j]->this_id = -1;   /* If BIOS is disabled, force enable interrupts */   if (sh[j]->base == 0) outb(CMD_ENA_INTR, sh[j]->io_port + REG_SYS_MASK);   /* Register the I/O space that we use */   request_region(sh[j]->io_port, sh[j]->n_io_port, driver_name);   memset(HD(j), 0, sizeof(struct hostdata));   HD(j)->heads = mapping_table[config_2.mapping_mode].heads;   HD(j)->sectors = mapping_table[config_2.mapping_mode].sectors;   HD(j)->subversion = subversion;   HD(j)->board_number = j;   if (have_old_firmware) sh[j]->sg_tablesize = MAX_SAFE_SGLIST;   if (HD(j)->subversion == ESA) {      sh[j]->unchecked_isa_dma = FALSE;      sh[j]->dma_channel = NO_DMA;      sprintf(BN(j), "U34F%d", j);      bus_type = "VESA";      }   else {      sh[j]->wish_block = TRUE;      sh[j]->unchecked_isa_dma = TRUE;      disable_dma(dma_channel);      clear_dma_ff(dma_channel);      set_dma_mode(dma_channel, DMA_MODE_CASCADE);      enable_dma(dma_channel);      sh[j]->dma_channel = dma_channel;      sprintf(BN(j), "U14F%d", j);      bus_type = "ISA";      }   sh[j]->max_channel = MAX_CHANNEL - 1;   sh[j]->max_id = MAX_TARGET;   sh[j]->max_lun = MAX_LUN;   if (HD(j)->subversion == ISA && !board_inquiry(j)) {      HD(j)->board_id[40] = 0;      if (strcmp(&HD(j)->board_id[32], "06000600")) {         printk("%s: %s.\n", BN(j), &HD(j)->board_id[8]);         printk("%s: firmware %s is outdated, FW PROM should be 28004-006.\n",                BN(j), &HD(j)->board_id[32]);         sh[j]->hostt->use_clustering = DISABLE_CLUSTERING;         sh[j]->sg_tablesize = MAX_SAFE_SGLIST;         }      }   if (dma_channel == NO_DMA) sprintf(dma_name, "%s", "BMST");   else                       sprintf(dma_name, "DMA %u", dma_channel);   for (i = 0; i < sh[j]->can_queue; i++)      if (! ((&HD(j)->cp[i])->sglist = kmalloc(            sh[j]->sg_tablesize * sizeof(struct sg_list),            (sh[j]->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC))) {         printk("%s: kmalloc SGlist failed, mbox %d, detaching.\n", BN(j), i);         u14_34f_release(sh[j]);         return FALSE;         }   if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN)       max_queue_depth = MAX_TAGGED_CMD_PER_LUN;   if (max_queue_depth < MAX_CMD_PER_LUN) max_queue_depth = MAX_CMD_PER_LUN;   if (j == 0) {      printk("UltraStor 14F/34F: Copyright (C) 1994-1998 Dario Ballabio.\n");      printk("%s config options -> of:%c, lc:%c, mq:%d, eh:%c, et:%c.\n",             driver_name, YESNO(have_old_firmware), YESNO(linked_comm),             max_queue_depth, YESNO(use_new_eh_code), YESNO(ext_tran));      }   printk("%s: %s 0x%03lx, BIOS 0x%05x, IRQ %u, %s, SG %d, MB %d.\n",          BN(j), bus_type, (unsigned long)sh[j]->io_port, (int)sh[j]->base,          sh[j]->irq, dma_name, sh[j]->sg_tablesize, sh[j]->can_queue);   if (sh[j]->max_id > 8 || sh[j]->max_lun > 8)      printk("%s: wide SCSI support enabled, max_id %u, max_lun %u.\n",             BN(j), sh[j]->max_id, sh[j]->max_lun);   for (i = 0; i <= sh[j]->max_channel; i++)      printk("%s: SCSI channel %u enabled, host target ID %d.\n",             BN(j), i, sh[j]->this_id);   return TRUE;}__initfunc (void u14_34f_setup(char *str, int *ints)) {   int i, argc = ints[0];   char *cur = str, *pc;   if (argc > 0) {      if (argc > MAX_INT_PARAM) argc = MAX_INT_PARAM;      for (i = 0; i < argc; i++) io_port[i] = ints[i + 1];      io_port[i] = 0;      setup_done = TRUE;      }   while (cur && (pc = strchr(cur, ':'))) {      int val = 0, c = *++pc;      if (c == 'n' || c == 'N') val = FALSE;      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, "of:", 3)) have_old_firmware = 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;      if ((cur = strchr(cur, ','))) ++cur;      }   return;}__initfunc (int u14_34f_detect(Scsi_Host_Template *tpnt)) {   unsigned int j = 0, k;   IRQ_FLAGS   IRQ_LOCK_SAVE   tpnt->proc_dir = &proc_scsi_u14_34f;#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;   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, data_len = 0;   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);      data_len += sgpnt[k].length;      }   cpp->use_sg = SCpnt->use_sg;   cpp->data_address = V2DEV(cpp->sglist);   cpp->data_len = H2DEV(data_len);}static inline int do_qcomm(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *)) {   unsigned int i, j, k;   struct mscp *cpp;   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 *));   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);   cpp->xdir = DTD_IN;   for (k = 0; k < ARRAY_SIZE(data_out_cmds); k++)      if (SCpnt->cmnd[0] == data_out_cmds[k]) {         cpp->xdir = DTD_OUT;         break;         }   if (cpp->xdir == DTD_IN)      for (k = 0; k < ARRAY_SIZE(data_none_cmds); k++)         if (SCpnt->cmnd[0] == data_none_cmds[k]) {            cpp->xdir = DTD_NONE;            break;            }   cpp->opcode = OP_SCSI;   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->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);      }   cpp->scsi_cdbs_len = SCpnt->cmd_len;   memcpy(cpp->scsi_cdbs, SCpnt->cmnd, cpp->scsi_cdbs_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;      }   if (wait_on_busy(sh[j]->io_port, MAXLOOP)) {      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;      }   /* Store pointer in OGM address bytes */   outl(V2DEV(cpp), sh[j]->io_port + REG_OGM);   /* Issue OGM interrupt */   outb(CMD_OGM_INTR, sh[j]->io_port + REG_LCL_INTR);   HD(j)->cp_stat[i] = IN_USE;   return 0;}int u14_34f_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_SYS_INTR) & 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 u14_34f_old_abort(Scsi_Cmnd *SCarg) {   int rtn;   IRQ_FLAGS

⌨️ 快捷键说明

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