示例#1
0
文件: ide-cs.c 项目: sarnobat/knoppix
static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq)
{
    hw_regs_t hw;
    ide_init_hwif_ports(&hw, io, ctl, NULL);
    hw.irq = irq;
    hw.chipset = ide_pci;
    return ide_register_hw(&hw, NULL);
}
示例#2
0
int idecs_register (int arg1, int arg2, int irq)
{
        hw_regs_t hw;
        ide_init_hwif_ports(&hw, (ide_ioreg_t) arg1, (ide_ioreg_t) arg2, NULL);
        hw.irq = irq;
        hw.chipset = ide_pci; /* this enables IRQ sharing w/ PCI irqs */
        return ide_register_hw(&hw, NULL);
}
示例#3
0
static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq)
{
    hw_regs_t hw;
    memset(&hw, 0, sizeof(hw));
    ide_init_hwif_ports(&hw, io, ctl, NULL);
    hw.irq = irq;
    hw.chipset = ide_pci;
    return ide_register_hw_with_fixup(&hw, NULL, ide_undecoded_slave);
}
示例#4
0
文件: ide-cs.c 项目: cilynx/dd-wrt
static int idecs_register(unsigned long io, unsigned long ctl, unsigned long irq, struct pcmcia_device *handle)
{
    hw_regs_t hw;
    memset(&hw, 0, sizeof(hw));
    ide_init_hwif_ports(&hw, io, ctl, NULL);
    hw.irq = irq;
    hw.chipset = ide_pci;
    hw.dev = &handle->dev;
    return ide_register_hw_with_fixup(&hw, 0, NULL, ide_undecoded_slave);
}
示例#5
0
static int __devinit
delkin_cb_probe (struct pci_dev *dev, const struct pci_device_id *id)
{
	unsigned long base;
	hw_regs_t hw;
	ide_hwif_t *hwif = NULL;
	ide_drive_t *drive;
	int i, rc;

	rc = pci_enable_device(dev);
	if (rc) {
		printk(KERN_ERR "delkin_cb: pci_enable_device failed (%d)\n", rc);
		return rc;
	}
	rc = pci_request_regions(dev, "delkin_cb");
	if (rc) {
		printk(KERN_ERR "delkin_cb: pci_request_regions failed (%d)\n", rc);
		pci_disable_device(dev);
		return rc;
	}
	base = pci_resource_start(dev, 0);
	outb(0x02, base + 0x1e);	/* set nIEN to block interrupts */
	inb(base + 0x17);		/* read status to clear interrupts */
	for (i = 0; i < sizeof(setup); ++i) {
		if (setup[i])
			outb(setup[i], base + i);
	}
	pci_release_regions(dev);	/* IDE layer handles regions itself */

	memset(&hw, 0, sizeof(hw));
	ide_init_hwif_ports(&hw, (ide_ioreg_t)(base + 0x10),
				 (ide_ioreg_t)(base + 0x1e), NULL);
	hw.irq = dev->irq;
	hw.chipset = ide_pci;		/* this enables IRQ sharing */

	rc = ide_register_hw(&hw, &hwif);
	if (rc < 0)	/* ide_register_hw likes to be invoked twice (buggy) */
		rc = ide_register_hw(&hw, &hwif);
	if (rc < 0) {
		printk(KERN_ERR "delkin_cb: ide_register_hw failed (%d)\n", rc);
		pci_disable_device(dev);
		return -ENODEV;
	}
	MOD_INC_USE_COUNT;
	pci_set_drvdata(dev, hwif);
	hwif->pci_dev = dev;
	drive = &hwif->drives[0];
	if (drive->present) {
		drive->id->csfo = 0; /* workaround for idedisk_open bug */
		drive->io_32bit = 1;
		drive->unmask   = 1;
	}
	return 0;
}
示例#6
0
static void init_hwif_default(ide_hwif_t *hwif, unsigned int index)
{
	hw_regs_t hw;

	memset(&hw, 0, sizeof(hw_regs_t));

	ide_init_hwif_ports(&hw, ide_default_io_base(index), 0, &hwif->irq);

	memcpy(&hwif->hw, &hw, sizeof(hw));
	memcpy(hwif->io_ports, hw.io_ports, sizeof(hw.io_ports));

	hwif->noprobe = !hwif->io_ports[IDE_DATA_OFFSET];
#ifdef CONFIG_BLK_DEV_HD
	if (hwif->io_ports[IDE_DATA_OFFSET] == HD_DATA)
		hwif->noprobe = 1;	/* may be overridden by ide_setup() */
#endif
}
示例#7
0
/*
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;
}
示例#8
0
/*
 * ide_setup() gets called VERY EARLY during initialization,
 * to handle kernel "command line" strings beginning with "hdx=" or "ide".
 *
 * Remember to update Documentation/ide.txt if you change something here.
 */
static int __init ide_setup(char *s)
{
	int i, vals[3];
	ide_hwif_t *hwif;
	ide_drive_t *drive;
	unsigned int hw, unit;
	const char max_drive = 'a' + ((MAX_HWIFS * MAX_DRIVES) - 1);
	const char max_hwif  = '0' + (MAX_HWIFS - 1);

	
	if (strncmp(s,"hd",2) == 0 && s[2] == '=')	/* hd= is for hd.c   */
		return 0;				/* driver and not us */

	if (strncmp(s,"ide",3) && strncmp(s,"idebus",6) && strncmp(s,"hd",2))
		return 0;

	printk(KERN_INFO "ide_setup: %s", s);
	init_ide_data ();

#ifdef CONFIG_BLK_DEV_IDEDOUBLER
	if (!strcmp(s, "ide=doubler")) {
		extern int ide_doubler;

		printk(" : Enabled support for IDE doublers\n");
		ide_doubler = 1;
		return 1;
	}
#endif /* CONFIG_BLK_DEV_IDEDOUBLER */

	if (!strcmp(s, "ide=nodma")) {
		printk(" : Prevented DMA\n");
		noautodma = 1;
		return 1;
	}

#ifdef CONFIG_IDEPCI_PCIBUS_ORDER
	if (!strcmp(s, "ide=reverse")) {
		ide_scan_direction = 1;
		printk(" : Enabled support for IDE inverse scan order.\n");
		return 1;
	}
#endif

#ifdef CONFIG_BLK_DEV_IDEACPI
	if (!strcmp(s, "ide=noacpi")) {
		//printk(" : Disable IDE ACPI support.\n");
		ide_noacpi = 1;
		return 1;
	}
	if (!strcmp(s, "ide=acpigtf")) {
		//printk(" : Enable IDE ACPI _GTF support.\n");
		ide_noacpitfs = 0;
		return 1;
	}
	if (!strcmp(s, "ide=acpionboot")) {
		//printk(" : Call IDE ACPI methods on boot.\n");
		ide_noacpionboot = 0;
		return 1;
	}
#endif /* CONFIG_BLK_DEV_IDEACPI */

	/*
	 * Look for drive options:  "hdx="
	 */
	if (s[0] == 'h' && s[1] == 'd' && s[2] >= 'a' && s[2] <= max_drive) {
		const char *hd_words[] = {
			"none", "noprobe", "nowerr", "cdrom", "minus5",
			"autotune", "noautotune", "minus8", "swapdata", "bswap",
			"noflush", "remap", "remap63", "scsi", NULL };
		unit = s[2] - 'a';
		hw   = unit / MAX_DRIVES;
		unit = unit % MAX_DRIVES;
		hwif = &ide_hwifs[hw];
		drive = &hwif->drives[unit];
		if (strncmp(s + 4, "ide-", 4) == 0) {
			strlcpy(drive->driver_req, s + 4, sizeof(drive->driver_req));
			goto done;
		}
		switch (match_parm(&s[3], hd_words, vals, 3)) {
			case -1: /* "none" */
			case -2: /* "noprobe" */
				drive->noprobe = 1;
				goto done;
			case -3: /* "nowerr" */
				drive->bad_wstat = BAD_R_STAT;
				hwif->noprobe = 0;
				goto done;
			case -4: /* "cdrom" */
				drive->present = 1;
				drive->media = ide_cdrom;
				/* an ATAPI device ignores DRDY */
				drive->ready_stat = 0;
				hwif->noprobe = 0;
				goto done;
			case -6: /* "autotune" */
				drive->autotune = IDE_TUNE_AUTO;
				goto obsolete_option;
			case -7: /* "noautotune" */
				drive->autotune = IDE_TUNE_NOAUTO;
				goto obsolete_option;
			case -9: /* "swapdata" */
			case -10: /* "bswap" */
				drive->bswap = 1;
				goto done;
			case -11: /* noflush */
				drive->noflush = 1;
				goto done;
			case -12: /* "remap" */
				drive->remap_0_to_1 = 1;
				goto done;
			case -13: /* "remap63" */
				drive->sect0 = 63;
				goto done;
			case -14: /* "scsi" */
				drive->scsi = 1;
				goto done;
			case 3: /* cyl,head,sect */
				drive->media	= ide_disk;
				drive->ready_stat = READY_STAT;
				drive->cyl	= drive->bios_cyl  = vals[0];
				drive->head	= drive->bios_head = vals[1];
				drive->sect	= drive->bios_sect = vals[2];
				drive->present	= 1;
				drive->forced_geom = 1;
				hwif->noprobe = 0;
				goto done;
			default:
				goto bad_option;
		}
	}

	if (s[0] != 'i' || s[1] != 'd' || s[2] != 'e')
		goto bad_option;
	/*
	 * Look for bus speed option:  "idebus="
	 */
	if (s[3] == 'b' && s[4] == 'u' && s[5] == 's') {
		if (match_parm(&s[6], NULL, vals, 1) != 1)
			goto bad_option;
		if (vals[0] >= 20 && vals[0] <= 66) {
			idebus_parameter = vals[0];
		} else
			printk(" -- BAD BUS SPEED! Expected value from 20 to 66");
		goto done;
	}
	/*
	 * Look for interface options:  "idex="
	 */
	if (s[3] >= '0' && s[3] <= max_hwif) {
		/*
		 * Be VERY CAREFUL changing this: note hardcoded indexes below
		 * (-8, -9, -10) are reserved to ease the hardcoding.
		 */
		static const char *ide_words[] = {
			"noprobe", "serialize", "minus3", "minus4",
			"reset", "dma", "ata66", "minus8", "minus9",
			"minus10", "four", "qd65xx", "ht6560b", "cmd640_vlb",
			"dtc2278", "umc8672", "ali14xx", NULL };
		hw = s[3] - '0';
		hwif = &ide_hwifs[hw];
		i = match_parm(&s[4], ide_words, vals, 3);

		/*
		 * Cryptic check to ensure chipset not already set for hwif.
		 * Note: we can't depend on hwif->chipset here.
		 */
		if ((i >= -18 && i <= -11) || (i > 0 && i <= 3)) {
			/* chipset already specified */
			if (is_chipset_set[hw])
				goto bad_option;
			if (i > -18 && i <= -11) {
				/* these drivers are for "ide0=" only */
				if (hw != 0)
					goto bad_hwif;
				/* chipset already specified for 2nd port */
				if (is_chipset_set[hw+1])
					goto bad_option;
			}
			is_chipset_set[hw] = 1;
			printk("\n");
		}

		switch (i) {
#ifdef CONFIG_BLK_DEV_ALI14XX
			case -17: /* "ali14xx" */
				probe_ali14xx = 1;
				goto done;
#endif
#ifdef CONFIG_BLK_DEV_UMC8672
			case -16: /* "umc8672" */
				probe_umc8672 = 1;
				goto done;
#endif
#ifdef CONFIG_BLK_DEV_DTC2278
			case -15: /* "dtc2278" */
				probe_dtc2278 = 1;
				goto done;
#endif
#ifdef CONFIG_BLK_DEV_CMD640
			case -14: /* "cmd640_vlb" */
			{
				extern int cmd640_vlb; /* flag for cmd640.c */
				cmd640_vlb = 1;
				goto done;
			}
#endif
#ifdef CONFIG_BLK_DEV_HT6560B
			case -13: /* "ht6560b" */
				probe_ht6560b = 1;
				goto done;
#endif
#ifdef CONFIG_BLK_DEV_QD65XX
			case -12: /* "qd65xx" */
				probe_qd65xx = 1;
				goto done;
#endif
#ifdef CONFIG_BLK_DEV_4DRIVES
			case -11: /* "four" drives on one set of ports */
			{
				ide_hwif_t *mate = &ide_hwifs[hw^1];
				mate->drives[0].select.all ^= 0x20;
				mate->drives[1].select.all ^= 0x20;
				hwif->chipset = mate->chipset = ide_4drives;
				mate->irq = hwif->irq;
				memcpy(mate->io_ports, hwif->io_ports, sizeof(hwif->io_ports));
				hwif->mate = mate;
				mate->mate = hwif;
				hwif->serialized = mate->serialized = 1;
				goto obsolete_option;
			}
#endif /* CONFIG_BLK_DEV_4DRIVES */
			case -10: /* minus10 */
			case -9: /* minus9 */
			case -8: /* minus8 */
			case -4:
			case -3:
				goto bad_option;
			case -7: /* ata66 */
#ifdef CONFIG_BLK_DEV_IDEPCI
				hwif->udma_four = 1;
				goto obsolete_option;
#else
				goto bad_hwif;
#endif
			case -6: /* dma */
				hwif->autodma = 1;
				goto obsolete_option;
			case -5: /* "reset" */
				hwif->reset = 1;
				goto obsolete_option;
			case -2: /* "serialize" */
				hwif->mate = &ide_hwifs[hw^1];
				hwif->mate->mate = hwif;
				hwif->serialized = hwif->mate->serialized = 1;
				goto obsolete_option;

			case -1: /* "noprobe" */
				hwif->noprobe = 1;
				goto done;

			case 1:	/* base */
				vals[1] = vals[0] + 0x206; /* default ctl */
			case 2: /* base,ctl */
				vals[2] = 0;	/* default irq = probe for it */
			case 3: /* base,ctl,irq */
				hwif->hw.irq = vals[2];
				ide_init_hwif_ports(&hwif->hw, (unsigned long) vals[0], (unsigned long) vals[1], &hwif->irq);
				memcpy(hwif->io_ports, hwif->hw.io_ports, sizeof(hwif->io_ports));
				hwif->irq      = vals[2];
				hwif->noprobe  = 0;
				hwif->chipset  = ide_forced;
				goto obsolete_option;

			case 0: goto bad_option;
			default:
				printk(" -- SUPPORT NOT CONFIGURED IN THIS KERNEL\n");
				return 1;
		}
	}
bad_option:
	printk(" -- BAD OPTION\n");
	return 1;
obsolete_option:
	printk(" -- OBSOLETE OPTION, WILL BE REMOVED SOON!\n");
	return 1;
bad_hwif:
	printk("-- NOT SUPPORTED ON ide%d", hw);
done:
	printk("\n");
	return 1;
}
示例#9
0
int generic_ide_ioctl(ide_drive_t *drive, struct file *file, struct block_device *bdev,
			unsigned int cmd, unsigned long arg)
{
	unsigned long flags;
	ide_driver_t *drv;
	void __user *p = (void __user *)arg;
	int err = 0, (*setfunc)(ide_drive_t *, int);
	u8 *val;

	switch (cmd) {
	case HDIO_GET_32BIT:	    val = &drive->io_32bit;	 goto read_val;
	case HDIO_GET_KEEPSETTINGS: val = &drive->keep_settings; goto read_val;
	case HDIO_GET_UNMASKINTR:   val = &drive->unmask;	 goto read_val;
	case HDIO_GET_DMA:	    val = &drive->using_dma;	 goto read_val;
	case HDIO_SET_32BIT:	    setfunc = set_io_32bit;	 goto set_val;
	case HDIO_SET_KEEPSETTINGS: setfunc = set_ksettings;	 goto set_val;
	case HDIO_SET_PIO_MODE:	    setfunc = set_pio_mode;	 goto set_val;
	case HDIO_SET_UNMASKINTR:   setfunc = set_unmaskirq;	 goto set_val;
	case HDIO_SET_DMA:	    setfunc = set_using_dma;	 goto set_val;
	}

	switch (cmd) {
		case HDIO_OBSOLETE_IDENTITY:
		case HDIO_GET_IDENTITY:
			if (bdev != bdev->bd_contains)
				return -EINVAL;
			if (drive->id_read == 0)
				return -ENOMSG;
			if (copy_to_user(p, drive->id, (cmd == HDIO_GET_IDENTITY) ? sizeof(*drive->id) : 142))
				return -EFAULT;
			return 0;

		case HDIO_GET_NICE:
			return put_user(drive->dsc_overlap	<<	IDE_NICE_DSC_OVERLAP	|
					drive->atapi_overlap	<<	IDE_NICE_ATAPI_OVERLAP	|
					drive->nice0		<< 	IDE_NICE_0		|
					drive->nice1		<<	IDE_NICE_1		|
					drive->nice2		<<	IDE_NICE_2,
					(long __user *) arg);

#ifdef CONFIG_IDE_TASK_IOCTL
		case HDIO_DRIVE_TASKFILE:
		        if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
				return -EACCES;
			switch(drive->media) {
				case ide_disk:
					return ide_taskfile_ioctl(drive, cmd, arg);
				default:
					return -ENOMSG;
			}
#endif /* CONFIG_IDE_TASK_IOCTL */

		case HDIO_DRIVE_CMD:
			if (!capable(CAP_SYS_RAWIO))
				return -EACCES;
			return ide_cmd_ioctl(drive, cmd, arg);

		case HDIO_DRIVE_TASK:
			if (!capable(CAP_SYS_RAWIO))
				return -EACCES;
			return ide_task_ioctl(drive, cmd, arg);

		case HDIO_SCAN_HWIF:
		{
			hw_regs_t hw;
			int args[3];
			if (!capable(CAP_SYS_RAWIO)) return -EACCES;
			if (copy_from_user(args, p, 3 * sizeof(int)))
				return -EFAULT;
			memset(&hw, 0, sizeof(hw));
			ide_init_hwif_ports(&hw, (unsigned long) args[0],
					    (unsigned long) args[1], NULL);
			hw.irq = args[2];
			if (ide_register_hw(&hw, 0, NULL) == -1)
				return -EIO;
			return 0;
		}
	        case HDIO_UNREGISTER_HWIF:
			if (!capable(CAP_SYS_RAWIO)) return -EACCES;
			/* (arg > MAX_HWIFS) checked in function */
			ide_unregister(arg);
			return 0;
		case HDIO_SET_NICE:
			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
			if (arg != (arg & ((1 << IDE_NICE_DSC_OVERLAP) | (1 << IDE_NICE_1))))
				return -EPERM;
			drive->dsc_overlap = (arg >> IDE_NICE_DSC_OVERLAP) & 1;
			drv = *(ide_driver_t **)bdev->bd_disk->private_data;
			if (drive->dsc_overlap && !drv->supports_dsc_overlap) {
				drive->dsc_overlap = 0;
				return -EPERM;
			}
			drive->nice1 = (arg >> IDE_NICE_1) & 1;
			return 0;
		case HDIO_DRIVE_RESET:
		{
			unsigned long flags;
			if (!capable(CAP_SYS_ADMIN)) return -EACCES;
			
			/*
			 *	Abort the current command on the
			 *	group if there is one, taking
			 *	care not to allow anything else
			 *	to be queued and to die on the
			 *	spot if we miss one somehow
			 */

			spin_lock_irqsave(&ide_lock, flags);

			if (HWGROUP(drive)->resetting) {
				spin_unlock_irqrestore(&ide_lock, flags);
				return -EBUSY;
			}

			ide_abort(drive, "drive reset");

			BUG_ON(HWGROUP(drive)->handler);
				
			/* Ensure nothing gets queued after we
			   drop the lock. Reset will clear the busy */
		   
			HWGROUP(drive)->busy = 1;
			spin_unlock_irqrestore(&ide_lock, flags);
			(void) ide_do_reset(drive);

			return 0;
		}

		case CDROMEJECT:
		case CDROMCLOSETRAY:
			return scsi_cmd_ioctl(file, bdev->bd_disk, cmd, p);

		case HDIO_GET_BUSSTATE:
			if (!capable(CAP_SYS_ADMIN))
				return -EACCES;
			if (put_user(HWIF(drive)->bus_state, (long __user *)arg))
				return -EFAULT;
			return 0;

		case HDIO_SET_BUSSTATE:
			if (!capable(CAP_SYS_ADMIN))
				return -EACCES;
			if (HWIF(drive)->busproc)
				return HWIF(drive)->busproc(drive, (int)arg);
			return -EOPNOTSUPP;
		default:
			return -EINVAL;
	}

read_val:
	down(&ide_setting_sem);
	spin_lock_irqsave(&ide_lock, flags);
	err = *val;
	spin_unlock_irqrestore(&ide_lock, flags);
	up(&ide_setting_sem);
	return err >= 0 ? put_user(err, (long __user *)arg) : err;

set_val:
	if (bdev != bdev->bd_contains)
		err = -EINVAL;
	else {
		if (!capable(CAP_SYS_ADMIN))
			err = -EACCES;
		else {
			down(&ide_setting_sem);
			err = setfunc(drive, arg);
			up(&ide_setting_sem);
		}
	}
	return err;
}