Beispiel #1
0
/* pdev is NULL for eisa */
static int cpqarray_register_ctlr( int i, struct pci_dev *pdev)
{
	request_queue_t *q;
	int j;

	/* 
	 * register block devices
	 * Find disks and fill in structs
	 * Get an interrupt, set the Q depth and get into /proc
	 */

	/* If this successful it should insure that we are the only */
	/* instance of the driver */
	if (register_blkdev(COMPAQ_SMART2_MAJOR+i, hba[i]->devname)) {
		goto Enomem4;
	}
	hba[i]->access.set_intr_mask(hba[i], 0);
	if (request_irq(hba[i]->intr, do_ida_intr,
		SA_INTERRUPT|SA_SHIRQ|SA_SAMPLE_RANDOM,
		hba[i]->devname, hba[i]))
	{
		printk(KERN_ERR "cpqarray: Unable to get irq %d for %s\n",
				hba[i]->intr, hba[i]->devname);
		goto Enomem3;
	}
		
	for (j=0; j<NWD; j++) {
		ida_gendisk[i][j] = alloc_disk(1 << NWD_SHIFT);
		if (!ida_gendisk[i][j])
			goto Enomem2;
	}

	hba[i]->cmd_pool = (cmdlist_t *)pci_alloc_consistent(
		hba[i]->pci_dev, NR_CMDS * sizeof(cmdlist_t),
		&(hba[i]->cmd_pool_dhandle));
	hba[i]->cmd_pool_bits = kmalloc(
		((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long),
		GFP_KERNEL);

	if (!hba[i]->cmd_pool_bits || !hba[i]->cmd_pool)
			goto Enomem1;

	memset(hba[i]->cmd_pool, 0, NR_CMDS * sizeof(cmdlist_t));
	memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+BITS_PER_LONG-1)/BITS_PER_LONG)*sizeof(unsigned long));
	printk(KERN_INFO "cpqarray: Finding drives on %s",
		hba[i]->devname);

	spin_lock_init(&hba[i]->lock);
	q = blk_init_queue(do_ida_request, &hba[i]->lock);
	if (!q)
		goto Enomem1;

	hba[i]->queue = q;
	q->queuedata = hba[i];

	getgeometry(i);
	start_fwbk(i);

	ida_procinit(i);

	if (pdev)
		blk_queue_bounce_limit(q, hba[i]->pci_dev->dma_mask);

	/* This is a hardware imposed limit. */
	blk_queue_max_hw_segments(q, SG_MAX);

	/* This is a driver limit and could be eliminated. */
	blk_queue_max_phys_segments(q, SG_MAX);
	
	init_timer(&hba[i]->timer);
	hba[i]->timer.expires = jiffies + IDA_TIMER;
	hba[i]->timer.data = (unsigned long)hba[i];
	hba[i]->timer.function = ida_timer;
	add_timer(&hba[i]->timer);

	/* Enable IRQ now that spinlock and rate limit timer are set up */
	hba[i]->access.set_intr_mask(hba[i], FIFO_NOT_EMPTY);

	for(j=0; j<NWD; j++) {
		struct gendisk *disk = ida_gendisk[i][j];
		drv_info_t *drv = &hba[i]->drv[j];
		sprintf(disk->disk_name, "ida/c%dd%d", i, j);
		disk->major = COMPAQ_SMART2_MAJOR + i;
		disk->first_minor = j<<NWD_SHIFT;
		disk->fops = &ida_fops;
		if (j && !drv->nr_blks)
			continue;
		blk_queue_hardsect_size(hba[i]->queue, drv->blk_size);
		set_capacity(disk, drv->nr_blks);
		disk->queue = hba[i]->queue;
		disk->private_data = drv;
		add_disk(disk);
	}

	/* done ! */
	return(i);

Enomem1:
	nr_ctlr = i; 
	kfree(hba[i]->cmd_pool_bits);
	if (hba[i]->cmd_pool)
		pci_free_consistent(hba[i]->pci_dev, NR_CMDS*sizeof(cmdlist_t), 
				    hba[i]->cmd_pool, hba[i]->cmd_pool_dhandle);
Enomem2:
	while (j--) {
		put_disk(ida_gendisk[i][j]);
		ida_gendisk[i][j] = NULL;
	}
	free_irq(hba[i]->intr, hba[i]);
Enomem3:
	unregister_blkdev(COMPAQ_SMART2_MAJOR+i, hba[i]->devname);
Enomem4:
	if (pdev)
		pci_set_drvdata(pdev, NULL);
	release_io_mem(hba[i]);
	free_hba(i);

	printk( KERN_ERR "cpqarray: out of memory");

	return -1;
}
Beispiel #2
0
/*
 *  This is it.  Find all the controllers and register them.  I really hate
 *  stealing all these major device numbers.
 */
