📄 u14-34f.c
字号:
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 + -