/* * Input data function for emxx_ide */ static void emxx_ide_input_data(ide_drive_t *drive, struct request *rq, void *buf, unsigned int len) { if (emxx_cfi_connect) { emxx_cfi_push++; ide_input_data(drive, rq, buf, len); emxx_cfi_push--; } }
/* * Update the */ int ide_driveid_update (ide_drive_t *drive) { /* * Re-read drive->id for possible DMA mode * change (copied from ide-probe.c) */ struct hd_driveid *id; unsigned long timeout, flags; SELECT_MASK(HWIF(drive), drive, 1); if (IDE_CONTROL_REG) OUT_BYTE(drive->ctl,IDE_CONTROL_REG); ide_delay_50ms(); OUT_BYTE(WIN_IDENTIFY, IDE_COMMAND_REG); timeout = jiffies + WAIT_WORSTCASE; do { if (0 < (signed long)(jiffies - timeout)) { SELECT_MASK(HWIF(drive), drive, 0); return 0; /* drive timed-out */ } ide_delay_50ms(); /* give drive a breather */ } while (IN_BYTE(IDE_ALTSTATUS_REG) & BUSY_STAT); ide_delay_50ms(); /* wait for IRQ and DRQ_STAT */ if (!OK_STAT(GET_STAT(),DRQ_STAT,BAD_R_STAT)) { SELECT_MASK(HWIF(drive), drive, 0); printk("%s: CHECK for good STATUS\n", drive->name); return 0; } __save_flags(flags); /* local CPU only */ __cli(); /* local CPU only; some systems need this */ SELECT_MASK(HWIF(drive), drive, 0); id = kmalloc(SECTOR_WORDS*4, GFP_ATOMIC); if (!id) { __restore_flags(flags); /* local CPU only */ return 0; } ide_input_data(drive, id, SECTOR_WORDS); (void) GET_STAT(); /* clear drive IRQ */ ide__sti(); /* local CPU only */ __restore_flags(flags); /* local CPU only */ 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); } return 1; }
/* * promise_read_intr() is the handler for disk read/multread interrupts */ static ide_startstop_t promise_read_intr (ide_drive_t *drive) { byte stat; int i; unsigned int sectors_left, sectors_avail, nsect; struct request *rq; if (!OK_STAT(stat=GET_STAT(),DATA_READY,BAD_R_STAT)) { return ide_error(drive, "promise_read_intr", stat); } read_again: do { sectors_left = IN_BYTE(IDE_NSECTOR_REG); IN_BYTE(IDE_SECTOR_REG); } while (IN_BYTE(IDE_NSECTOR_REG) != sectors_left); rq = HWGROUP(drive)->rq; sectors_avail = rq->nr_sectors - sectors_left; read_next: rq = HWGROUP(drive)->rq; if ((nsect = rq->current_nr_sectors) > sectors_avail) nsect = sectors_avail; sectors_avail -= nsect; ide_input_data(drive, rq->buffer, nsect * SECTOR_WORDS); #ifdef DEBUG printk("%s: promise_read: sectors(%ld-%ld), buffer=0x%08lx, " "remaining=%ld\n", drive->name, rq->sector, rq->sector+nsect-1, (unsigned long) rq->buffer+(nsect<<9), rq->nr_sectors-nsect); #endif rq->sector += nsect; rq->buffer += nsect<<9; rq->errors = 0; i = (rq->nr_sectors -= nsect); if ((rq->current_nr_sectors -= nsect) <= 0) ide_end_request(1, HWGROUP(drive)); if (i > 0) { if (sectors_avail) goto read_next; stat = GET_STAT(); if(stat & DRQ_STAT) goto read_again; if(stat & BUSY_STAT) { ide_set_handler (drive, &promise_read_intr, WAIT_CMD, NULL); return ide_started; } printk("Ah! promise read intr: sectors left !DRQ !BUSY\n"); return ide_error(drive, "promise read intr", stat); } return ide_stopped; }
/* init_pdc4030: Test for presence of a Promise caching controller card. Returns: 0 if no Promise card present at this io_base 1 if Promise card found */ int init_pdc4030 (void) { ide_startstop_t startstop; ide_hwif_t *hwif = hwif_required; ide_drive_t *drive; ide_hwif_t *second_hwif; struct dc_ident ident; int i; if (!hwif) return 0; drive = &hwif->drives[0]; second_hwif = &ide_hwifs[hwif->index+1]; if(hwif->chipset == ide_pdc4030) /* we've already been found ! */ return 1; if(IN_BYTE(IDE_NSECTOR_REG) == 0xFF || IN_BYTE(IDE_SECTOR_REG) == 0xFF) { return 0; } OUT_BYTE(0x08,IDE_CONTROL_REG); if(pdc4030_cmd(drive,PROMISE_GET_CONFIG)) { return 0; } if(ide_wait_stat(&startstop,drive,DATA_READY,BAD_W_STAT,WAIT_DRQ)) { printk("%s: Failed Promise read config!\n",hwif->name); return 0; } ide_input_data(drive,&ident,SECTOR_WORDS); if(ident.id[1] != 'P' || ident.id[0] != 'T') { return 0; } printk("%s: Promise caching controller, ",hwif->name); switch(ident.type) { case 0x43: printk("DC4030VL-2, "); break; case 0x41: printk("DC4030VL-1, "); break; case 0x40: printk("DC4030VL, "); break; default: printk("unknown - type 0x%02x - please report!\n" ,ident.type); return 0; } printk("%dKB cache, ",(int)ident.cache_mem); switch(ident.irq) { case 0x00: hwif->irq = 14; break; case 0x01: hwif->irq = 12; break; default: hwif->irq = 15; break; } printk("on IRQ %d\n",hwif->irq); hwif->chipset = second_hwif->chipset = ide_pdc4030; hwif->mate = second_hwif; second_hwif->mate = hwif; second_hwif->channel = 1; hwif->selectproc = second_hwif->selectproc = &promise_selectproc; /* Shift the remaining interfaces down by one */ for (i=MAX_HWIFS-1 ; i > hwif->index+1 ; i--) { ide_hwif_t *h = &ide_hwifs[i]; printk("Shifting i/f %d values to i/f %d\n",i-1,i); ide_init_hwif_ports(h->io_ports, (h-1)->io_ports[IDE_DATA_OFFSET], NULL); h->io_ports[IDE_CONTROL_OFFSET] = (h-1)->io_ports[IDE_CONTROL_OFFSET]; h->noprobe = (h-1)->noprobe; } ide_init_hwif_ports(second_hwif->io_ports, hwif->io_ports[IDE_DATA_OFFSET], NULL); second_hwif->io_ports[IDE_CONTROL_OFFSET] = hwif->io_ports[IDE_CONTROL_OFFSET]; second_hwif->irq = hwif->irq; for (i=0; i<2 ; i++) { hwif->drives[i].io_32bit = 3; second_hwif->drives[i].io_32bit = 3; if(!ident.current_tm[i+2].cyl) second_hwif->drives[i].noprobe=1; } return 1; }
static inline void do_identify (ide_drive_t *drive, byte cmd) { int bswap = 1; struct hd_driveid *id; id = drive->id = kmalloc (SECTOR_WORDS*4, GFP_ATOMIC); /* called with interrupts disabled! */ ide_input_data(drive, id, SECTOR_WORDS); /* read 512 bytes of id info */ ide__sti(); /* local CPU only */ ide_fix_driveid(id); if (id->word156 == 0x4d42) { printk("%s: drive->id->word156 == 0x%04x \n", drive->name, drive->id->word156); } if (!drive->forced_lun) drive->last_lun = id->last_lun & 0x7; #if defined (CONFIG_SCSI_EATA_DMA) || defined (CONFIG_SCSI_EATA_PIO) || defined (CONFIG_SCSI_EATA) /* * EATA SCSI controllers do a hardware ATA emulation: * Ignore them if there is a driver for them available. */ if ((id->model[0] == 'P' && id->model[1] == 'M') || (id->model[0] == 'S' && id->model[1] == 'K')) { printk("%s: EATA SCSI HBA %.10s\n", drive->name, id->model); drive->present = 0; return; } #endif /* CONFIG_SCSI_EATA_DMA || CONFIG_SCSI_EATA_PIO */ /* * WIN_IDENTIFY returns little-endian info, * WIN_PIDENTIFY *usually* returns little-endian info. */ if (cmd == WIN_PIDENTIFY) { if ((id->model[0] == 'N' && id->model[1] == 'E') /* NEC */ || (id->model[0] == 'F' && id->model[1] == 'X') /* Mitsumi */ || (id->model[0] == 'P' && id->model[1] == 'i'))/* Pioneer */ bswap ^= 1; /* Vertos drives may still be weird */ } ide_fixstring (id->model, sizeof(id->model), bswap); ide_fixstring (id->fw_rev, sizeof(id->fw_rev), bswap); ide_fixstring (id->serial_no, sizeof(id->serial_no), bswap); if (strstr(id->model, "E X A B Y T E N E S T")) return; id->model[sizeof(id->model)-1] = '\0'; /* we depend on this a lot! */ printk("%s: %s, ", drive->name, id->model); drive->present = 1; /* * Check for an ATAPI device */ if (cmd == WIN_PIDENTIFY) { byte type = (id->config >> 8) & 0x1f; printk("ATAPI "); #ifdef CONFIG_BLK_DEV_PDC4030 if (HWIF(drive)->channel == 1 && HWIF(drive)->chipset == ide_pdc4030) { printk(" -- not supported on 2nd Promise port\n"); drive->present = 0; return; } #endif /* CONFIG_BLK_DEV_PDC4030 */ switch (type) { case ide_floppy: if (!strstr(id->model, "CD-ROM")) { if (!strstr(id->model, "oppy") && !strstr(id->model, "poyp") && !strstr(id->model, "ZIP")) printk("cdrom or floppy?, assuming "); if (drive->media != ide_cdrom) { printk ("FLOPPY"); break; } } type = ide_cdrom; /* Early cdrom models used zero */ case ide_cdrom: drive->removable = 1; #ifdef CONFIG_PPC /* kludge for Apple PowerBook internal zip */ if (!strstr(id->model, "CD-ROM") && strstr(id->model, "ZIP")) { printk ("FLOPPY"); type = ide_floppy; break; } #endif printk ("CDROM"); break; case ide_tape: printk ("TAPE"); break; case ide_optical: printk ("OPTICAL"); drive->removable = 1; break; default: printk("UNKNOWN (type %d)", type); break; } printk (" drive\n"); drive->media = type; return; }