📄 icside.c
字号:
{ "Toshiba CD-ROM XM-6202B", "ALL" }, { "CD-532E-A", "ALL" }, { "E-IDE CD-ROM CR-840", "ALL" }, { "CD-ROM Drive/F5A", "ALL" }, { "RICOH CD-R/RW MP7083A", "ALL" }, { "WPI CDD-820", "ALL" }, { "SAMSUNG CD-ROM SC-148C", "ALL" }, { "SAMSUNG CD-ROM SC-148F", "ALL" }, { "SAMSUNG CD-ROM SC", "ALL" }, { "SanDisk SDP3B-64", "ALL" }, { "SAMSUNG CD-ROM SN-124", "ALL" }, { "PLEXTOR CD-R PX-W8432T", "ALL" }, { "ATAPI CD-ROM DRIVE 40X MAXIMUM", "ALL" }, { "_NEC DV5800A", "ALL" }, { NULL, 0 }};static int in_drive_list(struct hd_driveid *id, struct drive_list_entry * drive_table){ for ( ; drive_table->id_model ; drive_table++) if ((!strcmp(drive_table->id_model, id->model)) && ((!strstr(drive_table->id_firmware, id->fw_rev)) || (!strcmp(drive_table->id_firmware, "ALL")))) return 1; return 0;}/* * For both Blacklisted and Whitelisted drives. * This is setup to be called as an extern for future support * to other special driver code. */static int check_drive_lists(ide_drive_t *drive, int good_bad){ struct hd_driveid *id = drive->id; if (good_bad) { return in_drive_list(id, drive_whitelist); } else { int blacklist = in_drive_list(id, drive_blacklist); if (blacklist) printk("%s: Disabling DMA for %s\n", drive->name, id->model); return(blacklist); } return 0;}static inticside_dma_check(ide_drive_t *drive){ struct hd_driveid *id = drive->id; ide_hwif_t *hwif = HWIF(drive); int autodma = hwif->autodma; int xfer_mode = XFER_PIO_2; int func = ide_dma_off_quietly; if (!id || !(id->capability & 1) || !autodma) goto out; /* * Consult the list of known "bad" drives */ if (check_drive_lists(drive, 0)) { func = ide_dma_off; goto out; } /* * Enable DMA on any drive that has multiword DMA */ if (id->field_valid & 2) { if (id->dma_mword & 4) { xfer_mode = XFER_MW_DMA_2; func = ide_dma_on; } else if (id->dma_mword & 2) { xfer_mode = XFER_MW_DMA_1; func = ide_dma_on; } else if (id->dma_mword & 1) { xfer_mode = XFER_MW_DMA_0; func = ide_dma_on; } goto out; } /* * Consult the list of known "good" drives */ if (check_drive_lists(drive, 1)) { if (id->eide_dma_time > 150) goto out; xfer_mode = XFER_MW_DMA_1; func = ide_dma_on; }out: func = icside_config_if(drive, xfer_mode); return hwif->dmaproc(func, drive);}static inticside_dma_verbose(ide_drive_t *drive){ printk(", DMA"); return 1;}static inticside_dmaproc(ide_dma_action_t func, ide_drive_t *drive){ ide_hwif_t *hwif = HWIF(drive); int count, reading = 0; switch (func) { case ide_dma_off: printk("%s: DMA disabled\n", drive->name); /*FALLTHROUGH*/ case ide_dma_off_quietly: case ide_dma_on: drive->using_dma = (func == ide_dma_on); return 0; case ide_dma_check: return icside_dma_check(drive); case ide_dma_read: reading = 1; case ide_dma_write: count = icside_build_dmatable(drive, reading); if (!count) return 1; disable_dma(hwif->hw.dma); /* Route the DMA signals to * to the correct interface. */ outb(hwif->select_data, hwif->config_data); /* Select the correct timing * for this drive */ set_dma_speed(hwif->hw.dma, drive->drive_data); set_dma_sg(hwif->hw.dma, HWIF(drive)->sg_table, count); set_dma_mode(hwif->hw.dma, reading ? DMA_MODE_READ : DMA_MODE_WRITE); drive->waiting_for_dma = 1; if (drive->media != ide_disk) return 0; ide_set_handler(drive, &icside_dmaintr, WAIT_CMD, NULL); OUT_BYTE(reading ? WIN_READDMA : WIN_WRITEDMA, IDE_COMMAND_REG); case ide_dma_begin: enable_dma(hwif->hw.dma); return 0; case ide_dma_end: drive->waiting_for_dma = 0; disable_dma(hwif->hw.dma); icside_destroy_dmatable(drive); return get_dma_residue(hwif->hw.dma) != 0; case ide_dma_test_irq: return inb((unsigned long)hwif->hw.priv) & 1; case ide_dma_bad_drive: case ide_dma_good_drive: return check_drive_lists(drive, (func == ide_dma_good_drive)); case ide_dma_verbose: return icside_dma_verbose(drive); case ide_dma_timeout: default: printk("icside_dmaproc: unsupported %s func: %d\n", ide_dmafunc_verbose(func), func); } return 1;}static inticside_setup_dma(ide_hwif_t *hwif, int autodma){ printk(" %s: SG-DMA", hwif->name); hwif->sg_table = kmalloc(sizeof(struct scatterlist) * NR_ENTRIES, GFP_KERNEL); if (!hwif->sg_table) goto failed; hwif->dmatable_cpu = NULL; hwif->dmatable_dma = 0; hwif->speedproc = icside_set_speed; hwif->dmaproc = icside_dmaproc; hwif->autodma = autodma; printk(" capable%s\n", autodma ? ", auto-enable" : ""); return 1;failed: printk(" -- ERROR, unable to allocate DMA table\n"); return 0;}#endifstatic ide_hwif_t *icside_find_hwif(unsigned long dataport){ ide_hwif_t *hwif; int index; for (index = 0; index < MAX_HWIFS; ++index) { hwif = &ide_hwifs[index]; if (hwif->io_ports[IDE_DATA_OFFSET] == (ide_ioreg_t)dataport) goto found; } for (index = 0; index < MAX_HWIFS; ++index) { hwif = &ide_hwifs[index]; if (!hwif->io_ports[IDE_DATA_OFFSET]) goto found; } return NULL;found: return hwif;}static ide_hwif_t *icside_setup(unsigned long base, struct cardinfo *info, int irq){ unsigned long port = base + info->dataoffset; ide_hwif_t *hwif; hwif = icside_find_hwif(base); if (hwif) { int i; memset(&hwif->hw, 0, sizeof(hw_regs_t)); for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { hwif->hw.io_ports[i] = (ide_ioreg_t)port; hwif->io_ports[i] = (ide_ioreg_t)port; port += 1 << info->stepping; } hwif->hw.io_ports[IDE_CONTROL_OFFSET] = base + info->ctrloffset; hwif->io_ports[IDE_CONTROL_OFFSET] = base + info->ctrloffset; hwif->hw.irq = irq; hwif->irq = irq; hwif->hw.dma = NO_DMA; hwif->noprobe = 0; hwif->chipset = ide_acorn; } return hwif;}static int __init icside_register_v5(struct expansion_card *ec, int autodma){ unsigned long slot_port; ide_hwif_t *hwif; slot_port = ecard_address(ec, ECARD_MEMC, 0); ec->irqaddr = (unsigned char *)ioaddr(slot_port + ICS_ARCIN_V5_INTRSTAT); ec->irqmask = 1; ec->irq_data = (void *)slot_port; ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v5; /* * Be on the safe side - disable interrupts */ inb(slot_port + ICS_ARCIN_V5_INTROFFSET); hwif = icside_setup(slot_port, &icside_cardinfo_v5, ec->irq); return hwif ? 0 : -1;}static int __init icside_register_v6(struct expansion_card *ec, int autodma){ unsigned long slot_port, port; ide_hwif_t *hwif, *mate; int sel = 0; slot_port = ecard_address(ec, ECARD_IOC, ECARD_FAST); port = ecard_address(ec, ECARD_EASI, ECARD_FAST); if (port == 0) port = slot_port; else sel = 1 << 5; outb(sel, slot_port); ec->irq_data = (void *)port; ec->ops = (expansioncard_ops_t *)&icside_ops_arcin_v6; /* * Be on the safe side - disable interrupts */ inb(port + ICS_ARCIN_V6_INTROFFSET_1); inb(port + ICS_ARCIN_V6_INTROFFSET_2); hwif = icside_setup(port, &icside_cardinfo_v6_1, ec->irq); mate = icside_setup(port, &icside_cardinfo_v6_2, ec->irq);#ifdef CONFIG_BLK_DEV_IDEDMA_ICS if (ec->dma != NO_DMA) { if (request_dma(ec->dma, hwif->name)) goto no_dma; if (hwif) { hwif->config_data = slot_port; hwif->select_data = sel; hwif->hw.dma = ec->dma; hwif->hw.priv = (void *) (port + ICS_ARCIN_V6_INTRSTAT_1); hwif->channel = 0; icside_setup_dma(hwif, autodma); } if (mate) { mate->config_data = slot_port; mate->select_data = sel | 1; mate->hw.dma = ec->dma; mate->hw.priv = (void *) (port + ICS_ARCIN_V6_INTRSTAT_2); mate->channel = 1; icside_setup_dma(mate, autodma); } }no_dma:#endif return hwif || mate ? 0 : -1;}int __init icside_init(void){ int autodma = 0;#ifdef CONFIG_IDEDMA_ICS_AUTO autodma = 1;#endif ecard_startfind (); do { struct expansion_card *ec; int result; ec = ecard_find(0, icside_cids); if (ec == NULL) break; ecard_claim(ec); switch (icside_identifyif(ec)) { case ics_if_arcin_v5: result = icside_register_v5(ec, autodma); break; case ics_if_arcin_v6: result = icside_register_v6(ec, autodma); break; default: result = -1; break; } if (result) ecard_release(ec); } while (1); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -