Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 8abfc6e7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

Merge branch 'for-2.6.37/drivers' of git://git.kernel.dk/linux-2.6-block

* 'for-2.6.37/drivers' of git://git.kernel.dk/linux-2.6-block: (95 commits)
  cciss: fix PCI IDs for new Smart Array controllers
  drbd: add race-breaker to drbd_go_diskless
  drbd: use dynamic_dev_dbg to optionally log uuid changes
  dynamic_debug.h: Fix dynamic_dev_dbg() macro if CONFIG_DYNAMIC_DEBUG not set
  drbd: cleanup: change "<= 0" to "== 0"
  drbd: relax the grace period of the md_sync timer again
  drbd: add some more explicit drbd_md_sync
  drbd: drop wrong debug asserts, fix recently introduced race
  drbd: cleanup useless leftover warn/error printk's
  drbd: add explicit drbd_md_sync to drbd_resync_finished
  drbd: Do not log an ASSERT for P_OV_REQUEST packets while C_CONNECTED
  drbd: fix for possible deadlock on IO error during resync
  drbd: fix unlikely access after free and list corruption
  drbd: fix for spurious fullsync (uuids rotated too fast)
  drbd: allow for explicit resync-finished notifications
  drbd: preparation commit, using full state in receive_state()
  drbd: drbd_send_ack_dp must not rely on header information
  drbd: Fix regression in recv_bm_rle_bits (compressed bitmap)
  drbd: Fixed a stupid copy and paste error
  drbd: Allow larger values for c-fill-target.
  ...

Fix up trivial conflict in drivers/block/ataflop.c due to BKL removal
parents e9dd2b68 6362beea
Loading
Loading
Loading
Loading
+48 −12
Original line number Original line Diff line number Diff line
@@ -115,8 +115,6 @@ static unsigned long int fd_def_df0 = FD_DD_3; /* default for df0 if it does
module_param(fd_def_df0, ulong, 0);
module_param(fd_def_df0, ulong, 0);
MODULE_LICENSE("GPL");
MODULE_LICENSE("GPL");


static struct request_queue *floppy_queue;

/*
/*
 *  Macros
 *  Macros
 */
 */
@@ -165,6 +163,7 @@ static volatile int selected = -1; /* currently selected drive */
static int writepending;
static int writepending;
static int writefromint;
static int writefromint;
static char *raw_buf;
static char *raw_buf;
static int fdc_queue;


static DEFINE_SPINLOCK(amiflop_lock);
static DEFINE_SPINLOCK(amiflop_lock);


@@ -1335,6 +1334,42 @@ static int get_track(int drive, int track)
	return -1;
	return -1;
}
}


/*
 * Round-robin between our available drives, doing one request from each
 */
static struct request *set_next_request(void)
{
	struct request_queue *q;
	int cnt = FD_MAX_UNITS;
	struct request *rq;

	/* Find next queue we can dispatch from */
	fdc_queue = fdc_queue + 1;
	if (fdc_queue == FD_MAX_UNITS)
		fdc_queue = 0;

	for(cnt = FD_MAX_UNITS; cnt > 0; cnt--) {

		if (unit[fdc_queue].type->code == FD_NODRIVE) {
			if (++fdc_queue == FD_MAX_UNITS)
				fdc_queue = 0;
			continue;
		}

		q = unit[fdc_queue].gendisk->queue;
		if (q) {
			rq = blk_fetch_request(q);
			if (rq)
				break;
		}

		if (++fdc_queue == FD_MAX_UNITS)
			fdc_queue = 0;
	}

	return rq;
}

static void redo_fd_request(void)
static void redo_fd_request(void)
{
{
	struct request *rq;
	struct request *rq;
@@ -1346,7 +1381,7 @@ static void redo_fd_request(void)
	int err;
	int err;


next_req:
next_req:
	rq = blk_fetch_request(floppy_queue);
	rq = set_next_request();
	if (!rq) {
	if (!rq) {
		/* Nothing left to do */
		/* Nothing left to do */
		return;
		return;
@@ -1683,6 +1718,13 @@ static int __init fd_probe_drives(void)
			continue;
			continue;
		}
		}
		unit[drive].gendisk = disk;
		unit[drive].gendisk = disk;

		disk->queue = blk_init_queue(do_fd_request, &amiflop_lock);
		if (!disk->queue) {
			unit[drive].type->code = FD_NODRIVE;
			continue;
		}

		drives++;
		drives++;
		if ((unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL)) == NULL) {
		if ((unit[drive].trackbuf = kmalloc(FLOPPY_MAX_SECTORS * 512, GFP_KERNEL)) == NULL) {
			printk("no mem for ");
			printk("no mem for ");
@@ -1696,7 +1738,6 @@ static int __init fd_probe_drives(void)
		disk->fops = &floppy_fops;
		disk->fops = &floppy_fops;
		sprintf(disk->disk_name, "fd%d", drive);
		sprintf(disk->disk_name, "fd%d", drive);
		disk->private_data = &unit[drive];
		disk->private_data = &unit[drive];
		disk->queue = floppy_queue;
		set_capacity(disk, 880*2);
		set_capacity(disk, 880*2);
		add_disk(disk);
		add_disk(disk);
	}
	}
@@ -1744,11 +1785,6 @@ static int __init amiga_floppy_probe(struct platform_device *pdev)
		goto out_irq2;
		goto out_irq2;
	}
	}


	ret = -ENOMEM;
	floppy_queue = blk_init_queue(do_fd_request, &amiflop_lock);
	if (!floppy_queue)
		goto out_queue;

	ret = -ENODEV;
	ret = -ENODEV;
	if (fd_probe_drives() < 1) /* No usable drives */
	if (fd_probe_drives() < 1) /* No usable drives */
		goto out_probe;
		goto out_probe;
@@ -1792,8 +1828,6 @@ static int __init amiga_floppy_probe(struct platform_device *pdev)
	return 0;
	return 0;


out_probe:
out_probe:
	blk_cleanup_queue(floppy_queue);
out_queue:
	free_irq(IRQ_AMIGA_CIAA_TB, NULL);
	free_irq(IRQ_AMIGA_CIAA_TB, NULL);
out_irq2:
out_irq2:
	free_irq(IRQ_AMIGA_DSKBLK, NULL);
	free_irq(IRQ_AMIGA_DSKBLK, NULL);
@@ -1811,9 +1845,12 @@ static int __exit amiga_floppy_remove(struct platform_device *pdev)


	for( i = 0; i < FD_MAX_UNITS; i++) {
	for( i = 0; i < FD_MAX_UNITS; i++) {
		if (unit[i].type->code != FD_NODRIVE) {
		if (unit[i].type->code != FD_NODRIVE) {
			struct request_queue *q = unit[i].gendisk->queue;
			del_gendisk(unit[i].gendisk);
			del_gendisk(unit[i].gendisk);
			put_disk(unit[i].gendisk);
			put_disk(unit[i].gendisk);
			kfree(unit[i].trackbuf);
			kfree(unit[i].trackbuf);
			if (q)
				blk_cleanup_queue(q);
		}
		}
	}
	}
	blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
	blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
@@ -1821,7 +1858,6 @@ static int __exit amiga_floppy_remove(struct platform_device *pdev)
	free_irq(IRQ_AMIGA_DSKBLK, NULL);
	free_irq(IRQ_AMIGA_DSKBLK, NULL);
	custom.dmacon = DMAF_DISK; /* disable DMA */
	custom.dmacon = DMAF_DISK; /* disable DMA */
	amiga_chip_free(raw_buf);
	amiga_chip_free(raw_buf);
	blk_cleanup_queue(floppy_queue);
	unregister_blkdev(FLOPPY_MAJOR, "fd");
	unregister_blkdev(FLOPPY_MAJOR, "fd");
}
}
#endif
#endif
+39 −11
Original line number Original line Diff line number Diff line
@@ -80,8 +80,8 @@
#undef DEBUG
#undef DEBUG


static DEFINE_MUTEX(ataflop_mutex);
static DEFINE_MUTEX(ataflop_mutex);
static struct request_queue *floppy_queue;
static struct request *fd_request;
static struct request *fd_request;
static int fdc_queue;


/* Disk types: DD, HD, ED */
/* Disk types: DD, HD, ED */
static struct atari_disk_type {
static struct atari_disk_type {
@@ -1392,6 +1392,29 @@ static void setup_req_params( int drive )
			ReqTrack, ReqSector, (unsigned long)ReqData ));
			ReqTrack, ReqSector, (unsigned long)ReqData ));
}
}


/*
 * Round-robin between our available drives, doing one request from each
 */
static struct request *set_next_request(void)
{
	struct request_queue *q;
	int old_pos = fdc_queue;
	struct request *rq;

	do {
		q = unit[fdc_queue].disk->queue;
		if (++fdc_queue == FD_MAX_UNITS)
			fdc_queue = 0;
		if (q) {
			rq = blk_fetch_request(q);
			if (rq)
				break;
		}
	} while (fdc_queue != old_pos);

	return rq;
}



static void redo_fd_request(void)
static void redo_fd_request(void)
{
{
@@ -1406,7 +1429,7 @@ static void redo_fd_request(void)


repeat:
repeat:
	if (!fd_request) {
	if (!fd_request) {
		fd_request = blk_fetch_request(floppy_queue);
		fd_request = set_next_request();
		if (!fd_request)
		if (!fd_request)
			goto the_end;
			goto the_end;
	}
	}
@@ -1933,10 +1956,6 @@ static int __init atari_floppy_init (void)
	PhysTrackBuffer = virt_to_phys(TrackBuffer);
	PhysTrackBuffer = virt_to_phys(TrackBuffer);
	BufferDrive = BufferSide = BufferTrack = -1;
	BufferDrive = BufferSide = BufferTrack = -1;


	floppy_queue = blk_init_queue(do_fd_request, &ataflop_lock);
	if (!floppy_queue)
		goto Enomem;

	for (i = 0; i < FD_MAX_UNITS; i++) {
	for (i = 0; i < FD_MAX_UNITS; i++) {
		unit[i].track = -1;
		unit[i].track = -1;
		unit[i].flags = 0;
		unit[i].flags = 0;
@@ -1945,7 +1964,10 @@ static int __init atari_floppy_init (void)
		sprintf(unit[i].disk->disk_name, "fd%d", i);
		sprintf(unit[i].disk->disk_name, "fd%d", i);
		unit[i].disk->fops = &floppy_fops;
		unit[i].disk->fops = &floppy_fops;
		unit[i].disk->private_data = &unit[i];
		unit[i].disk->private_data = &unit[i];
		unit[i].disk->queue = floppy_queue;
		unit[i].disk->queue = blk_init_queue(do_fd_request,
					&ataflop_lock);
		if (!unit[i].disk->queue)
			goto Enomem;
		set_capacity(unit[i].disk, MAX_DISK_SIZE * 2);
		set_capacity(unit[i].disk, MAX_DISK_SIZE * 2);
		add_disk(unit[i].disk);
		add_disk(unit[i].disk);
	}
	}
@@ -1960,10 +1982,14 @@ static int __init atari_floppy_init (void)


	return 0;
	return 0;
Enomem:
Enomem:
	while (i--)
	while (i--) {
		struct request_queue *q = unit[i].disk->queue;

		put_disk(unit[i].disk);
		put_disk(unit[i].disk);
	if (floppy_queue)
		if (q)
		blk_cleanup_queue(floppy_queue);
			blk_cleanup_queue(q);
	}

	unregister_blkdev(FLOPPY_MAJOR, "fd");
	unregister_blkdev(FLOPPY_MAJOR, "fd");
	return -ENOMEM;
	return -ENOMEM;
}
}
@@ -2012,12 +2038,14 @@ static void __exit atari_floppy_exit(void)
	int i;
	int i;
	blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
	blk_unregister_region(MKDEV(FLOPPY_MAJOR, 0), 256);
	for (i = 0; i < FD_MAX_UNITS; i++) {
	for (i = 0; i < FD_MAX_UNITS; i++) {
		struct request_queue *q = unit[i].disk->queue;

		del_gendisk(unit[i].disk);
		del_gendisk(unit[i].disk);
		put_disk(unit[i].disk);
		put_disk(unit[i].disk);
		blk_cleanup_queue(q);
	}
	}
	unregister_blkdev(FLOPPY_MAJOR, "fd");
	unregister_blkdev(FLOPPY_MAJOR, "fd");


	blk_cleanup_queue(floppy_queue);
	del_timer_sync(&fd_timer);
	del_timer_sync(&fd_timer);
	atari_stram_free( DMABuffer );
	atari_stram_free( DMABuffer );
}
}
+424 −440
Original line number Original line Diff line number Diff line
@@ -105,11 +105,12 @@ static const struct pci_device_id cciss_pci_device_id[] = {
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3249},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3249},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x324A},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x324A},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x324B},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x324B},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3250},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSF,     0x103C, 0x3350},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3251},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSF,     0x103C, 0x3351},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3252},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSF,     0x103C, 0x3352},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3253},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSF,     0x103C, 0x3353},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSE,     0x103C, 0x3254},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSF,     0x103C, 0x3354},
	{PCI_VENDOR_ID_HP,     PCI_DEVICE_ID_HP_CISSF,     0x103C, 0x3355},
	{0,}
	{0,}
};
};


@@ -149,11 +150,12 @@ static struct board_type products[] = {
	{0x3249103C, "Smart Array P812", &SA5_access},
	{0x3249103C, "Smart Array P812", &SA5_access},
	{0x324A103C, "Smart Array P712m", &SA5_access},
	{0x324A103C, "Smart Array P712m", &SA5_access},
	{0x324B103C, "Smart Array P711m", &SA5_access},
	{0x324B103C, "Smart Array P711m", &SA5_access},
	{0x3250103C, "Smart Array", &SA5_access},
	{0x3350103C, "Smart Array", &SA5_access},
	{0x3251103C, "Smart Array", &SA5_access},
	{0x3351103C, "Smart Array", &SA5_access},
	{0x3252103C, "Smart Array", &SA5_access},
	{0x3352103C, "Smart Array", &SA5_access},
	{0x3253103C, "Smart Array", &SA5_access},
	{0x3353103C, "Smart Array", &SA5_access},
	{0x3254103C, "Smart Array", &SA5_access},
	{0x3354103C, "Smart Array", &SA5_access},
	{0x3355103C, "Smart Array", &SA5_access},
};
};


/* How long to wait (in milliseconds) for board to go into simple mode */
/* How long to wait (in milliseconds) for board to go into simple mode */
@@ -1232,128 +1234,102 @@ static void check_ioctl_unit_attention(ctlr_info_t *h, CommandList_struct *c)
			c->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION)
			c->err_info->ScsiStatus != SAM_STAT_CHECK_CONDITION)
		(void)check_for_unit_attention(h, c);
		(void)check_for_unit_attention(h, c);
}
}
/*
 * ioctl
 */
static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
		       unsigned int cmd, unsigned long arg)
{
	struct gendisk *disk = bdev->bd_disk;
	ctlr_info_t *h = get_host(disk);
	drive_info_struct *drv = get_drv(disk);
	void __user *argp = (void __user *)arg;


	dev_dbg(&h->pdev->dev, "cciss_ioctl: Called with cmd=%x %lx\n",
static int cciss_getpciinfo(ctlr_info_t *h, void __user *argp)
		cmd, arg);
	switch (cmd) {
	case CCISS_GETPCIINFO:
{
{
	cciss_pci_info_struct pciinfo;
	cciss_pci_info_struct pciinfo;


			if (!arg)
	if (!argp)
		return -EINVAL;
		return -EINVAL;
	pciinfo.domain = pci_domain_nr(h->pdev->bus);
	pciinfo.domain = pci_domain_nr(h->pdev->bus);
	pciinfo.bus = h->pdev->bus->number;
	pciinfo.bus = h->pdev->bus->number;
	pciinfo.dev_fn = h->pdev->devfn;
	pciinfo.dev_fn = h->pdev->devfn;
	pciinfo.board_id = h->board_id;
	pciinfo.board_id = h->board_id;
			if (copy_to_user
	if (copy_to_user(argp, &pciinfo, sizeof(cciss_pci_info_struct)))
			    (argp, &pciinfo, sizeof(cciss_pci_info_struct)))
		return -EFAULT;
		return -EFAULT;
	return 0;
	return 0;
}
}
	case CCISS_GETINTINFO:

static int cciss_getintinfo(ctlr_info_t *h, void __user *argp)
{
{
	cciss_coalint_struct intinfo;
	cciss_coalint_struct intinfo;
			if (!arg)

	if (!argp)
		return -EINVAL;
		return -EINVAL;
			intinfo.delay =
	intinfo.delay = readl(&h->cfgtable->HostWrite.CoalIntDelay);
			    readl(&h->cfgtable->HostWrite.CoalIntDelay);
	intinfo.count = readl(&h->cfgtable->HostWrite.CoalIntCount);
			intinfo.count =
			    readl(&h->cfgtable->HostWrite.CoalIntCount);
	if (copy_to_user
	if (copy_to_user
	    (argp, &intinfo, sizeof(cciss_coalint_struct)))
	    (argp, &intinfo, sizeof(cciss_coalint_struct)))
		return -EFAULT;
		return -EFAULT;
	return 0;
	return 0;
}
}
	case CCISS_SETINTINFO:

static int cciss_setintinfo(ctlr_info_t *h, void __user *argp)
{
{
	cciss_coalint_struct intinfo;
	cciss_coalint_struct intinfo;
	unsigned long flags;
	unsigned long flags;
	int i;
	int i;


			if (!arg)
	if (!argp)
		return -EINVAL;
		return -EINVAL;
	if (!capable(CAP_SYS_ADMIN))
	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;
		return -EPERM;
			if (copy_from_user
	if (copy_from_user(&intinfo, argp, sizeof(intinfo)))
			    (&intinfo, argp, sizeof(cciss_coalint_struct)))
		return -EFAULT;
		return -EFAULT;
	if ((intinfo.delay == 0) && (intinfo.count == 0))
	if ((intinfo.delay == 0) && (intinfo.count == 0))
		return -EINVAL;
		return -EINVAL;
	spin_lock_irqsave(&h->lock, flags);
	spin_lock_irqsave(&h->lock, flags);
	/* Update the field, and then ring the doorbell */
	/* Update the field, and then ring the doorbell */
			writel(intinfo.delay,
	writel(intinfo.delay, &(h->cfgtable->HostWrite.CoalIntDelay));
			       &(h->cfgtable->HostWrite.CoalIntDelay));
	writel(intinfo.count, &(h->cfgtable->HostWrite.CoalIntCount));
			writel(intinfo.count,
			       &(h->cfgtable->HostWrite.CoalIntCount));
	writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
	writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);


	for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
	for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
				if (!(readl(h->vaddr + SA5_DOORBELL)
		if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
				      & CFGTBL_ChangeReq))
			break;
			break;
				/* delay and try again */
		udelay(1000); /* delay and try again */
				udelay(1000);
	}
	}
	spin_unlock_irqrestore(&h->lock, flags);
	spin_unlock_irqrestore(&h->lock, flags);
	if (i >= MAX_IOCTL_CONFIG_WAIT)
	if (i >= MAX_IOCTL_CONFIG_WAIT)
		return -EAGAIN;
		return -EAGAIN;
	return 0;
	return 0;
}
}
	case CCISS_GETNODENAME:

static int cciss_getnodename(ctlr_info_t *h, void __user *argp)
{
{
	NodeName_type NodeName;
	NodeName_type NodeName;
	int i;
	int i;


			if (!arg)
	if (!argp)
		return -EINVAL;
		return -EINVAL;
	for (i = 0; i < 16; i++)
	for (i = 0; i < 16; i++)
				NodeName[i] =
		NodeName[i] = readb(&h->cfgtable->ServerName[i]);
				    readb(&h->cfgtable->ServerName[i]);
	if (copy_to_user(argp, NodeName, sizeof(NodeName_type)))
	if (copy_to_user(argp, NodeName, sizeof(NodeName_type)))
		return -EFAULT;
		return -EFAULT;
	return 0;
	return 0;
}
}
	case CCISS_SETNODENAME:

static int cciss_setnodename(ctlr_info_t *h, void __user *argp)
{
{
	NodeName_type NodeName;
	NodeName_type NodeName;
	unsigned long flags;
	unsigned long flags;
	int i;
	int i;


			if (!arg)
	if (!argp)
		return -EINVAL;
		return -EINVAL;
	if (!capable(CAP_SYS_ADMIN))
	if (!capable(CAP_SYS_ADMIN))
		return -EPERM;
		return -EPERM;

	if (copy_from_user(NodeName, argp, sizeof(NodeName_type)))
			if (copy_from_user
			    (NodeName, argp, sizeof(NodeName_type)))
		return -EFAULT;
		return -EFAULT;

	spin_lock_irqsave(&h->lock, flags);
	spin_lock_irqsave(&h->lock, flags);

	/* Update the field, and then ring the doorbell */
	/* Update the field, and then ring the doorbell */
	for (i = 0; i < 16; i++)
	for (i = 0; i < 16; i++)
				writeb(NodeName[i],
		writeb(NodeName[i], &h->cfgtable->ServerName[i]);
				       &h->cfgtable->ServerName[i]);

	writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);
	writel(CFGTBL_ChangeReq, h->vaddr + SA5_DOORBELL);

	for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
	for (i = 0; i < MAX_IOCTL_CONFIG_WAIT; i++) {
				if (!(readl(h->vaddr + SA5_DOORBELL)
		if (!(readl(h->vaddr + SA5_DOORBELL) & CFGTBL_ChangeReq))
				      & CFGTBL_ChangeReq))
			break;
			break;
				/* delay and try again */
		udelay(1000); /* delay and try again */
				udelay(1000);
	}
	}
	spin_unlock_irqrestore(&h->lock, flags);
	spin_unlock_irqrestore(&h->lock, flags);
	if (i >= MAX_IOCTL_CONFIG_WAIT)
	if (i >= MAX_IOCTL_CONFIG_WAIT)
@@ -1361,35 +1337,35 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	return 0;
	return 0;
}
}


	case CCISS_GETHEARTBEAT:
static int cciss_getheartbeat(ctlr_info_t *h, void __user *argp)
{
{
	Heartbeat_type heartbeat;
	Heartbeat_type heartbeat;


			if (!arg)
	if (!argp)
		return -EINVAL;
		return -EINVAL;
	heartbeat = readl(&h->cfgtable->HeartBeat);
	heartbeat = readl(&h->cfgtable->HeartBeat);
			if (copy_to_user
	if (copy_to_user(argp, &heartbeat, sizeof(Heartbeat_type)))
			    (argp, &heartbeat, sizeof(Heartbeat_type)))
		return -EFAULT;
		return -EFAULT;
	return 0;
	return 0;
}
}
	case CCISS_GETBUSTYPES:

static int cciss_getbustypes(ctlr_info_t *h, void __user *argp)
{
{
	BusTypes_type BusTypes;
	BusTypes_type BusTypes;


			if (!arg)
	if (!argp)
		return -EINVAL;
		return -EINVAL;
	BusTypes = readl(&h->cfgtable->BusTypes);
	BusTypes = readl(&h->cfgtable->BusTypes);
			if (copy_to_user
	if (copy_to_user(argp, &BusTypes, sizeof(BusTypes_type)))
			    (argp, &BusTypes, sizeof(BusTypes_type)))
		return -EFAULT;
		return -EFAULT;
	return 0;
	return 0;
}
}
	case CCISS_GETFIRMVER:

static int cciss_getfirmver(ctlr_info_t *h, void __user *argp)
{
{
	FirmwareVer_type firmware;
	FirmwareVer_type firmware;


			if (!arg)
	if (!argp)
		return -EINVAL;
		return -EINVAL;
	memcpy(firmware, h->firm_ver, 4);
	memcpy(firmware, h->firm_ver, 4);


@@ -1398,37 +1374,35 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
		return -EFAULT;
		return -EFAULT;
	return 0;
	return 0;
}
}
	case CCISS_GETDRIVVER:

static int cciss_getdrivver(ctlr_info_t *h, void __user *argp)
{
{
	DriverVer_type DriverVer = DRIVER_VERSION;
	DriverVer_type DriverVer = DRIVER_VERSION;


			if (!arg)
	if (!argp)
		return -EINVAL;
		return -EINVAL;

	if (copy_to_user(argp, &DriverVer, sizeof(DriverVer_type)))
			if (copy_to_user
			    (argp, &DriverVer, sizeof(DriverVer_type)))
		return -EFAULT;
		return -EFAULT;
	return 0;
	return 0;
}
}


	case CCISS_DEREGDISK:
static int cciss_getluninfo(ctlr_info_t *h,
	case CCISS_REGNEWD:
	struct gendisk *disk, void __user *argp)
	case CCISS_REVALIDVOLS:
{
		return rebuild_lun_table(h, 0, 1);

	case CCISS_GETLUNINFO:{
	LogvolInfo_struct luninfo;
	LogvolInfo_struct luninfo;
	drive_info_struct *drv = get_drv(disk);


			memcpy(&luninfo.LunID, drv->LunID,
	if (!argp)
				sizeof(luninfo.LunID));
		return -EINVAL;
	memcpy(&luninfo.LunID, drv->LunID, sizeof(luninfo.LunID));
	luninfo.num_opens = drv->usage_count;
	luninfo.num_opens = drv->usage_count;
	luninfo.num_parts = 0;
	luninfo.num_parts = 0;
			if (copy_to_user(argp, &luninfo,
	if (copy_to_user(argp, &luninfo, sizeof(LogvolInfo_struct)))
					 sizeof(LogvolInfo_struct)))
		return -EFAULT;
		return -EFAULT;
	return 0;
	return 0;
}
}
	case CCISS_PASSTHRU:

static int cciss_passthru(ctlr_info_t *h, void __user *argp)
{
{
	IOCTL_Command_struct iocommand;
	IOCTL_Command_struct iocommand;
	CommandList_struct *c;
	CommandList_struct *c;
@@ -1436,7 +1410,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	u64bit temp64;
	u64bit temp64;
	DECLARE_COMPLETION_ONSTACK(wait);
	DECLARE_COMPLETION_ONSTACK(wait);


			if (!arg)
	if (!argp)
		return -EINVAL;
		return -EINVAL;


	if (!capable(CAP_SYS_RAWIO))
	if (!capable(CAP_SYS_RAWIO))
@@ -1449,11 +1423,6 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	    (iocommand.Request.Type.Direction != XFER_NONE)) {
	    (iocommand.Request.Type.Direction != XFER_NONE)) {
		return -EINVAL;
		return -EINVAL;
	}
	}
#if 0				/* 'buf_size' member is 16-bits, and always smaller than kmalloc limit */
			/* Check kmalloc limits */
			if (iocommand.buf_size > 128000)
				return -EINVAL;
#endif
	if (iocommand.buf_size > 0) {
	if (iocommand.buf_size > 0) {
		buff = kmalloc(iocommand.buf_size, GFP_KERNEL);
		buff = kmalloc(iocommand.buf_size, GFP_KERNEL);
		if (buff == NULL)
		if (buff == NULL)
@@ -1461,8 +1430,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	}
	}
	if (iocommand.Request.Type.Direction == XFER_WRITE) {
	if (iocommand.Request.Type.Direction == XFER_WRITE) {
		/* Copy the data into the buffer we created */
		/* Copy the data into the buffer we created */
				if (copy_from_user
		if (copy_from_user(buff, iocommand.buf, iocommand.buf_size)) {
				    (buff, iocommand.buf, iocommand.buf_size)) {
			kfree(buff);
			kfree(buff);
			return -EFAULT;
			return -EFAULT;
		}
		}
@@ -1478,12 +1446,10 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	c->cmd_type = CMD_IOCTL_PEND;
	c->cmd_type = CMD_IOCTL_PEND;
	/* Fill in Command Header */
	/* Fill in Command Header */
	c->Header.ReplyQueue = 0;   /* unused in simple mode */
	c->Header.ReplyQueue = 0;   /* unused in simple mode */
			if (iocommand.buf_size > 0) /* buffer to fill */
	if (iocommand.buf_size > 0) { /* buffer to fill */
			{
		c->Header.SGList = 1;
		c->Header.SGList = 1;
		c->Header.SGTotal = 1;
		c->Header.SGTotal = 1;
			} else /* no buffers to fill */
	} else { /* no buffers to fill */
			{
		c->Header.SGList = 0;
		c->Header.SGList = 0;
		c->Header.SGTotal = 0;
		c->Header.SGTotal = 0;
	}
	}
@@ -1497,8 +1463,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	/* Fill in the scatter gather information */
	/* Fill in the scatter gather information */
	if (iocommand.buf_size > 0) {
	if (iocommand.buf_size > 0) {
		temp64.val = pci_map_single(h->pdev, buff,
		temp64.val = pci_map_single(h->pdev, buff,
					iocommand.buf_size,
			iocommand.buf_size, PCI_DMA_BIDIRECTIONAL);
					PCI_DMA_BIDIRECTIONAL);
		c->SG[0].Addr.lower = temp64.val32.lower;
		c->SG[0].Addr.lower = temp64.val32.lower;
		c->SG[0].Addr.upper = temp64.val32.upper;
		c->SG[0].Addr.upper = temp64.val32.upper;
		c->SG[0].Len = iocommand.buf_size;
		c->SG[0].Len = iocommand.buf_size;
@@ -1512,16 +1477,13 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	/* unlock the buffers from DMA */
	/* unlock the buffers from DMA */
	temp64.val32.lower = c->SG[0].Addr.lower;
	temp64.val32.lower = c->SG[0].Addr.lower;
	temp64.val32.upper = c->SG[0].Addr.upper;
	temp64.val32.upper = c->SG[0].Addr.upper;
			pci_unmap_single(h->pdev, (dma_addr_t) temp64.val,
	pci_unmap_single(h->pdev, (dma_addr_t) temp64.val, iocommand.buf_size,
					 iocommand.buf_size,
			 PCI_DMA_BIDIRECTIONAL);
			 PCI_DMA_BIDIRECTIONAL);

	check_ioctl_unit_attention(h, c);
	check_ioctl_unit_attention(h, c);


	/* Copy the error information out */
	/* Copy the error information out */
	iocommand.error_info = *(c->err_info);
	iocommand.error_info = *(c->err_info);
			if (copy_to_user
	if (copy_to_user(argp, &iocommand, sizeof(IOCTL_Command_struct))) {
			    (argp, &iocommand, sizeof(IOCTL_Command_struct))) {
		kfree(buff);
		kfree(buff);
		cmd_special_free(h, c);
		cmd_special_free(h, c);
		return -EFAULT;
		return -EFAULT;
@@ -1529,8 +1491,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,


	if (iocommand.Request.Type.Direction == XFER_READ) {
	if (iocommand.Request.Type.Direction == XFER_READ) {
		/* Copy the data out of the buffer we created */
		/* Copy the data out of the buffer we created */
				if (copy_to_user
		if (copy_to_user(iocommand.buf, buff, iocommand.buf_size)) {
				    (iocommand.buf, buff, iocommand.buf_size)) {
			kfree(buff);
			kfree(buff);
			cmd_special_free(h, c);
			cmd_special_free(h, c);
			return -EFAULT;
			return -EFAULT;
@@ -1540,7 +1501,9 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	cmd_special_free(h, c);
	cmd_special_free(h, c);
	return 0;
	return 0;
}
}
	case CCISS_BIG_PASSTHRU:{

static int cciss_bigpassthru(ctlr_info_t *h, void __user *argp)
{
	BIG_IOCTL_Command_struct *ioc;
	BIG_IOCTL_Command_struct *ioc;
	CommandList_struct *c;
	CommandList_struct *c;
	unsigned char **buff = NULL;
	unsigned char **buff = NULL;
@@ -1554,7 +1517,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	__u32 sz;
	__u32 sz;
	BYTE __user *data_ptr;
	BYTE __user *data_ptr;


			if (!arg)
	if (!argp)
		return -EINVAL;
		return -EINVAL;
	if (!capable(CAP_SYS_RAWIO))
	if (!capable(CAP_SYS_RAWIO))
		return -EPERM;
		return -EPERM;
@@ -1582,14 +1545,12 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
		status = -EINVAL;
		status = -EINVAL;
		goto cleanup1;
		goto cleanup1;
	}
	}
			buff =
	buff = kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL);
			    kzalloc(MAXSGENTRIES * sizeof(char *), GFP_KERNEL);
	if (!buff) {
	if (!buff) {
		status = -ENOMEM;
		status = -ENOMEM;
		goto cleanup1;
		goto cleanup1;
	}
	}
			buff_size = kmalloc(MAXSGENTRIES * sizeof(int),
	buff_size = kmalloc(MAXSGENTRIES * sizeof(int), GFP_KERNEL);
						   GFP_KERNEL);
	if (!buff_size) {
	if (!buff_size) {
		status = -ENOMEM;
		status = -ENOMEM;
		goto cleanup1;
		goto cleanup1;
@@ -1597,9 +1558,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	left = ioc->buf_size;
	left = ioc->buf_size;
	data_ptr = ioc->buf;
	data_ptr = ioc->buf;
	while (left) {
	while (left) {
				sz = (left >
		sz = (left > ioc->malloc_size) ? ioc->malloc_size : left;
				      ioc->malloc_size) ? ioc->
				    malloc_size : left;
		buff_size[sg_used] = sz;
		buff_size[sg_used] = sz;
		buff[sg_used] = kmalloc(sz, GFP_KERNEL);
		buff[sg_used] = kmalloc(sz, GFP_KERNEL);
		if (buff[sg_used] == NULL) {
		if (buff[sg_used] == NULL) {
@@ -1607,8 +1566,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
			goto cleanup1;
			goto cleanup1;
		}
		}
		if (ioc->Request.Type.Direction == XFER_WRITE) {
		if (ioc->Request.Type.Direction == XFER_WRITE) {
					if (copy_from_user
			if (copy_from_user(buff[sg_used], data_ptr, sz)) {
					    (buff[sg_used], data_ptr, sz)) {
				status = -EFAULT;
				status = -EFAULT;
				goto cleanup1;
				goto cleanup1;
			}
			}
@@ -1626,32 +1584,20 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	}
	}
	c->cmd_type = CMD_IOCTL_PEND;
	c->cmd_type = CMD_IOCTL_PEND;
	c->Header.ReplyQueue = 0;
	c->Header.ReplyQueue = 0;

			if (ioc->buf_size > 0) {
	c->Header.SGList = sg_used;
	c->Header.SGList = sg_used;
	c->Header.SGTotal = sg_used;
	c->Header.SGTotal = sg_used;
			} else {
				c->Header.SGList = 0;
				c->Header.SGTotal = 0;
			}
	c->Header.LUN = ioc->LUN_info;
	c->Header.LUN = ioc->LUN_info;
	c->Header.Tag.lower = c->busaddr;
	c->Header.Tag.lower = c->busaddr;


	c->Request = ioc->Request;
	c->Request = ioc->Request;
			if (ioc->buf_size > 0) {
	for (i = 0; i < sg_used; i++) {
	for (i = 0; i < sg_used; i++) {
					temp64.val =
		temp64.val = pci_map_single(h->pdev, buff[i], buff_size[i],
					    pci_map_single(h->pdev, buff[i],
						    buff_size[i],
				    PCI_DMA_BIDIRECTIONAL);
				    PCI_DMA_BIDIRECTIONAL);
					c->SG[i].Addr.lower =
		c->SG[i].Addr.lower = temp64.val32.lower;
					    temp64.val32.lower;
		c->SG[i].Addr.upper = temp64.val32.upper;
					c->SG[i].Addr.upper =
					    temp64.val32.upper;
		c->SG[i].Len = buff_size[i];
		c->SG[i].Len = buff_size[i];
		c->SG[i].Ext = 0;	/* we are not chaining */
		c->SG[i].Ext = 0;	/* we are not chaining */
	}
	}
			}
	c->waiting = &wait;
	c->waiting = &wait;
	enqueue_cmd_and_start_io(h, c);
	enqueue_cmd_and_start_io(h, c);
	wait_for_completion(&wait);
	wait_for_completion(&wait);
@@ -1675,8 +1621,7 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
		/* Copy the data out of the buffer we created */
		/* Copy the data out of the buffer we created */
		BYTE __user *ptr = ioc->buf;
		BYTE __user *ptr = ioc->buf;
		for (i = 0; i < sg_used; i++) {
		for (i = 0; i < sg_used; i++) {
					if (copy_to_user
			if (copy_to_user(ptr, buff[i], buff_size[i])) {
					    (ptr, buff[i], buff_size[i])) {
				cmd_special_free(h, c);
				cmd_special_free(h, c);
				status = -EFAULT;
				status = -EFAULT;
				goto cleanup1;
				goto cleanup1;
@@ -1697,6 +1642,45 @@ static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	return status;
	return status;
}
}


static int cciss_ioctl(struct block_device *bdev, fmode_t mode,
	unsigned int cmd, unsigned long arg)
{
	struct gendisk *disk = bdev->bd_disk;
	ctlr_info_t *h = get_host(disk);
	void __user *argp = (void __user *)arg;

	dev_dbg(&h->pdev->dev, "cciss_ioctl: Called with cmd=%x %lx\n",
		cmd, arg);
	switch (cmd) {
	case CCISS_GETPCIINFO:
		return cciss_getpciinfo(h, argp);
	case CCISS_GETINTINFO:
		return cciss_getintinfo(h, argp);
	case CCISS_SETINTINFO:
		return cciss_setintinfo(h, argp);
	case CCISS_GETNODENAME:
		return cciss_getnodename(h, argp);
	case CCISS_SETNODENAME:
		return cciss_setnodename(h, argp);
	case CCISS_GETHEARTBEAT:
		return cciss_getheartbeat(h, argp);
	case CCISS_GETBUSTYPES:
		return cciss_getbustypes(h, argp);
	case CCISS_GETFIRMVER:
		return cciss_getfirmver(h, argp);
	case CCISS_GETDRIVVER:
		return cciss_getdrivver(h, argp);
	case CCISS_DEREGDISK:
	case CCISS_REGNEWD:
	case CCISS_REVALIDVOLS:
		return rebuild_lun_table(h, 0, 1);
	case CCISS_GETLUNINFO:
		return cciss_getluninfo(h, disk, argp);
	case CCISS_PASSTHRU:
		return cciss_passthru(h, argp);
	case CCISS_BIG_PASSTHRU:
		return cciss_bigpassthru(h, argp);

	/* scsi_cmd_ioctl handles these, below, though some are not */
	/* scsi_cmd_ioctl handles these, below, though some are not */
	/* very meaningful for cciss.  SG_IO is the main one people want. */
	/* very meaningful for cciss.  SG_IO is the main one people want. */


+20 −21
Original line number Original line Diff line number Diff line
@@ -965,29 +965,30 @@ void __drbd_set_in_sync(struct drbd_conf *mdev, sector_t sector, int size,
	 * ok, (capacity & 7) != 0 sometimes, but who cares...
	 * ok, (capacity & 7) != 0 sometimes, but who cares...
	 * we count rs_{total,left} in bits, not sectors.
	 * we count rs_{total,left} in bits, not sectors.
	 */
	 */
	spin_lock_irqsave(&mdev->al_lock, flags);
	count = drbd_bm_clear_bits(mdev, sbnr, ebnr);
	count = drbd_bm_clear_bits(mdev, sbnr, ebnr);
	if (count) {
	if (count && get_ldev(mdev)) {
		/* we need the lock for drbd_try_clear_on_disk_bm */
		unsigned long now = jiffies;
		if (jiffies - mdev->rs_mark_time > HZ*10) {
		unsigned long last = mdev->rs_mark_time[mdev->rs_last_mark];
			/* should be rolling marks,
		int next = (mdev->rs_last_mark + 1) % DRBD_SYNC_MARKS;
			 * but we estimate only anyways. */
		if (time_after_eq(now, last + DRBD_SYNC_MARK_STEP)) {
			if (mdev->rs_mark_left != drbd_bm_total_weight(mdev) &&
			unsigned long tw = drbd_bm_total_weight(mdev);
			if (mdev->rs_mark_left[mdev->rs_last_mark] != tw &&
			    mdev->state.conn != C_PAUSED_SYNC_T &&
			    mdev->state.conn != C_PAUSED_SYNC_T &&
			    mdev->state.conn != C_PAUSED_SYNC_S) {
			    mdev->state.conn != C_PAUSED_SYNC_S) {
				mdev->rs_mark_time = jiffies;
				mdev->rs_mark_time[next] = now;
				mdev->rs_mark_left = drbd_bm_total_weight(mdev);
				mdev->rs_mark_left[next] = tw;
				mdev->rs_last_mark = next;
			}
			}
		}
		}
		if (get_ldev(mdev)) {
		spin_lock_irqsave(&mdev->al_lock, flags);
		drbd_try_clear_on_disk_bm(mdev, sector, count, TRUE);
		drbd_try_clear_on_disk_bm(mdev, sector, count, TRUE);
			put_ldev(mdev);
		spin_unlock_irqrestore(&mdev->al_lock, flags);
		}

		/* just wake_up unconditional now, various lc_chaged(),
		/* just wake_up unconditional now, various lc_chaged(),
		 * lc_put() in drbd_try_clear_on_disk_bm(). */
		 * lc_put() in drbd_try_clear_on_disk_bm(). */
		wake_up = 1;
		wake_up = 1;
		put_ldev(mdev);
	}
	}
	spin_unlock_irqrestore(&mdev->al_lock, flags);
	if (wake_up)
	if (wake_up)
		wake_up(&mdev->al_wait);
		wake_up(&mdev->al_wait);
}
}
@@ -1118,7 +1119,7 @@ static int _is_in_al(struct drbd_conf *mdev, unsigned int enr)
 * @mdev:	DRBD device.
 * @mdev:	DRBD device.
 * @sector:	The sector number.
 * @sector:	The sector number.
 *
 *
 * This functions sleeps on al_wait. Returns 1 on success, 0 if interrupted.
 * This functions sleeps on al_wait. Returns 0 on success, -EINTR if interrupted.
 */
 */
int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
{
{
@@ -1129,10 +1130,10 @@ int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
	sig = wait_event_interruptible(mdev->al_wait,
	sig = wait_event_interruptible(mdev->al_wait,
			(bm_ext = _bme_get(mdev, enr)));
			(bm_ext = _bme_get(mdev, enr)));
	if (sig)
	if (sig)
		return 0;
		return -EINTR;


	if (test_bit(BME_LOCKED, &bm_ext->flags))
	if (test_bit(BME_LOCKED, &bm_ext->flags))
		return 1;
		return 0;


	for (i = 0; i < AL_EXT_PER_BM_SECT; i++) {
	for (i = 0; i < AL_EXT_PER_BM_SECT; i++) {
		sig = wait_event_interruptible(mdev->al_wait,
		sig = wait_event_interruptible(mdev->al_wait,
@@ -1145,13 +1146,11 @@ int drbd_rs_begin_io(struct drbd_conf *mdev, sector_t sector)
				wake_up(&mdev->al_wait);
				wake_up(&mdev->al_wait);
			}
			}
			spin_unlock_irq(&mdev->al_lock);
			spin_unlock_irq(&mdev->al_lock);
			return 0;
			return -EINTR;
		}
		}
	}
	}

	set_bit(BME_LOCKED, &bm_ext->flags);
	set_bit(BME_LOCKED, &bm_ext->flags);

	return 0;
	return 1;
}
}


/**
/**
+1 −1
Original line number Original line Diff line number Diff line
@@ -569,7 +569,7 @@ int drbd_bm_resize(struct drbd_conf *mdev, sector_t capacity, int set_new_bits)
 *
 *
 * maybe bm_set should be atomic_t ?
 * maybe bm_set should be atomic_t ?
 */
 */
static unsigned long _drbd_bm_total_weight(struct drbd_conf *mdev)
unsigned long _drbd_bm_total_weight(struct drbd_conf *mdev)
{
{
	struct drbd_bitmap *b = mdev->bitmap;
	struct drbd_bitmap *b = mdev->bitmap;
	unsigned long s;
	unsigned long s;
Loading