void cpqarray_init(void)
{
	void (*request_fns[MAX_CTLR])(void) = {
		do_ida_request0, do_ida_request1,
		do_ida_request2, do_ida_request3,
		do_ida_request4, do_ida_request5,
		do_ida_request6, do_ida_request7,
	};
	int i;

	/* detect controllers */
#ifdef CONFIG_BLK_CPQ_DA_PCI
	cpqarray_pci_detect();
#endif
#ifdef CONFIG_BLK_CPQ_DA_EISA
	cpqarray_eisa_detect();
#endif

	if (nr_ctlr == 0)
		return;

	printk(DRIVER_NAME "\n");
	printk("Found %d controller(s)\n", nr_ctlr);

	/* allocate space for disk structs */
	ida = kmalloc(sizeof(struct hd_struct)*nr_ctlr*NWD*16, GFP_KERNEL);
	ida_sizes =      kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
	ida_blocksizes = kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
	ida_hardsizes =  kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);

	ida_maxsegments =  kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);
	ida_maxsectors =  kmalloc(sizeof(int)*nr_ctlr*NWD*16, GFP_KERNEL);

	memset(ida, 0, sizeof(struct hd_struct)*nr_ctlr*NWD*16);
	memset(ida_sizes, 0, sizeof(int)*nr_ctlr*NWD*16);
	memset(ida_blocksizes, 0, sizeof(int)*nr_ctlr*NWD*16);
	memset(ida_hardsizes, 0, sizeof(int)*nr_ctlr*NWD*16);
	memset(ida_maxsegments, 0, sizeof(int)*nr_ctlr*NWD*16);
	memset(ida_maxsectors, 0, sizeof(int)*nr_ctlr*NWD*16);
	memset(ida_gendisk, 0, sizeof(struct gendisk)*MAX_CTLR);

	for(i=0; i<nr_ctlr*NWD*16; i++) {
		ida_maxsegments[i] = SG_MAX;
		ida_maxsectors[i] = 1024;
	}
	/* 
	 * register block devices
	 * Find disks and fill in structs
	 * Get an interrupt, set the Q depth and get into /proc
	 */
	for(i=0; i< nr_ctlr; i++) {
		smart2_write(0, hba[i], INTR_MASK);  /* No interrupts */
		if (request_irq(hba[i]->intr, do_ida_intr,
			SA_INTERRUPT | SA_SHIRQ, hba[i]->devname, hba[i])) {

			printk("Unable to get irq %d for %s\n",
				hba[i]->intr, hba[i]->devname);
			continue;
		}
		if (register_blkdev(MAJOR_NR+i, hba[i]->devname, &ida_fops)) {
			printk("Unable to get major number %d for %s\n",
				MAJOR_NR+i, hba[i]->devname);
			continue;
		}

		hba[i]->cmd_pool = (cmdlist_t*)kmalloc(
				NR_CMDS*sizeof(cmdlist_t), GFP_KERNEL);
		hba[i]->cmd_pool_bits = (__u32*)kmalloc(
				((NR_CMDS+31)/32)*sizeof(__u32), GFP_KERNEL);
		memset(hba[i]->cmd_pool, 0, NR_CMDS*sizeof(cmdlist_t));
		memset(hba[i]->cmd_pool_bits, 0, ((NR_CMDS+31)/32)*sizeof(__u32));

		printk("Finding drives on %s", hba[i]->devname);
		getgeometry(i);

		smart2_write(FIFO_NOT_EMPTY, hba[i], INTR_MASK);

		ida_procinit(i);

		ida_gendisk[i].major = MAJOR_NR + i;
		ida_gendisk[i].major_name = "ida";
		ida_gendisk[i].minor_shift = NWD_SHIFT;
		ida_gendisk[i].max_p = 16;
		ida_gendisk[i].max_nr = 16;
		ida_gendisk[i].init = ida_geninit;
		ida_gendisk[i].part = ida + (i*256);
		ida_gendisk[i].sizes = ida_sizes + (i*256);
		/* ida_gendisk[i].nr_real is handled by getgeometry */
	
		blk_dev[MAJOR_NR+i].request_fn = request_fns[i];
		blksize_size[MAJOR_NR+i] = ida_blocksizes + (i*256);
		hardsect_size[MAJOR_NR+i] = ida_hardsizes + (i*256);
		read_ahead[MAJOR_NR+i] = READ_AHEAD;
		max_sectors[MAJOR_NR+i] = ida_maxsectors + (i*256);
		max_segments[MAJOR_NR+i] = ida_maxsegments + (i*256);

		/* Get on the disk list */
		ida_gendisk[i].next = gendisk_head;
		gendisk_head = &ida_gendisk[i];

		init_timer(&hba[i]->timer);
		hba[i]->timer.expires = jiffies + IDA_TIMER;
		hba[i]->timer.data = (unsigned long)hba[i];
		hba[i]->timer.function = ida_timer;
		add_timer(&hba[i]->timer);

	}
	/* done ! */
}