Пример #1
0
static int floppy_locked_ioctl(struct block_device *bdev, fmode_t mode,
			unsigned int cmd, unsigned long param)
{
	struct floppy_state *fs = bdev->bd_disk->private_data;
	int err;
		
	if ((cmd & 0x80) && !capable(CAP_SYS_ADMIN))
		return -EPERM;

	if (fs->mdev->media_bay &&
	    check_media_bay(fs->mdev->media_bay) != MB_FD)
		return -ENXIO;

	switch (cmd) {
	case FDEJECT:
		if (fs->ref_count != 1)
			return -EBUSY;
		err = fd_eject(fs);
		return err;
	case FDGETPRM:
	        if (copy_to_user((void __user *) param, &floppy_type,
				 sizeof(struct floppy_struct)))
			return -EFAULT;
		return 0;
	}
	return -ENOTTY;
}
Пример #2
0
static void do_fd_request(struct request_queue * q)
{
	int i;

	for(i=0; i<floppy_count; i++) {
		struct floppy_state *fs = &floppy_states[i];
		if (fs->mdev->media_bay &&
		    check_media_bay(fs->mdev->media_bay) != MB_FD)
			continue;
		start_request(fs);
	}
}
Пример #3
0
static void do_fd_request(request_queue_t * q)
{
	int i;
	for(i=0;i<floppy_count;i++)
	{
		if (floppy_states[i].media_bay &&
			check_media_bay(floppy_states[i].media_bay, MB_FD))
			continue;
		start_request(&floppy_states[i]);
	}
	sti();
}
Пример #4
0
static void do_fd_request(request_queue_t * q)
{
	int i;
	for(i=0;i<floppy_count;i++)
	{
#ifdef CONFIG_PMAC_MEDIABAY
		if (floppy_states[i].media_bay &&
			check_media_bay(floppy_states[i].media_bay, MB_FD))
			continue;
#endif /* CONFIG_PMAC_MEDIABAY */
		start_request(&floppy_states[i]);
	}
}
Пример #5
0
static void pmac_ide_init_dev(ide_drive_t *drive)
{
	ide_hwif_t *hwif = drive->hwif;
	pmac_ide_hwif_t *pmif = dev_get_drvdata(hwif->gendev.parent);

	if (on_media_bay(pmif)) {
		if (check_media_bay(pmif->mdev->media_bay) == MB_CD) {
			drive->dev_flags &= ~IDE_DFLAG_NOPROBE;
			return;
		}
		drive->dev_flags |= IDE_DFLAG_NOPROBE;
	}
}
Пример #6
0
static int floppy_revalidate(struct gendisk *disk)
{
	struct floppy_state *fs = disk->private_data;
	struct swim3 __iomem *sw;
	int ret, n;

	if (fs->mdev->media_bay &&
	    check_media_bay(fs->mdev->media_bay) != MB_FD)
		return -ENXIO;

	sw = fs->swim3;
	grab_drive(fs, revalidating, 0);
	out_8(&sw->intr_enable, 0);
	out_8(&sw->control_bis, DRIVE_ENABLE);
	swim3_action(fs, MOTOR_ON);	/* necessary? */
	fs->write_prot = -1;
	fs->cur_cyl = -1;
	mdelay(1);
	for (n = HZ; n > 0; --n) {
		if (swim3_readbit(fs, SEEK_COMPLETE))
			break;
		if (signal_pending(current))
			break;
		swim3_select(fs, RELAX);
		schedule_timeout_interruptible(1);
	}
	ret = swim3_readbit(fs, SEEK_COMPLETE) == 0
		|| swim3_readbit(fs, DISK_IN) == 0;
	if (ret)
		swim3_action(fs, MOTOR_OFF);
	else {
		fs->ejected = 0;
		swim3_action(fs, SETMFM);
	}
	swim3_select(fs, RELAX);

	release_drive(fs);
	return ret;
}
Пример #7
0
static int floppy_open(struct block_device *bdev, fmode_t mode)
{
	struct floppy_state *fs = bdev->bd_disk->private_data;
	struct swim3 __iomem *sw = fs->swim3;
	int n, err = 0;

	if (fs->ref_count == 0) {
		if (fs->mdev->media_bay &&
		    check_media_bay(fs->mdev->media_bay) != MB_FD)
			return -ENXIO;
		out_8(&sw->setup, S_IBM_DRIVE | S_FCLK_DIV2);
		out_8(&sw->control_bic, 0xff);
		out_8(&sw->mode, 0x95);
		udelay(10);
		out_8(&sw->intr_enable, 0);
		out_8(&sw->control_bis, DRIVE_ENABLE | INTR_ENABLE);
		swim3_action(fs, MOTOR_ON);
		fs->write_prot = -1;
		fs->cur_cyl = -1;
		for (n = 0; n < 2 * HZ; ++n) {
			if (n >= HZ/30 && swim3_readbit(fs, SEEK_COMPLETE))
				break;
			if (signal_pending(current)) {
				err = -EINTR;
				break;
			}
			swim3_select(fs, RELAX);
			schedule_timeout_interruptible(1);
		}
		if (err == 0 && (swim3_readbit(fs, SEEK_COMPLETE) == 0
				 || swim3_readbit(fs, DISK_IN) == 0))
			err = -ENXIO;
		swim3_action(fs, SETMFM);
		swim3_select(fs, RELAX);

	} else if (fs->ref_count == -1 || mode & FMODE_EXCL)
		return -EBUSY;

	if (err == 0 && (mode & FMODE_NDELAY) == 0
	    && (mode & (FMODE_READ|FMODE_WRITE))) {
		check_disk_change(bdev);
		if (fs->ejected)
			err = -ENXIO;
	}

	if (err == 0 && (mode & FMODE_WRITE)) {
		if (fs->write_prot < 0)
			fs->write_prot = swim3_readbit(fs, WRITE_PROT);
		if (fs->write_prot)
			err = -EROFS;
	}

	if (err) {
		if (fs->ref_count == 0) {
			swim3_action(fs, MOTOR_OFF);
			out_8(&sw->control_bic, DRIVE_ENABLE | INTR_ENABLE);
			swim3_select(fs, RELAX);
		}
		return err;
	}

	if (mode & FMODE_EXCL)
		fs->ref_count = -1;
	else
		++fs->ref_count;

	return 0;
}
Пример #8
0
static void start_request(struct floppy_state *fs)
{
	struct request *req;
	unsigned long x;

	swim3_dbg("start request, initial state=%d\n", fs->state);

	if (fs->state == idle && fs->wanted) {
		fs->state = available;
		wake_up(&fs->wait);
		return;
	}
	while (fs->state == idle) {
		swim3_dbg("start request, idle loop, cur_req=%p\n", fs->cur_req);
		if (!fs->cur_req) {
			fs->cur_req = blk_fetch_request(disks[fs->index]->queue);
			swim3_dbg("  fetched request %p\n", fs->cur_req);
			if (!fs->cur_req)
				break;
		}
		req = fs->cur_req;

		if (fs->mdev->media_bay &&
		    check_media_bay(fs->mdev->media_bay) != MB_FD) {
			swim3_dbg("%s", "  media bay absent, dropping req\n");
			swim3_end_request(fs, BLK_STS_IOERR, 0);
			continue;
		}

#if 0 /* This is really too verbose */
		swim3_dbg("do_fd_req: dev=%s cmd=%d sec=%ld nr_sec=%u buf=%p\n",
			  req->rq_disk->disk_name, req->cmd,
			  (long)blk_rq_pos(req), blk_rq_sectors(req),
			  bio_data(req->bio));
		swim3_dbg("           current_nr_sectors=%u\n",
			  blk_rq_cur_sectors(req));
#endif

		if (blk_rq_pos(req) >= fs->total_secs) {
			swim3_dbg("  pos out of bounds (%ld, max is %ld)\n",
				  (long)blk_rq_pos(req), (long)fs->total_secs);
			swim3_end_request(fs, BLK_STS_IOERR, 0);
			continue;
		}
		if (fs->ejected) {
			swim3_dbg("%s", "  disk ejected\n");
			swim3_end_request(fs, BLK_STS_IOERR, 0);
			continue;
		}

		if (rq_data_dir(req) == WRITE) {
			if (fs->write_prot < 0)
				fs->write_prot = swim3_readbit(fs, WRITE_PROT);
			if (fs->write_prot) {
				swim3_dbg("%s", "  try to write, disk write protected\n");
				swim3_end_request(fs, BLK_STS_IOERR, 0);
				continue;
			}
		}

		/* Do not remove the cast. blk_rq_pos(req) is now a
		 * sector_t and can be 64 bits, but it will never go
		 * past 32 bits for this driver anyway, so we can
		 * safely cast it down and not have to do a 64/32
		 * division
		 */
		fs->req_cyl = ((long)blk_rq_pos(req)) / fs->secpercyl;
		x = ((long)blk_rq_pos(req)) % fs->secpercyl;
		fs->head = x / fs->secpertrack;
		fs->req_sector = x % fs->secpertrack + 1;
		fs->state = do_transfer;
		fs->retries = 0;

		act(fs);
	}
}
Пример #9
0
static int swim3_add_device(struct macio_dev *mdev, int index)
{
	struct device_node *swim = mdev->ofdev.dev.of_node;
	struct floppy_state *fs = &floppy_states[index];
	int rc = -EBUSY;

	/* Do this first for message macros */
	memset(fs, 0, sizeof(*fs));
	fs->mdev = mdev;
	fs->index = index;

	/* Check & Request resources */
	if (macio_resource_count(mdev) < 2) {
		swim3_err("%s", "No address in device-tree\n");
		return -ENXIO;
	}
	if (macio_irq_count(mdev) < 1) {
		swim3_err("%s", "No interrupt in device-tree\n");
		return -ENXIO;
	}
	if (macio_request_resource(mdev, 0, "swim3 (mmio)")) {
		swim3_err("%s", "Can't request mmio resource\n");
		return -EBUSY;
	}
	if (macio_request_resource(mdev, 1, "swim3 (dma)")) {
		swim3_err("%s", "Can't request dma resource\n");
		macio_release_resource(mdev, 0);
		return -EBUSY;
	}
	dev_set_drvdata(&mdev->ofdev.dev, fs);

	if (mdev->media_bay == NULL)
		pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 1);
	
	fs->state = idle;
	fs->swim3 = (struct swim3 __iomem *)
		ioremap(macio_resource_start(mdev, 0), 0x200);
	if (fs->swim3 == NULL) {
		swim3_err("%s", "Couldn't map mmio registers\n");
		rc = -ENOMEM;
		goto out_release;
	}
	fs->dma = (struct dbdma_regs __iomem *)
		ioremap(macio_resource_start(mdev, 1), 0x200);
	if (fs->dma == NULL) {
		swim3_err("%s", "Couldn't map dma registers\n");
		iounmap(fs->swim3);
		rc = -ENOMEM;
		goto out_release;
	}
	fs->swim3_intr = macio_irq(mdev, 0);
	fs->dma_intr = macio_irq(mdev, 1);
	fs->cur_cyl = -1;
	fs->cur_sector = -1;
	fs->secpercyl = 36;
	fs->secpertrack = 18;
	fs->total_secs = 2880;
	init_waitqueue_head(&fs->wait);

	fs->dma_cmd = (struct dbdma_cmd *) DBDMA_ALIGN(fs->dbdma_cmd_space);
	memset(fs->dma_cmd, 0, 2 * sizeof(struct dbdma_cmd));
	fs->dma_cmd[1].command = cpu_to_le16(DBDMA_STOP);

	if (mdev->media_bay == NULL || check_media_bay(mdev->media_bay) == MB_FD)
		swim3_mb_event(mdev, MB_FD);

	if (request_irq(fs->swim3_intr, swim3_interrupt, 0, "SWIM3", fs)) {
		swim3_err("%s", "Couldn't request interrupt\n");
		pmac_call_feature(PMAC_FTR_SWIM3_ENABLE, swim, 0, 0);
		goto out_unmap;
		return -EBUSY;
	}

	timer_setup(&fs->timeout, NULL, 0);

	swim3_info("SWIM3 floppy controller %s\n",
		mdev->media_bay ? "in media bay" : "");

	return 0;

 out_unmap:
	iounmap(fs->dma);
	iounmap(fs->swim3);

 out_release:
	macio_release_resource(mdev, 0);
	macio_release_resource(mdev, 1);

	return rc;
}