patch-2.1.101 linux/drivers/block/swim3.c
Next file: linux/drivers/block/xd.c
Previous file: linux/drivers/block/raid5.c
Back to the patch index
Back to the overall index
- Lines: 284
- Date:
Fri May 8 18:12:30 1998
- Orig file:
v2.1.100/linux/drivers/block/swim3.c
- Orig date:
Sun Dec 21 17:41:24 1997
diff -u --recursive --new-file v2.1.100/linux/drivers/block/swim3.c linux/drivers/block/swim3.c
@@ -21,6 +21,7 @@
#include <asm/dbdma.h>
#include <asm/prom.h>
#include <asm/uaccess.h>
+#include <asm/mediabay.h>
#define MAJOR_NR FLOPPY_MAJOR
#include <linux/blk.h>
@@ -134,9 +135,11 @@
int ref_count;
int expect_cyl;
struct timer_list timeout;
+ int timeout_pending;
int ejected;
struct wait_queue *wait;
int wanted;
+ int in_media_bay;
char dbdma_cmd_space[5 * sizeof(struct dbdma_cmd)];
};
@@ -161,6 +164,8 @@
static int swim3_readbit(struct floppy_state *fs, int bit);
static void do_fd_request(void);
static void start_request(struct floppy_state *fs);
+static void set_timeout(struct floppy_state *fs, int nticks,
+ void (*proc)(unsigned long));
static void scan_track(struct floppy_state *fs);
static void seek_track(struct floppy_state *fs, int n);
static void init_dma(struct dbdma_cmd *cp, int cmd, void *buf, int count);
@@ -179,10 +184,10 @@
unsigned int cmd, unsigned long param);
static int floppy_open(struct inode *inode, struct file *filp);
static int floppy_release(struct inode *inode, struct file *filp);
-static long floppy_read(struct inode *inode, struct file *filp,
- char *buf, unsigned long count);
-static long floppy_write(struct inode *inode, struct file *filp,
- const char *buf, unsigned long count);
+static ssize_t floppy_read(struct file *filp, char *buf,
+ size_t count, loff_t *ppos);
+static ssize_t floppy_write(struct file *filp, const char *buf,
+ size_t count, loff_t *ppos);
static int floppy_check_change(kdev_t dev);
static int floppy_revalidate(kdev_t dev);
int swim3_init(void);
@@ -294,6 +299,22 @@
}
}
+static void set_timeout(struct floppy_state *fs, int nticks,
+ void (*proc)(unsigned long))
+{
+ unsigned long flags;
+
+ save_flags(flags); cli();
+ if (fs->timeout_pending)
+ del_timer(&fs->timeout);
+ fs->timeout.expires = jiffies + nticks;
+ fs->timeout.function = proc;
+ fs->timeout.data = (unsigned long) fs;
+ add_timer(&fs->timeout);
+ fs->timeout_pending = 1;
+ restore_flags(flags);
+}
+
static inline void scan_track(struct floppy_state *fs)
{
volatile struct swim3 *sw = fs->swim3;
@@ -304,11 +325,7 @@
out_8(&sw->control_bis, SCAN_TRACK);
/* enable intr when track found */
out_8(&sw->intr_enable, ERROR | SEEN_SECTOR);
- /* enable timeout */
- fs->timeout.expires = jiffies + HZ;
- fs->timeout.function = scan_timeout;
- fs->timeout.data = (unsigned long) fs;
- add_timer(&fs->timeout);
+ set_timeout(fs, HZ, scan_timeout); /* enable timeout */
}
static inline void seek_track(struct floppy_state *fs, int n)
@@ -327,11 +344,7 @@
out_8(&sw->control_bis, DO_SEEK);
/* enable intr when seek finished */
out_8(&sw->intr_enable, ERROR | SEEK_DONE);
- /* enable timeout */
- fs->timeout.expires = jiffies + HZ/2;
- fs->timeout.function = seek_timeout;
- fs->timeout.data = (unsigned long) fs;
- add_timer(&fs->timeout);
+ set_timeout(fs, HZ/2, seek_timeout); /* enable timeout */
}
static inline void init_dma(struct dbdma_cmd *cp, int cmd,
@@ -384,11 +397,7 @@
(CURRENT->cmd == WRITE? WRITE_SECTORS: 0) | SCAN_TRACK);
/* enable intr when transfer complete */
out_8(&sw->intr_enable, ERROR | TRANSFER_DONE);
- /* enable timeout */
- fs->timeout.expires = jiffies + 2*HZ;
- fs->timeout.function = xfer_timeout;
- fs->timeout.data = (unsigned long) fs;
- add_timer(&fs->timeout);
+ set_timeout(fs, 2*HZ, xfer_timeout); /* enable timeout */
}
static void act(struct floppy_state *fs)
@@ -434,10 +443,7 @@
in_8(&sw->intr); /* clear DATA_CHANGED */
if (in_8(&sw->status) & DATA) {
/* seek_complete is not yet true */
- fs->timeout.expires = jiffies + HZ/2;
- fs->timeout.function = seek_timeout;
- fs->timeout.data = (unsigned long) fs;
- add_timer(&fs->timeout);
+ set_timeout(fs, HZ/2, seek_timeout);
return;
}
out_8(&sw->intr_enable, 0);
@@ -474,6 +480,7 @@
struct floppy_state *fs = (struct floppy_state *) data;
volatile struct swim3 *sw = fs->swim3;
+ fs->timeout_pending = 0;
out_8(&sw->control_bic, SCAN_TRACK);
out_8(&sw->select, RELAX);
out_8(&sw->intr_enable, 0);
@@ -493,6 +500,7 @@
struct floppy_state *fs = (struct floppy_state *) data;
volatile struct swim3 *sw = fs->swim3;
+ fs->timeout_pending = 0;
if (fs->state == settling) {
printk(KERN_ERR "swim3: MSI sel=%x ctrl=%x stat=%x intr=%x ie=%x\n",
sw->select, sw->control, sw->status, sw->intr, sw->intr_enable);
@@ -520,6 +528,7 @@
struct dbdma_cmd *cp = fs->dma_cmd;
unsigned long s;
+ fs->timeout_pending = 0;
st_le32(&dr->control, RUN << 16);
out_8(&sw->intr_enable, 0);
out_8(&sw->control_bic, WRITE_SECTORS | SCAN_TRACK);
@@ -550,6 +559,9 @@
err = in_8(&sw->error);
intr = in_8(&sw->intr);
+#if 0
+ printk(KERN_DEBUG "swim3 intr state=%d intr=%x err=%x\n", fs->state, intr, err);
+#endif
if ((intr & ERROR) && fs->state != do_transfer)
printk(KERN_ERR "swim3_interrupt, state=%d, cmd=%x, intr=%x, err=%x\n",
fs->state, CURRENT->cmd, intr, err);
@@ -560,6 +572,7 @@
out_8(&sw->select, RELAX);
out_8(&sw->intr_enable, 0);
del_timer(&fs->timeout);
+ fs->timeout_pending = 0;
if (sw->ctrack == 0xff) {
printk(KERN_ERR "swim3: seen sector but cyl=ff?\n");
fs->cur_cyl = -1;
@@ -589,6 +602,7 @@
out_8(&sw->select, RELAX);
out_8(&sw->intr_enable, 0);
del_timer(&fs->timeout);
+ fs->timeout_pending = 0;
if (fs->state == seeking)
++fs->retries;
fs->state = settling;
@@ -598,6 +612,7 @@
case settling:
out_8(&sw->intr_enable, 0);
del_timer(&fs->timeout);
+ fs->timeout_pending = 0;
act(fs);
break;
case do_transfer:
@@ -610,6 +625,7 @@
out_8(&sw->control_bic, WRITE_SECTORS | SCAN_TRACK);
out_8(&sw->select, RELAX);
del_timer(&fs->timeout);
+ fs->timeout_pending = 0;
if (CURRENT->cmd == WRITE)
++cp;
stat = ld_le16(&cp->xfer_status);
@@ -772,6 +788,12 @@
sw = fs->swim3;
err = 0;
if (fs->ref_count == 0) {
+ if (fs->in_media_bay && !check_media_bay(MB_FD))
+ return -ENXIO;
+ out_8(&sw->mode, 0x95);
+ out_8(&sw->control_bic, 0xff);
+ out_8(&sw->reg5, 0x28);
+ udelay(1);
out_8(&sw->intr_enable, 0);
out_8(&sw->control_bis, DRIVE_ENABLE | INTR_ENABLE);
swim3_action(fs, MOTOR_ON);
@@ -905,9 +927,10 @@
return ret;
}
-static long floppy_read(struct inode *inode, struct file *filp,
- char *buf, unsigned long count)
+static ssize_t floppy_read(struct file *filp, char *buf,
+ size_t count, loff_t *ppos)
{
+ struct inode *inode = filp->f_dentry->d_inode;
struct floppy_state *fs;
if (MINOR(inode->i_rdev) != 0)
@@ -915,12 +938,13 @@
fs = &floppy_states[0];
if (fs->ejected)
return -ENXIO;
- return block_read(inode, filp, buf, count);
+ return block_read(filp, buf, count, ppos);
}
-static long floppy_write(struct inode *inode, struct file *filp,
- const char *buf, unsigned long count)
+static ssize_t floppy_write(struct file * filp, const char * buf,
+ size_t count, loff_t *ppos)
{
+ struct inode * inode = filp->f_dentry->d_inode;
struct floppy_state *fs;
if (MINOR(inode->i_rdev) != 0)
@@ -928,7 +952,7 @@
fs = &floppy_states[0];
if (fs->ejected)
return -ENXIO;
- return block_write(inode, filp, buf, count);
+ return block_write(filp, buf, count, ppos);
}
static void floppy_off(unsigned int nr)
@@ -955,9 +979,16 @@
{
struct device_node *swims;
struct floppy_state *fs = &floppy_states[0];
- volatile struct swim3 *sw;
+ int is_3400 = 0;
+
+ if (find_devices("media-bay") != NULL) {
+ /* assume this is a PB3400 */
+ swims = find_devices("floppy");
+ is_3400 = 1;
+ } else {
+ swims = find_devices("swim3");
+ }
- swims = find_devices("swim3");
if (swims == NULL)
return 0;
@@ -982,13 +1013,14 @@
fs->state = idle;
fs->swim3 = (volatile struct swim3 *) swims->addrs[0].address;
fs->dma = (struct dbdma_regs *) swims->addrs[1].address;
- fs->swim3_intr = swims->intrs[0];
- fs->dma_intr = swims->intrs[1];
+ fs->swim3_intr = swims->intrs[0].line;
+ fs->dma_intr = swims->intrs[1].line;
fs->cur_cyl = -1;
fs->cur_sector = -1;
fs->secpercyl = 36;
fs->secpertrack = 18;
fs->total_secs = 2880;
+ fs->in_media_bay = is_3400;
fs->dma_cmd = (struct dbdma_cmd *) DBDMA_ALIGN(fs->dbdma_cmd_space);
memset(fs->dma_cmd, 0, 2 * sizeof(struct dbdma_cmd));
@@ -1004,10 +1036,7 @@
return -EBUSY;
}
- sw = fs->swim3;
- out_8(&sw->mode, 0x95);
- out_8(&sw->control_bic, 0xff);
- out_8(&sw->reg5, 0x28);
+ init_timer(&fs->timeout);
do_floppy = NULL;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen, slshen@lbl.gov