📄 ide-iops.c
字号:
{ u8 *p = s, *end = &s[bytecount & ~1]; /* bytecount must be even */ if (byteswap) { /* convert from big-endian to host byte order */ for (p = end ; p != s;) { unsigned short *pp = (unsigned short *) (p -= 2); *pp = ntohs(*pp); } } /* strip leading blanks */ while (s != end && *s == ' ') ++s; /* compress internal blanks and strip trailing blanks */ while (s != end && *s) { if (*s++ != ' ' || (s != end && *s && *s != ' ')) *p++ = *(s-1); } /* wipe out trailing garbage */ while (p != end) *p++ = '\0';}EXPORT_SYMBOL(ide_fixstring);/* * Needed for PCI irq sharing */int drive_is_ready (ide_drive_t *drive){ ide_hwif_t *hwif = HWIF(drive); u8 stat = 0; if (drive->waiting_for_dma) return hwif->ide_dma_test_irq(drive);#if 0 /* need to guarantee 400ns since last command was issued */ udelay(1);#endif#ifdef CONFIG_IDEPCI_SHARE_IRQ /* * We do a passive status test under shared PCI interrupts on * cards that truly share the ATA side interrupt, but may also share * an interrupt with another pci card/device. We make no assumptions * about possible isa-pnp and pci-pnp issues yet. */ if (IDE_CONTROL_REG) stat = hwif->INB(IDE_ALTSTATUS_REG); else#endif /* CONFIG_IDEPCI_SHARE_IRQ */ /* Note: this may clear a pending IRQ!! */ stat = hwif->INB(IDE_STATUS_REG); if (stat & BUSY_STAT) /* drive busy: definitely not interrupting */ return 0; /* drive ready: *might* be interrupting */ return 1;}EXPORT_SYMBOL(drive_is_ready);/* * This routine busy-waits for the drive status to be not "busy". * It then checks the status for all of the "good" bits and none * of the "bad" bits, and if all is okay it returns 0. All other * cases return error -- caller may then invoke ide_error(). * * This routine should get fixed to not hog the cpu during extra long waits.. * That could be done by busy-waiting for the first jiffy or two, and then * setting a timer to wake up at half second intervals thereafter, * until timeout is achieved, before timing out. */static int __ide_wait_stat(ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout, u8 *rstat){ ide_hwif_t *hwif = drive->hwif; unsigned long flags; int i; u8 stat; udelay(1); /* spec allows drive 400ns to assert "BUSY" */ if ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { local_irq_set(flags); timeout += jiffies; while ((stat = hwif->INB(IDE_STATUS_REG)) & BUSY_STAT) { if (time_after(jiffies, timeout)) { /* * One last read after the timeout in case * heavy interrupt load made us not make any * progress during the timeout.. */ stat = hwif->INB(IDE_STATUS_REG); if (!(stat & BUSY_STAT)) break; local_irq_restore(flags); *rstat = stat; return -EBUSY; } } local_irq_restore(flags); } /* * Allow status to settle, then read it again. * A few rare drives vastly violate the 400ns spec here, * so we'll wait up to 10usec for a "good" status * rather than expensively fail things immediately. * This fix courtesy of Matthew Faupel & Niccolo Rigacci. */ for (i = 0; i < 10; i++) { udelay(1); if (OK_STAT((stat = hwif->INB(IDE_STATUS_REG)), good, bad)) { *rstat = stat; return 0; } } *rstat = stat; return -EFAULT;}/* * In case of error returns error value after doing "*startstop = ide_error()". * The caller should return the updated value of "startstop" in this case, * "startstop" is unchanged when the function returns 0. */int ide_wait_stat(ide_startstop_t *startstop, ide_drive_t *drive, u8 good, u8 bad, unsigned long timeout){ int err; u8 stat; /* bail early if we've exceeded max_failures */ if (drive->max_failures && (drive->failures > drive->max_failures)) { *startstop = ide_stopped; return 1; } err = __ide_wait_stat(drive, good, bad, timeout, &stat); if (err) { char *s = (err == -EBUSY) ? "status timeout" : "status error"; *startstop = ide_error(drive, s, stat); } return err;}EXPORT_SYMBOL(ide_wait_stat);/** * ide_in_drive_list - look for drive in black/white list * @id: drive identifier * @drive_table: list to inspect * * Look for a drive in the blacklist and the whitelist tables * Returns 1 if the drive is found in the table. */int ide_in_drive_list(struct hd_driveid *id, const struct drive_list_entry *drive_table){ for ( ; drive_table->id_model; drive_table++) if ((!strcmp(drive_table->id_model, id->model)) && (!drive_table->id_firmware || strstr(id->fw_rev, drive_table->id_firmware))) return 1; return 0;}EXPORT_SYMBOL_GPL(ide_in_drive_list);/* * Early UDMA66 devices don't set bit14 to 1, only bit13 is valid. * We list them here and depend on the device side cable detection for them. * * Some optical devices with the buggy firmwares have the same problem. */static const struct drive_list_entry ivb_list[] = { { "QUANTUM FIREBALLlct10 05" , "A03.0900" }, { "TSSTcorp CDDVDW SH-S202J" , "SB00" }, { "TSSTcorp CDDVDW SH-S202J" , "SB01" }, { "TSSTcorp CDDVDW SH-S202N" , "SB00" }, { "TSSTcorp CDDVDW SH-S202N" , "SB01" }, { NULL , NULL }};/* * All hosts that use the 80c ribbon must use! * The name is derived from upper byte of word 93 and the 80c ribbon. */u8 eighty_ninty_three (ide_drive_t *drive){ ide_hwif_t *hwif = drive->hwif; struct hd_driveid *id = drive->id; int ivb = ide_in_drive_list(id, ivb_list); if (hwif->cbl == ATA_CBL_PATA40_SHORT) return 1; if (ivb) printk(KERN_DEBUG "%s: skipping word 93 validity check\n", drive->name); if (ide_dev_is_sata(id) && !ivb) return 1; if (hwif->cbl != ATA_CBL_PATA80 && !ivb) goto no_80w; /* * FIXME: * - force bit13 (80c cable present) check also for !ivb devices * (unless the slave device is pre-ATA3) */ if ((id->hw_config & 0x4000) || (ivb && (id->hw_config & 0x2000))) return 1;no_80w: if (drive->udma33_warned == 1) return 0; printk(KERN_WARNING "%s: %s side 80-wire cable detection failed, " "limiting max speed to UDMA33\n", drive->name, hwif->cbl == ATA_CBL_PATA80 ? "drive" : "host"); drive->udma33_warned = 1; return 0;}int ide_ata66_check (ide_drive_t *drive, ide_task_t *args){ if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) && (args->tfRegister[IDE_SECTOR_OFFSET] > XFER_UDMA_2) && (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER)) { if (eighty_ninty_three(drive) == 0) { printk(KERN_WARNING "%s: UDMA speeds >UDMA33 cannot " "be set\n", drive->name); return 1; } } return 0;}/* * Backside of HDIO_DRIVE_CMD call of SETFEATURES_XFER. * 1 : Safe to update drive->id DMA registers. * 0 : OOPs not allowed. */int set_transfer (ide_drive_t *drive, ide_task_t *args){ if ((args->tfRegister[IDE_COMMAND_OFFSET] == WIN_SETFEATURES) && (args->tfRegister[IDE_SECTOR_OFFSET] >= XFER_SW_DMA_0) && (args->tfRegister[IDE_FEATURE_OFFSET] == SETFEATURES_XFER) && (drive->id->dma_ultra || drive->id->dma_mword || drive->id->dma_1word)) return 1; return 0;}#ifdef CONFIG_BLK_DEV_IDEDMAstatic u8 ide_auto_reduce_xfer (ide_drive_t *drive){ if (!drive->crc_count) return drive->current_speed; drive->crc_count = 0; switch(drive->current_speed) { case XFER_UDMA_7: return XFER_UDMA_6; case XFER_UDMA_6: return XFER_UDMA_5; case XFER_UDMA_5: return XFER_UDMA_4; case XFER_UDMA_4: return XFER_UDMA_3; case XFER_UDMA_3: return XFER_UDMA_2; case XFER_UDMA_2: return XFER_UDMA_1; case XFER_UDMA_1: return XFER_UDMA_0; /* * OOPS we do not goto non Ultra DMA modes * without iCRC's available we force * the system to PIO and make the user * invoke the ATA-1 ATA-2 DMA modes. */ case XFER_UDMA_0: default: return XFER_PIO_4; }}#endif /* CONFIG_BLK_DEV_IDEDMA */int ide_driveid_update(ide_drive_t *drive){ ide_hwif_t *hwif = drive->hwif; struct hd_driveid *id; unsigned long timeout, flags; /* * Re-read drive->id for possible DMA mode * change (copied from ide-probe.c) */ SELECT_MASK(drive, 1); if (IDE_CONTROL_REG) hwif->OUTB(drive->ctl,IDE_CONTROL_REG); msleep(50); hwif->OUTB(WIN_IDENTIFY, IDE_COMMAND_REG); timeout = jiffies + WAIT_WORSTCASE; do { if (time_after(jiffies, timeout)) { SELECT_MASK(drive, 0); return 0; /* drive timed-out */ } msleep(50); /* give drive a breather */ } while (hwif->INB(IDE_ALTSTATUS_REG) & BUSY_STAT); msleep(50); /* wait for IRQ and DRQ_STAT */ if (!OK_STAT(hwif->INB(IDE_STATUS_REG),DRQ_STAT,BAD_R_STAT)) { SELECT_MASK(drive, 0); printk("%s: CHECK for good STATUS\n", drive->name); return 0; } local_irq_save(flags); SELECT_MASK(drive, 0); id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC); if (!id) { local_irq_restore(flags); return 0; } ata_input_data(drive, id, SECTOR_WORDS); (void) hwif->INB(IDE_STATUS_REG); /* clear drive IRQ */ local_irq_enable(); local_irq_restore(flags); ide_fix_driveid(id); if (id) { drive->id->dma_ultra = id->dma_ultra; drive->id->dma_mword = id->dma_mword; drive->id->dma_1word = id->dma_1word; /* anything more ? */ kfree(id); if (drive->using_dma && ide_id_dma_bug(drive)) ide_dma_off(drive); } return 1;}int ide_config_drive_speed(ide_drive_t *drive, u8 speed){ ide_hwif_t *hwif = drive->hwif; int error = 0; u8 stat;// while (HWGROUP(drive)->busy)// msleep(50);#ifdef CONFIG_BLK_DEV_IDEDMA if (hwif->ide_dma_on) /* check if host supports DMA */ hwif->dma_host_off(drive);#endif /* Skip setting PIO flow-control modes on pre-EIDE drives */ if ((speed & 0xf8) == XFER_PIO_0 && !(drive->id->capability & 0x08)) goto skip; /* * Don't use ide_wait_cmd here - it will * attempt to set_geometry and recalibrate, * but for some reason these don't work at * this point (lost interrupt). */ /* * Select the drive, and issue the SETFEATURES command */ disable_irq_nosync(hwif->irq); /* * FIXME: we race against the running IRQ here if * this is called from non IRQ context. If we use * disable_irq() we hang on the error path. Work * is needed. */ udelay(1); SELECT_DRIVE(drive); SELECT_MASK(drive, 0); udelay(1); if (IDE_CONTROL_REG) hwif->OUTB(drive->ctl | 2, IDE_CONTROL_REG); hwif->OUTB(speed, IDE_NSECTOR_REG); hwif->OUTB(SETFEATURES_XFER, IDE_FEATURE_REG); hwif->OUTBSYNC(drive, WIN_SETFEATURES, IDE_COMMAND_REG); if ((IDE_CONTROL_REG) && (drive->quirk_list == 2)) hwif->OUTB(drive->ctl, IDE_CONTROL_REG); error = __ide_wait_stat(drive, drive->ready_stat, BUSY_STAT|DRQ_STAT|ERR_STAT, WAIT_CMD, &stat); SELECT_MASK(drive, 0); enable_irq(hwif->irq); if (error) { (void) ide_dump_status(drive, "set_drive_speed_status", stat); return error; } drive->id->dma_ultra &= ~0xFF00;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -