⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 umem.c

📁 Linux块设备驱动源码
💻 C
📖 第 1 页 / 共 3 页
字号:
	return -EINVAL;}/*-------------------------------------------------------------------------------------                                mm_check_change-----------------------------------------------------------------------------------  Future support for removable devices*/static int mm_check_change(struct gendisk *disk){/*  struct cardinfo *dev = disk->private_data; */	return 0;}/*-------------------------------------------------------------------------------------                             mm_fops-----------------------------------------------------------------------------------*/static struct block_device_operations mm_fops = {	.owner		= THIS_MODULE,	.ioctl		= mm_ioctl,	.revalidate_disk= mm_revalidate,	.media_changed	= mm_check_change,};/*-------------------------------------------------------------------------------------                                mm_pci_probe-----------------------------------------------------------------------------------*/static int __devinit mm_pci_probe(struct pci_dev *dev, const struct pci_device_id *id){	int ret = -ENODEV;	struct cardinfo *card = &cards[num_cards];	unsigned char	mem_present;	unsigned char	batt_status;	unsigned int	saved_bar, data;	int		magic_number;	if (pci_enable_device(dev) < 0)		return -ENODEV;	pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xF8);	pci_set_master(dev);	card->dev         = dev;	card->card_number = num_cards;	card->csr_base = pci_resource_start(dev, 0);	card->csr_len  = pci_resource_len(dev, 0);#ifdef CONFIG_MM_MAP_MEMORY	card->mem_base = pci_resource_start(dev, 1);	card->mem_len  = pci_resource_len(dev, 1);#endif	printk(KERN_INFO "Micro Memory(tm) controller #%d found at %02x:%02x (PCI Mem Module (Battery Backup))\n",	       card->card_number, dev->bus->number, dev->devfn);	if (pci_set_dma_mask(dev, 0xffffffffffffffffLL) &&	    !pci_set_dma_mask(dev, 0xffffffffLL)) {		printk(KERN_WARNING "MM%d: NO suitable DMA found\n",num_cards);		return  -ENOMEM;	}	if (!request_mem_region(card->csr_base, card->csr_len, "Micro Memory")) {		printk(KERN_ERR "MM%d: Unable to request memory region\n", card->card_number);		ret = -ENOMEM;		goto failed_req_csr;	}	card->csr_remap = ioremap_nocache(card->csr_base, card->csr_len);	if (!card->csr_remap) {		printk(KERN_ERR "MM%d: Unable to remap memory region\n", card->card_number);		ret = -ENOMEM;		goto failed_remap_csr;	}	printk(KERN_INFO "MM%d: CSR 0x%08lx -> 0x%p (0x%lx)\n", card->card_number,	       card->csr_base, card->csr_remap, card->csr_len);#ifdef CONFIG_MM_MAP_MEMORY	if (!request_mem_region(card->mem_base, card->mem_len, "Micro Memory")) {		printk(KERN_ERR "MM%d: Unable to request memory region\n", card->card_number);		ret = -ENOMEM;		goto failed_req_mem;	}	if (!(card->mem_remap = ioremap(card->mem_base, cards->mem_len))) {		printk(KERN_ERR "MM%d: Unable to remap memory region\n", card->card_number);		ret = -ENOMEM;		goto failed_remap_mem;	}	printk(KERN_INFO "MM%d: MEM 0x%8lx -> 0x%8lx (0x%lx)\n", card->card_number,	       card->mem_base, card->mem_remap, card->mem_len);#else	printk(KERN_INFO "MM%d: MEM area not remapped (CONFIG_MM_MAP_MEMORY not set)\n",	       card->card_number);#endif	switch(card->dev->device) {	case 0x5415:		card->flags |= UM_FLAG_NO_BYTE_STATUS | UM_FLAG_NO_BATTREG;		magic_number = 0x59;		break;	case 0x5425:		card->flags |= UM_FLAG_NO_BYTE_STATUS;		magic_number = 0x5C;		break;	case 0x6155:		card->flags |= UM_FLAG_NO_BYTE_STATUS | UM_FLAG_NO_BATTREG | UM_FLAG_NO_BATT;		magic_number = 0x99;		break;	default:		magic_number = 0x100;		break;	}	if (readb(card->csr_remap + MEMCTRLSTATUS_MAGIC) != magic_number) {		printk(KERN_ERR "MM%d: Magic number invalid\n", card->card_number);		ret = -ENOMEM;		goto failed_magic;	}	card->mm_pages[0].desc = pci_alloc_consistent(card->dev,						      PAGE_SIZE*2,						      &card->mm_pages[0].page_dma);	card->mm_pages[1].desc = pci_alloc_consistent(card->dev,						      PAGE_SIZE*2,						      &card->mm_pages[1].page_dma);	if (card->mm_pages[0].desc == NULL ||	    card->mm_pages[1].desc == NULL) {		printk(KERN_ERR "MM%d: alloc failed\n", card->card_number);		goto failed_alloc;	}	reset_page(&card->mm_pages[0]);	reset_page(&card->mm_pages[1]);	card->Ready = 0;	/* page 0 is ready */	card->Active = -1;	/* no page is active */	card->bio = NULL;	card->biotail = &card->bio;	card->queue = blk_alloc_queue(GFP_KERNEL);	if (!card->queue)		goto failed_alloc;	blk_queue_make_request(card->queue, mm_make_request);	card->queue->queuedata = card;	card->queue->unplug_fn = mm_unplug_device;	tasklet_init(&card->tasklet, process_page, (unsigned long)card);	card->check_batteries = 0;		mem_present = readb(card->csr_remap + MEMCTRLSTATUS_MEMORY);	switch (mem_present) {	case MEM_128_MB:		card->mm_size = 1024 * 128;		break;	case MEM_256_MB:		card->mm_size = 1024 * 256;		break;	case MEM_512_MB:		card->mm_size = 1024 * 512;		break;	case MEM_1_GB:		card->mm_size = 1024 * 1024;		break;	case MEM_2_GB:		card->mm_size = 1024 * 2048;		break;	default:		card->mm_size = 0;		break;	}	/* Clear the LED's we control */	set_led(card, LED_REMOVE, LED_OFF);	set_led(card, LED_FAULT, LED_OFF);	batt_status = readb(card->csr_remap + MEMCTRLSTATUS_BATTERY);	card->battery[0].good = !(batt_status & BATTERY_1_FAILURE);	card->battery[1].good = !(batt_status & BATTERY_2_FAILURE);	card->battery[0].last_change = card->battery[1].last_change = jiffies;	if (card->flags & UM_FLAG_NO_BATT) 		printk(KERN_INFO "MM%d: Size %d KB\n",		       card->card_number, card->mm_size);	else {		printk(KERN_INFO "MM%d: Size %d KB, Battery 1 %s (%s), Battery 2 %s (%s)\n",		       card->card_number, card->mm_size,		       (batt_status & BATTERY_1_DISABLED ? "Disabled" : "Enabled"),		       card->battery[0].good ? "OK" : "FAILURE",		       (batt_status & BATTERY_2_DISABLED ? "Disabled" : "Enabled"),		       card->battery[1].good ? "OK" : "FAILURE");		set_fault_to_battery_status(card);	}	pci_read_config_dword(dev, PCI_BASE_ADDRESS_1, &saved_bar);	data = 0xffffffff;	pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, data);	pci_read_config_dword(dev, PCI_BASE_ADDRESS_1, &data);	pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, saved_bar);	data &= 0xfffffff0;	data = ~data;	data += 1;	card->win_size = data;	if (request_irq(dev->irq, mm_interrupt, SA_SHIRQ, "pci-umem", card)) {		printk(KERN_ERR "MM%d: Unable to allocate IRQ\n", card->card_number);		ret = -ENODEV;		goto failed_req_irq;	}	card->irq = dev->irq;	printk(KERN_INFO "MM%d: Window size %d bytes, IRQ %d\n", card->card_number,	       card->win_size, card->irq);        spin_lock_init(&card->lock);	pci_set_drvdata(dev, card);	if (pci_write_cmd != 0x0F) 	/* If not Memory Write & Invalidate */		pci_write_cmd = 0x07;	/* then Memory Write command */	if (pci_write_cmd & 0x08) { /* use Memory Write and Invalidate */		unsigned short cfg_command;		pci_read_config_word(dev, PCI_COMMAND, &cfg_command);		cfg_command |= 0x10; /* Memory Write & Invalidate Enable */		pci_write_config_word(dev, PCI_COMMAND, cfg_command);	}	pci_cmds = (pci_read_cmd << 28) | (pci_write_cmd << 24);	num_cards++;	if (!get_userbit(card, MEMORY_INITIALIZED)) {		printk(KERN_INFO "MM%d: memory NOT initialized. Consider over-writing whole device.\n", card->card_number);		card->init_size = 0;	} else {		printk(KERN_INFO "MM%d: memory already initialized\n", card->card_number);		card->init_size = card->mm_size;	}	/* Enable ECC */	writeb(EDC_STORE_CORRECT, card->csr_remap + MEMCTRLCMD_ERRCTRL);	return 0; failed_req_irq: failed_alloc:	if (card->mm_pages[0].desc)		pci_free_consistent(card->dev, PAGE_SIZE*2,				    card->mm_pages[0].desc,				    card->mm_pages[0].page_dma);	if (card->mm_pages[1].desc)		pci_free_consistent(card->dev, PAGE_SIZE*2,				    card->mm_pages[1].desc,				    card->mm_pages[1].page_dma); failed_magic:#ifdef CONFIG_MM_MAP_MEMORY	iounmap(card->mem_remap); failed_remap_mem:	release_mem_region(card->mem_base, card->mem_len); failed_req_mem:#endif	iounmap(card->csr_remap); failed_remap_csr:	release_mem_region(card->csr_base, card->csr_len); failed_req_csr:	return ret;}/*-------------------------------------------------------------------------------------                              mm_pci_remove-----------------------------------------------------------------------------------*/static void mm_pci_remove(struct pci_dev *dev){	struct cardinfo *card = pci_get_drvdata(dev);	tasklet_kill(&card->tasklet);	iounmap(card->csr_remap);	release_mem_region(card->csr_base, card->csr_len);#ifdef CONFIG_MM_MAP_MEMORY	iounmap(card->mem_remap);	release_mem_region(card->mem_base, card->mem_len);#endif	free_irq(card->irq, card);	if (card->mm_pages[0].desc)		pci_free_consistent(card->dev, PAGE_SIZE*2,				    card->mm_pages[0].desc,				    card->mm_pages[0].page_dma);	if (card->mm_pages[1].desc)		pci_free_consistent(card->dev, PAGE_SIZE*2,				    card->mm_pages[1].desc,				    card->mm_pages[1].page_dma);	blk_put_queue(card->queue);}static const struct pci_device_id mm_pci_ids[] = { {	.vendor =	PCI_VENDOR_ID_MICRO_MEMORY,	.device =	PCI_DEVICE_ID_MICRO_MEMORY_5415CN,	}, {	.vendor =	PCI_VENDOR_ID_MICRO_MEMORY,	.device =	PCI_DEVICE_ID_MICRO_MEMORY_5425CN,	}, {	.vendor =	PCI_VENDOR_ID_MICRO_MEMORY,	.device =	PCI_DEVICE_ID_MICRO_MEMORY_6155,	}, {	.vendor	=	0x8086,	.device	=	0xB555,	.subvendor=	0x1332,	.subdevice=	0x5460,	.class	=	0x050000,	.class_mask=	0,	}, { /* end: all zeroes */ }};MODULE_DEVICE_TABLE(pci, mm_pci_ids);static struct pci_driver mm_pci_driver = {	.name =		"umem",	.id_table =	mm_pci_ids,	.probe =	mm_pci_probe,	.remove =	mm_pci_remove,};/*-------------------------------------------------------------------------------------                               mm_init-----------------------------------------------------------------------------------*/static int __init mm_init(void){	int retval, i;	int err;	printk(KERN_INFO DRIVER_VERSION " : " DRIVER_DESC "\n");	retval = pci_module_init(&mm_pci_driver);	if (retval)		return -ENOMEM;	err = major_nr = register_blkdev(0, "umem");	if (err < 0)		return -EIO;	for (i = 0; i < num_cards; i++) {		mm_gendisk[i] = alloc_disk(1 << MM_SHIFT);		if (!mm_gendisk[i])			goto out;	}	for (i = 0; i < num_cards; i++) {		struct gendisk *disk = mm_gendisk[i];		sprintf(disk->disk_name, "umem%c", 'a'+i);		sprintf(disk->devfs_name, "umem/card%d", i);		spin_lock_init(&cards[i].lock);		disk->major = major_nr;		disk->first_minor  = i << MM_SHIFT;		disk->fops = &mm_fops;		disk->private_data = &cards[i];		disk->queue = cards[i].queue;		set_capacity(disk, cards[i].mm_size << 1);		add_disk(disk);	}	init_battery_timer();	printk("MM: desc_per_page = %ld\n", DESC_PER_PAGE);/* printk("mm_init: Done. 10-19-01 9:00\n"); */	return 0;out:	unregister_blkdev(major_nr, "umem");	while (i--)		put_disk(mm_gendisk[i]);	return -ENOMEM;}/*-------------------------------------------------------------------------------------                             mm_cleanup-----------------------------------------------------------------------------------*/static void __exit mm_cleanup(void){	int i;	del_battery_timer();	for (i=0; i < num_cards ; i++) {		del_gendisk(mm_gendisk[i]);		put_disk(mm_gendisk[i]);	}	pci_unregister_driver(&mm_pci_driver);	unregister_blkdev(major_nr, "umem");}module_init(mm_init);module_exit(mm_cleanup);MODULE_AUTHOR(DRIVER_AUTHOR);MODULE_DESCRIPTION(DRIVER_DESC);MODULE_LICENSE("GPL");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -