linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* PowerMac floppy (SWIM-3) doesn't compile
@ 2003-11-30  9:19 Sebastiaan
  0 siblings, 0 replies; 4+ messages in thread
From: Sebastiaan @ 2003-11-30  9:19 UTC (permalink / raw)
  To: linux-kernel

Hi,

I am trying to build the 2.6.0-test11 kernel for my PowerMac 7300/166, but
the floppy controller doesn't want to compile. I have:

CONFIG_MAC_FLOPPY=y

After a while 'make all' fails with:

  CC      drivers/block/swim3.o
drivers/block/swim3.c:224: parse error before `*'
drivers/block/swim3.c:224: warning: function declaration isn't a prototype
drivers/block/swim3.c:292: parse error before `*'
drivers/block/swim3.c:293: warning: function declaration isn't a prototype
drivers/block/swim3.c: In function `do_fd_request':
drivers/block/swim3.c:302: warning: implicit declaration of function `sti'
drivers/block/swim3.c: In function `start_request':
drivers/block/swim3.c:315: warning: implicit declaration of function `elv_next_request'
drivers/block/swim3.c:315: warning: assignment makes pointer from integer without a cast
drivers/block/swim3.c:324: dereferencing pointer to incomplete type
drivers/block/swim3.c:324: dereferencing pointer to incomplete type
drivers/block/swim3.c:325: warning: implicit declaration of function `end_request'
drivers/block/swim3.c:328: dereferencing pointer to incomplete type
drivers/block/swim3.c:337: warning: implicit declaration of function `rq_data_dir'
drivers/block/swim3.c:346: dereferencing pointer to incomplete type
drivers/block/swim3.c:347: dereferencing pointer to incomplete type
drivers/block/swim3.c: In function `set_timeout':
drivers/block/swim3.c:363: warning: implicit declaration of function `save_flags'
drivers/block/swim3.c:363: warning: implicit declaration of function `cli'
drivers/block/swim3.c:371: warning: implicit declaration of function `restore_flags'
drivers/block/swim3.c: In function `setup_transfer':
drivers/block/swim3.c:422: dereferencing pointer to incomplete type
drivers/block/swim3.c:430: dereferencing pointer to incomplete type
drivers/block/swim3.c:431: dereferencing pointer to incomplete type
drivers/block/swim3.c:443: dereferencing pointer to incomplete type
drivers/block/swim3.c:447: dereferencing pointer to incomplete type
drivers/block/swim3.c: In function `xfer_timeout':
drivers/block/swim3.c:598: dereferencing pointer to incomplete type
drivers/block/swim3.c:599: dereferencing pointer to incomplete type
drivers/block/swim3.c:601: dereferencing pointer to incomplete type
drivers/block/swim3.c: In function `swim3_interrupt':
drivers/block/swim3.c:623: warning: long unsigned int format, unsigned int arg (arg 3)
drivers/block/swim3.c:695: dereferencing pointer to incomplete type
drivers/block/swim3.c:696: dereferencing pointer to incomplete type
drivers/block/swim3.c:697: dereferencing pointer to incomplete type
drivers/block/swim3.c:706: dereferencing pointer to incomplete type
drivers/block/swim3.c:715: warning: long unsigned int format, unsigned int arg (arg 3)
drivers/block/swim3.c:721: dereferencing pointer to incomplete type
drivers/block/swim3.c:722: dereferencing pointer to incomplete type
drivers/block/swim3.c:723: dereferencing pointer to incomplete type
drivers/block/swim3.c:724: dereferencing pointer to incomplete type
drivers/block/swim3.c: In function `floppy_ioctl':
drivers/block/swim3.c:817: dereferencing pointer to incomplete type
drivers/block/swim3.c: In function `floppy_open':
drivers/block/swim3.c:843: dereferencing pointer to incomplete type
drivers/block/swim3.c: In function `floppy_release':
drivers/block/swim3.c:909: dereferencing pointer to incomplete type
drivers/block/swim3.c: In function `floppy_check_change':
drivers/block/swim3.c:920: dereferencing pointer to incomplete type
drivers/block/swim3.c: In function `floppy_revalidate':
drivers/block/swim3.c:926: dereferencing pointer to incomplete type
drivers/block/swim3.c: In function `swim3_init':
drivers/block/swim3.c:999: warning: implicit declaration of function `alloc_disk'
drivers/block/swim3.c:999: warning: assignment makes pointer from integer without a cast
drivers/block/swim3.c:1004: `FLOPPY_MAJOR' undeclared (first use in this function)
drivers/block/swim3.c:1004: (Each undeclared identifier is reported only once
drivers/block/swim3.c:1004: for each function it appears in.)
drivers/block/swim3.c:1009: warning: implicit declaration of function `blk_init_queue'
drivers/block/swim3.c:1009: warning: assignment makes pointer from integer without a cast
drivers/block/swim3.c:1017: dereferencing pointer to incomplete type
drivers/block/swim3.c:1018: dereferencing pointer to incomplete type
drivers/block/swim3.c:1019: dereferencing pointer to incomplete type
drivers/block/swim3.c:1020: dereferencing pointer to incomplete type
drivers/block/swim3.c:1021: dereferencing pointer to incomplete type
drivers/block/swim3.c:1022: dereferencing pointer to incomplete type
drivers/block/swim3.c:1023: dereferencing pointer to incomplete type
drivers/block/swim3.c:1024: warning: implicit declaration of function `set_capacity'
drivers/block/swim3.c:1025: warning: implicit declaration of function `add_disk'
drivers/block/swim3.c:1033: warning: implicit declaration of function `put_disk'
drivers/block/swim3.c: In function `swim3_add_device':
drivers/block/swim3.c:1084: warning: implicit declaration of function `request_irq'
drivers/block/swim3.c: At top level:
drivers/block/swim3.c:962: warning: `floppy_off' defined but not used
make[2]: *** [drivers/block/swim3.o] Error 1
make[1]: *** [drivers/block] Error 2
make: *** [drivers] Error 2


With my limiting knowledge about C and kernel sources I tried to locate
the error, but I haven't succeeded.

Setting CONFIG_MAC_FLOPPY=n will build the whole kernel.

Greetz,
Sebastiaan


--

English written by Dutch people is easily recognized by the improper use of 'In principle ...'

The software box said 'Requires Windows 95 or better', so I installed Linux.

Als Pacman in de jaren '80 de kinderen zo had be?nvloed zouden nu veel jongeren rondrennen
in donkere zalen terwijl ze pillen eten en luisteren naar monotone electronische muziek.
(Kristian Wilson, Nintendo, 1989)



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: PowerMac floppy (SWIM-3) doesn't compile
  2003-11-30 11:25 Mikael Pettersson
  2003-11-30 13:35 ` Sebastiaan
@ 2003-12-01  0:11 ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 4+ messages in thread
From: Benjamin Herrenschmidt @ 2003-12-01  0:11 UTC (permalink / raw)
  To: Mikael Pettersson; +Cc: S.Breedveld, Linux Kernel list

On Sun, 2003-11-30 at 22:25, Mikael Pettersson wrote:
> On Sun, 30 Nov 2003 10:19:07 +0100 (MET), Sebastiaan <S.Breedveld@ewi.tudelft.nl> wrote:
> >I am trying to build the 2.6.0-test11 kernel for my PowerMac 7300/166, but
> >the floppy controller doesn't want to compile. I have:
> 
> Known problem. Has been reported several times, but the PPC
> maintainers haven't bothered merging the fix yet.

The maintainer did bother, but along with a bunch of other PPC
driver updates, the fix is on hold until after 2.6.0. Code
freeze...

Also, the swim3 drivers, even with that fix, isn't in a very
good shape. It needs to be cleaned up and ported to the new
driver model.

> I'm using the patch below since the 2.5.7x kernels.
> (Paul Mackerras' 2.4 swim3 rework forward-ported to 2.5 by me.)
> There's also an "official" powermac tree somewhere which
> includes some swim3 patch, but I don't know if it's the same
> as this one.

Please test and let me know. It's at
bk://ppc.bkbits.net/linuxppc-2.5-benh or rsync from
source.mvista.com::linuxppc-2.5-benh.

> As for the boot problem you reported, please try a newer gcc
> like 3.2.3 or 3.3.2. I had lots of wierd problems with 2.95.3
> and the 2.4 kernels on ppc before I switched to gcc-3.x.x.
> 
> 2.6.0-test11 works just fine on my PM4400.
> 
> /Mikael
> 
> diff -ruN linux-2.6.0-test11/drivers/block/swim3.c linux-2.6.0-test11.swim3-fixes/drivers/block/swim3.c
> --- linux-2.6.0-test11/drivers/block/swim3.c	2003-08-09 11:54:06.000000000 +0200
> +++ linux-2.6.0-test11.swim3-fixes/drivers/block/swim3.c	2003-11-26 23:50:36.000000000 +0100
> @@ -24,7 +24,10 @@
>  #include <linux/delay.h>
>  #include <linux/fd.h>
>  #include <linux/ioctl.h>
> +#include <linux/blkdev.h>
>  #include <linux/devfs_fs_kernel.h>
> +#include <linux/interrupt.h>
> +#include <linux/module.h>
>  #include <asm/io.h>
>  #include <asm/dbdma.h>
>  #include <asm/prom.h>
> @@ -144,7 +147,7 @@
>  #define RELAX		3	/* also eject in progress */
>  #define READ_DATA_0	4
>  #define TWOMEG_DRIVE	5
> -#define SINGLE_SIDED	6
> +#define SINGLE_SIDED	6	/* drive or diskette is 4MB type? */
>  #define DRIVE_PRESENT	7
>  #define DISK_IN		8
>  #define WRITE_PROT	9
> @@ -184,6 +187,7 @@
>  	int	req_sector;	/* sector number ditto */
>  	int	scount;		/* # sectors we're transferring at present */
>  	int	retries;
> +	int	settle_time;
>  	int	secpercyl;	/* disk geometry information */
>  	int	secpertrack;
>  	int	total_secs;
> @@ -232,8 +236,9 @@
>  static void act(struct floppy_state *fs);
>  static void scan_timeout(unsigned long data);
>  static void seek_timeout(unsigned long data);
> +static void settle_timeout(unsigned long data);
>  static void xfer_timeout(unsigned long data);
> -static void swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
> +static irqreturn_t swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
>  /*static void fd_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs);*/
>  static int grab_drive(struct floppy_state *fs, enum swim_state state,
>  		      int interruptible);
> @@ -274,7 +279,6 @@
>  	udelay(2);
>  	out_8(&sw->select, sw->select & ~LSTRB);
>  	udelay(1);
> -	out_8(&sw->select, RELAX);
>  }
>  
>  static int swim3_readbit(struct floppy_state *fs, int bit)
> @@ -283,9 +287,8 @@
>  	int stat;
>  
>  	swim3_select(fs, bit);
> -	udelay(10);
> +	udelay(1);
>  	stat = in_8(&sw->status);
> -	out_8(&sw->select, RELAX);
>  	return (stat & DATA) == 0;
>  }
>  
> @@ -374,13 +377,13 @@
>  static inline void scan_track(struct floppy_state *fs)
>  {
>  	volatile struct swim3 *sw = fs->swim3;
> -	int xx;
>  
>  	swim3_select(fs, READ_DATA_0);
> -	xx = sw->intr;		/* clear SEEN_SECTOR bit */
> +	in_8(&sw->intr);		/* clear SEEN_SECTOR bit */
> +	in_8(&sw->error);
> +	out_8(&sw->intr_enable, SEEN_SECTOR);
>  	out_8(&sw->control_bis, DO_ACTION);
>  	/* enable intr when track found */
> -	out_8(&sw->intr_enable, ERROR_INTR | SEEN_SECTOR);
>  	set_timeout(fs, HZ, scan_timeout);	/* enable timeout */
>  }
>  
> @@ -395,12 +398,14 @@
>  		swim3_action(fs, SEEK_NEGATIVE);
>  		sw->nseek = -n;
>  	}
> -	fs->expect_cyl = (fs->cur_cyl > 0)? fs->cur_cyl + n: -1;
> +	fs->expect_cyl = (fs->cur_cyl >= 0)? fs->cur_cyl + n: -1;
>  	swim3_select(fs, STEP);
> -	out_8(&sw->control_bis, DO_SEEK);
> +	in_8(&sw->error);
>  	/* enable intr when seek finished */
> -	out_8(&sw->intr_enable, ERROR_INTR | SEEK_DONE);
> -	set_timeout(fs, HZ/2, seek_timeout);	/* enable timeout */
> +	out_8(&sw->intr_enable, SEEK_DONE);
> +	out_8(&sw->control_bis, DO_SEEK);
> +	set_timeout(fs, 3*HZ, seek_timeout);	/* enable timeout */
> +	fs->settle_time = 0;
>  }
>  
>  static inline void init_dma(struct dbdma_cmd *cp, int cmd,
> @@ -448,18 +453,21 @@
>  	}
>  	++cp;
>  	out_le16(&cp->command, DBDMA_STOP);
> +	out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
> +	in_8(&sw->error);
> +	out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
> +	if (rq_data_dir(fd_req) == WRITE)
> +		out_8(&sw->control_bis, WRITE_SECTORS);
> +	in_8(&sw->intr);
>  	out_le32(&dr->control, (RUN << 16) | RUN);
> -	out_8(&sw->control_bis,
> -	      (rq_data_dir(fd_req) == WRITE? WRITE_SECTORS: 0) | DO_ACTION);
>  	/* enable intr when transfer complete */
> -	out_8(&sw->intr_enable, ERROR_INTR | TRANSFER_DONE);
> +	out_8(&sw->intr_enable, TRANSFER_DONE);
> +	out_8(&sw->control_bis, DO_ACTION);
>  	set_timeout(fs, 2*HZ, xfer_timeout);	/* enable timeout */
>  }
>  
>  static void act(struct floppy_state *fs)
>  {
> -	volatile struct swim3 *sw = fs->swim3;
> -
>  	for (;;) {
>  		switch (fs->state) {
>  		case idle:
> @@ -492,20 +500,10 @@
>  			return;
>  
>  		case settling:
> -			/* wait for SEEK_COMPLETE to become true */
> -			swim3_select(fs, SEEK_COMPLETE);
> -			udelay(10);
> -			out_8(&sw->intr_enable, ERROR_INTR | DATA_CHANGED);
> -			in_8(&sw->intr);	/* clear DATA_CHANGED */
> -			if (in_8(&sw->status) & DATA) {
> -				/* seek_complete is not yet true */
> -				set_timeout(fs, HZ/2, seek_timeout);
> -				return;
> -			}
> -			out_8(&sw->intr_enable, 0);
> -			in_8(&sw->intr);
> -			fs->state = locating;
> -			break;
> +			/* check for SEEK_COMPLETE after 30ms */
> +			fs->settle_time = (HZ + 32) / 33;
> +			set_timeout(fs, fs->settle_time, settle_timeout);
> +			return;
>  
>  		case do_transfer:
>  			if (fs->cur_cyl != fs->req_cyl) {
> @@ -537,7 +535,7 @@
>  	volatile struct swim3 *sw = fs->swim3;
>  
>  	fs->timeout_pending = 0;
> -	out_8(&sw->control_bic, DO_ACTION);
> +	out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
>  	out_8(&sw->select, RELAX);
>  	out_8(&sw->intr_enable, 0);
>  	fs->cur_cyl = -1;
> @@ -557,20 +555,34 @@
>  	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);
> -	}
>  	out_8(&sw->control_bic, DO_SEEK);
>  	out_8(&sw->select, RELAX);
>  	out_8(&sw->intr_enable, 0);
> -	if (fs->state == settling && swim3_readbit(fs, SEEK_COMPLETE)) {
> -		/* printk(KERN_DEBUG "swim3: missed settling interrupt\n"); */
> +	printk(KERN_ERR "swim3: seek timeout\n");
> +	end_request(fd_req, 0);
> +	fs->state = idle;
> +	start_request(fs);
> +}
> +
> +static void settle_timeout(unsigned long data)
> +{
> +	struct floppy_state *fs = (struct floppy_state *) data;
> +	volatile struct swim3 *sw = fs->swim3;
> +
> +	fs->timeout_pending = 0;
> +	if (swim3_readbit(fs, SEEK_COMPLETE)) {
> +		out_8(&sw->select, RELAX);
>  		fs->state = locating;
>  		act(fs);
>  		return;
>  	}
> -	printk(KERN_ERR "swim3: seek timeout\n");
> +	out_8(&sw->select, RELAX);
> +	if (fs->settle_time < 2*HZ) {
> +		++fs->settle_time;
> +		set_timeout(fs, 1, settle_timeout);
> +		return;
> +	}
> +	printk(KERN_ERR "swim3: seek settle timeout\n");
>  	end_request(fd_req, 0);
>  	fs->state = idle;
>  	start_request(fs);
> @@ -583,9 +595,13 @@
>  	struct dbdma_regs *dr = fs->dma;
>  	struct dbdma_cmd *cp = fs->dma_cmd;
>  	unsigned long s;
> +	int n;
>  
>  	fs->timeout_pending = 0;
>  	st_le32(&dr->control, RUN << 16);
> +	/* We must wait a bit for dbdma to stop */
> +	for (n = 0; (in_le32(&dr->status) & ACTIVE) && n < 1000; n++)
> +		udelay(1);
>  	out_8(&sw->intr_enable, 0);
>  	out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION);
>  	out_8(&sw->select, RELAX);
> @@ -604,7 +620,7 @@
>  	start_request(fs);
>  }
>  
> -static void swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
> +static irqreturn_t swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
>  {
>  	struct floppy_state *fs = (struct floppy_state *) dev_id;
>  	volatile struct swim3 *sw = fs->swim3;
> @@ -613,18 +629,15 @@
>  	struct dbdma_regs *dr;
>  	struct dbdma_cmd *cp;
>  
> -	err = in_8(&sw->error);
>  	intr = in_8(&sw->intr);
> -#if 0
> -	printk("swim3 intr state=%d intr=%x err=%x\n", fs->state, intr, err);
> -#endif
> +	err = (intr & ERROR_INTR)? in_8(&sw->error): 0;
>  	if ((intr & ERROR_INTR) && fs->state != do_transfer)
>  		printk(KERN_ERR "swim3_interrupt, state=%d, dir=%lx, intr=%x, err=%x\n",
>  		       fs->state, rq_data_dir(fd_req), intr, err);
>  	switch (fs->state) {
>  	case locating:
>  		if (intr & SEEN_SECTOR) {
> -			out_8(&sw->control_bic, DO_ACTION);
> +			out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
>  			out_8(&sw->select, RELAX);
>  			out_8(&sw->intr_enable, 0);
>  			del_timer(&fs->timeout);
> @@ -674,19 +687,33 @@
>  	case do_transfer:
>  		if ((intr & (ERROR_INTR | TRANSFER_DONE)) == 0)
>  			break;
> -		dr = fs->dma;
> -		cp = fs->dma_cmd;
> -		/* We must wait a bit for dbdma to complete */
> -		for (n=0; (in_le32(&dr->status) & ACTIVE) && n < 1000; n++)
> -			udelay(10);
> -		DBDMA_DO_STOP(dr);
>  		out_8(&sw->intr_enable, 0);
>  		out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION);
>  		out_8(&sw->select, RELAX);
>  		del_timer(&fs->timeout);
>  		fs->timeout_pending = 0;
> +		dr = fs->dma;
> +		cp = fs->dma_cmd;
>  		if (rq_data_dir(fd_req) == WRITE)
>  			++cp;
> +		/*
> +		 * Check that the main data transfer has finished.
> +		 * On writing, the swim3 sometimes doesn't use
> +		 * up all the bytes of the postamble, so we can still
> +		 * see DMA active here.  That doesn't matter as long
> +		 * as all the sector data has been transferred.
> +		 */
> +		if ((intr & ERROR_INTR) == 0 && cp->xfer_status == 0) {
> +			/* wait a little while for DMA to complete */
> +			for (n = 0; n < 100; ++n) {
> +				if (cp->xfer_status != 0)
> +					break;
> +				udelay(1);
> +				barrier();
> +			}
> +		}
> +		/* turn off DMA */
> +		out_le32(&dr->control, (RUN | PAUSE) << 16);
>  		stat = ld_le16(&cp->xfer_status);
>  		resid = ld_le16(&cp->res_count);
>  		if (intr & ERROR_INTR) {
> @@ -742,6 +769,7 @@
>  	default:
>  		printk(KERN_ERR "swim3: don't know what to do in state %d\n", fs->state);
>  	}
> +	return IRQ_HANDLED;
>  }
>  
>  /*
> @@ -793,16 +821,19 @@
>  	if (err)
>  		return err;
>  	swim3_action(fs, EJECT);
> -	for (n = 2*HZ; n > 0; --n) {
> -		if (swim3_readbit(fs, RELAX))
> -			break;
> +	for (n = 20; n > 0; --n) {
>  		if (signal_pending(current)) {
>  			err = -EINTR;
>  			break;
>  		}
> +		swim3_select(fs, RELAX);
>  		current->state = TASK_INTERRUPTIBLE;
>  		schedule_timeout(1);
> +		if (swim3_readbit(fs, DISK_IN) == 0)
> +			break;
>  	}
> +	swim3_select(fs, RELAX);
> +	udelay(150);
>  	fs->ejected = 1;
>  	release_drive(fs);
>  	return err;
> @@ -847,29 +878,31 @@
>  	if (fs->ref_count == 0) {
>  		if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD))
>  			return -ENXIO;
> -		out_8(&sw->mode, 0x95);
> -		out_8(&sw->control_bic, 0xff);
>  		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 = HZ; n > 0; --n) {
> -			if (swim3_readbit(fs, SEEK_COMPLETE))
> +		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);
>  			current->state = TASK_INTERRUPTIBLE;
>  			schedule_timeout(1);
>  		}
>  		if (err == 0 && (swim3_readbit(fs, SEEK_COMPLETE) == 0
>  				 || swim3_readbit(fs, DISK_IN) == 0))
>  			err = -ENXIO;
> -		swim3_action(fs, 9);
> +		swim3_action(fs, SETMFM);
> +		swim3_select(fs, RELAX);
>  
>  	} else if (fs->ref_count == -1 || filp->f_flags & O_EXCL)
>  		return -EBUSY;
> @@ -892,6 +925,7 @@
>  		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;
>  	}
> @@ -911,6 +945,7 @@
>  	if (fs->ref_count > 0 && --fs->ref_count == 0) {
>  		swim3_action(fs, MOTOR_OFF);
>  		out_8(&sw->control_bic, 0xff);
> +		swim3_select(fs, RELAX);
>  	}
>  	return 0;
>  }
> @@ -933,15 +968,17 @@
>  	sw = fs->swim3;
>  	grab_drive(fs, revalidating, 0);
>  	out_8(&sw->intr_enable, 0);
> -	out_8(&sw->control_bis, DRIVE_ENABLE | INTR_ENABLE);
> -	swim3_action(fs, MOTOR_ON);
> +	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);
>  		current->state = TASK_INTERRUPTIBLE;
>  		schedule_timeout(1);
>  	}
> @@ -951,17 +988,14 @@
>  		swim3_action(fs, MOTOR_OFF);
>  	else {
>  		fs->ejected = 0;
> -		swim3_action(fs, 9);
> +		swim3_action(fs, SETMFM);
>  	}
> +	swim3_select(fs, RELAX);
>  
>  	release_drive(fs);
>  	return ret;
>  }
>  
> -static void floppy_off(unsigned int nr)
> -{
> -}
> -
>  static struct block_device_operations floppy_fops = {
>  	.open		= floppy_open,
>  	.release	= floppy_release,
> @@ -1104,3 +1138,5 @@
>  	
>  	return 0;
>  }
> +
> +module_init(swim3_init)
> -
> To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html
> Please read the FAQ at  http://www.tux.org/lkml/
-- 
Benjamin Herrenschmidt <benh@kernel.crashing.org>


^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: PowerMac floppy (SWIM-3) doesn't compile
  2003-11-30 11:25 Mikael Pettersson
@ 2003-11-30 13:35 ` Sebastiaan
  2003-12-01  0:11 ` Benjamin Herrenschmidt
  1 sibling, 0 replies; 4+ messages in thread
From: Sebastiaan @ 2003-11-30 13:35 UTC (permalink / raw)
  To: Mikael Pettersson; +Cc: S.Breedveld, linux-kernel

Hi,

On Sun, 30 Nov 2003, Mikael Pettersson wrote:

> On Sun, 30 Nov 2003 10:19:07 +0100 (MET), Sebastiaan <S.Breedveld@ewi.tudelft.nl> wrote:
> >I am trying to build the 2.6.0-test11 kernel for my PowerMac 7300/166, but
> >the floppy controller doesn't want to compile. I have:
>
> Known problem. Has been reported several times, but the PPC
> maintainers haven't bothered merging the fix yet.
>
> I'm using the patch below since the 2.5.7x kernels.
> (Paul Mackerras' 2.4 swim3 rework forward-ported to 2.5 by me.)
> There's also an "official" powermac tree somewhere which
> includes some swim3 patch, but I don't know if it's the same
> as this one.
>
Thanks, the patch works fine :).

> As for the boot problem you reported, please try a newer gcc
> like 3.2.3 or 3.3.2. I had lots of wierd problems with 2.95.3
> and the 2.4 kernels on ppc before I switched to gcc-3.x.x.
>
I have upgraded to 3.3.2 but the problem remains.

Thanks,
Sebastiaan


--

English written by Dutch people is easily recognized by the improper use of 'In principle ...'

The software box said 'Requires Windows 95 or better', so I installed Linux.

Als Pacman in de jaren '80 de kinderen zo had be?nvloed zouden nu veel jongeren rondrennen
in donkere zalen terwijl ze pillen eten en luisteren naar monotone electronische muziek.
(Kristian Wilson, Nintendo, 1989)



^ permalink raw reply	[flat|nested] 4+ messages in thread

* Re: PowerMac floppy (SWIM-3) doesn't compile
@ 2003-11-30 11:25 Mikael Pettersson
  2003-11-30 13:35 ` Sebastiaan
  2003-12-01  0:11 ` Benjamin Herrenschmidt
  0 siblings, 2 replies; 4+ messages in thread
From: Mikael Pettersson @ 2003-11-30 11:25 UTC (permalink / raw)
  To: S.Breedveld, linux-kernel

On Sun, 30 Nov 2003 10:19:07 +0100 (MET), Sebastiaan <S.Breedveld@ewi.tudelft.nl> wrote:
>I am trying to build the 2.6.0-test11 kernel for my PowerMac 7300/166, but
>the floppy controller doesn't want to compile. I have:

Known problem. Has been reported several times, but the PPC
maintainers haven't bothered merging the fix yet.

I'm using the patch below since the 2.5.7x kernels.
(Paul Mackerras' 2.4 swim3 rework forward-ported to 2.5 by me.)
There's also an "official" powermac tree somewhere which
includes some swim3 patch, but I don't know if it's the same
as this one.

As for the boot problem you reported, please try a newer gcc
like 3.2.3 or 3.3.2. I had lots of wierd problems with 2.95.3
and the 2.4 kernels on ppc before I switched to gcc-3.x.x.

2.6.0-test11 works just fine on my PM4400.

/Mikael

diff -ruN linux-2.6.0-test11/drivers/block/swim3.c linux-2.6.0-test11.swim3-fixes/drivers/block/swim3.c
--- linux-2.6.0-test11/drivers/block/swim3.c	2003-08-09 11:54:06.000000000 +0200
+++ linux-2.6.0-test11.swim3-fixes/drivers/block/swim3.c	2003-11-26 23:50:36.000000000 +0100
@@ -24,7 +24,10 @@
 #include <linux/delay.h>
 #include <linux/fd.h>
 #include <linux/ioctl.h>
+#include <linux/blkdev.h>
 #include <linux/devfs_fs_kernel.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
 #include <asm/io.h>
 #include <asm/dbdma.h>
 #include <asm/prom.h>
@@ -144,7 +147,7 @@
 #define RELAX		3	/* also eject in progress */
 #define READ_DATA_0	4
 #define TWOMEG_DRIVE	5
-#define SINGLE_SIDED	6
+#define SINGLE_SIDED	6	/* drive or diskette is 4MB type? */
 #define DRIVE_PRESENT	7
 #define DISK_IN		8
 #define WRITE_PROT	9
@@ -184,6 +187,7 @@
 	int	req_sector;	/* sector number ditto */
 	int	scount;		/* # sectors we're transferring at present */
 	int	retries;
+	int	settle_time;
 	int	secpercyl;	/* disk geometry information */
 	int	secpertrack;
 	int	total_secs;
@@ -232,8 +236,9 @@
 static void act(struct floppy_state *fs);
 static void scan_timeout(unsigned long data);
 static void seek_timeout(unsigned long data);
+static void settle_timeout(unsigned long data);
 static void xfer_timeout(unsigned long data);
-static void swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 /*static void fd_dma_interrupt(int irq, void *dev_id, struct pt_regs *regs);*/
 static int grab_drive(struct floppy_state *fs, enum swim_state state,
 		      int interruptible);
@@ -274,7 +279,6 @@
 	udelay(2);
 	out_8(&sw->select, sw->select & ~LSTRB);
 	udelay(1);
-	out_8(&sw->select, RELAX);
 }
 
 static int swim3_readbit(struct floppy_state *fs, int bit)
@@ -283,9 +287,8 @@
 	int stat;
 
 	swim3_select(fs, bit);
-	udelay(10);
+	udelay(1);
 	stat = in_8(&sw->status);
-	out_8(&sw->select, RELAX);
 	return (stat & DATA) == 0;
 }
 
@@ -374,13 +377,13 @@
 static inline void scan_track(struct floppy_state *fs)
 {
 	volatile struct swim3 *sw = fs->swim3;
-	int xx;
 
 	swim3_select(fs, READ_DATA_0);
-	xx = sw->intr;		/* clear SEEN_SECTOR bit */
+	in_8(&sw->intr);		/* clear SEEN_SECTOR bit */
+	in_8(&sw->error);
+	out_8(&sw->intr_enable, SEEN_SECTOR);
 	out_8(&sw->control_bis, DO_ACTION);
 	/* enable intr when track found */
-	out_8(&sw->intr_enable, ERROR_INTR | SEEN_SECTOR);
 	set_timeout(fs, HZ, scan_timeout);	/* enable timeout */
 }
 
@@ -395,12 +398,14 @@
 		swim3_action(fs, SEEK_NEGATIVE);
 		sw->nseek = -n;
 	}
-	fs->expect_cyl = (fs->cur_cyl > 0)? fs->cur_cyl + n: -1;
+	fs->expect_cyl = (fs->cur_cyl >= 0)? fs->cur_cyl + n: -1;
 	swim3_select(fs, STEP);
-	out_8(&sw->control_bis, DO_SEEK);
+	in_8(&sw->error);
 	/* enable intr when seek finished */
-	out_8(&sw->intr_enable, ERROR_INTR | SEEK_DONE);
-	set_timeout(fs, HZ/2, seek_timeout);	/* enable timeout */
+	out_8(&sw->intr_enable, SEEK_DONE);
+	out_8(&sw->control_bis, DO_SEEK);
+	set_timeout(fs, 3*HZ, seek_timeout);	/* enable timeout */
+	fs->settle_time = 0;
 }
 
 static inline void init_dma(struct dbdma_cmd *cp, int cmd,
@@ -448,18 +453,21 @@
 	}
 	++cp;
 	out_le16(&cp->command, DBDMA_STOP);
+	out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
+	in_8(&sw->error);
+	out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
+	if (rq_data_dir(fd_req) == WRITE)
+		out_8(&sw->control_bis, WRITE_SECTORS);
+	in_8(&sw->intr);
 	out_le32(&dr->control, (RUN << 16) | RUN);
-	out_8(&sw->control_bis,
-	      (rq_data_dir(fd_req) == WRITE? WRITE_SECTORS: 0) | DO_ACTION);
 	/* enable intr when transfer complete */
-	out_8(&sw->intr_enable, ERROR_INTR | TRANSFER_DONE);
+	out_8(&sw->intr_enable, TRANSFER_DONE);
+	out_8(&sw->control_bis, DO_ACTION);
 	set_timeout(fs, 2*HZ, xfer_timeout);	/* enable timeout */
 }
 
 static void act(struct floppy_state *fs)
 {
-	volatile struct swim3 *sw = fs->swim3;
-
 	for (;;) {
 		switch (fs->state) {
 		case idle:
@@ -492,20 +500,10 @@
 			return;
 
 		case settling:
-			/* wait for SEEK_COMPLETE to become true */
-			swim3_select(fs, SEEK_COMPLETE);
-			udelay(10);
-			out_8(&sw->intr_enable, ERROR_INTR | DATA_CHANGED);
-			in_8(&sw->intr);	/* clear DATA_CHANGED */
-			if (in_8(&sw->status) & DATA) {
-				/* seek_complete is not yet true */
-				set_timeout(fs, HZ/2, seek_timeout);
-				return;
-			}
-			out_8(&sw->intr_enable, 0);
-			in_8(&sw->intr);
-			fs->state = locating;
-			break;
+			/* check for SEEK_COMPLETE after 30ms */
+			fs->settle_time = (HZ + 32) / 33;
+			set_timeout(fs, fs->settle_time, settle_timeout);
+			return;
 
 		case do_transfer:
 			if (fs->cur_cyl != fs->req_cyl) {
@@ -537,7 +535,7 @@
 	volatile struct swim3 *sw = fs->swim3;
 
 	fs->timeout_pending = 0;
-	out_8(&sw->control_bic, DO_ACTION);
+	out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
 	out_8(&sw->select, RELAX);
 	out_8(&sw->intr_enable, 0);
 	fs->cur_cyl = -1;
@@ -557,20 +555,34 @@
 	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);
-	}
 	out_8(&sw->control_bic, DO_SEEK);
 	out_8(&sw->select, RELAX);
 	out_8(&sw->intr_enable, 0);
-	if (fs->state == settling && swim3_readbit(fs, SEEK_COMPLETE)) {
-		/* printk(KERN_DEBUG "swim3: missed settling interrupt\n"); */
+	printk(KERN_ERR "swim3: seek timeout\n");
+	end_request(fd_req, 0);
+	fs->state = idle;
+	start_request(fs);
+}
+
+static void settle_timeout(unsigned long data)
+{
+	struct floppy_state *fs = (struct floppy_state *) data;
+	volatile struct swim3 *sw = fs->swim3;
+
+	fs->timeout_pending = 0;
+	if (swim3_readbit(fs, SEEK_COMPLETE)) {
+		out_8(&sw->select, RELAX);
 		fs->state = locating;
 		act(fs);
 		return;
 	}
-	printk(KERN_ERR "swim3: seek timeout\n");
+	out_8(&sw->select, RELAX);
+	if (fs->settle_time < 2*HZ) {
+		++fs->settle_time;
+		set_timeout(fs, 1, settle_timeout);
+		return;
+	}
+	printk(KERN_ERR "swim3: seek settle timeout\n");
 	end_request(fd_req, 0);
 	fs->state = idle;
 	start_request(fs);
@@ -583,9 +595,13 @@
 	struct dbdma_regs *dr = fs->dma;
 	struct dbdma_cmd *cp = fs->dma_cmd;
 	unsigned long s;
+	int n;
 
 	fs->timeout_pending = 0;
 	st_le32(&dr->control, RUN << 16);
+	/* We must wait a bit for dbdma to stop */
+	for (n = 0; (in_le32(&dr->status) & ACTIVE) && n < 1000; n++)
+		udelay(1);
 	out_8(&sw->intr_enable, 0);
 	out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION);
 	out_8(&sw->select, RELAX);
@@ -604,7 +620,7 @@
 	start_request(fs);
 }
 
-static void swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+static irqreturn_t swim3_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct floppy_state *fs = (struct floppy_state *) dev_id;
 	volatile struct swim3 *sw = fs->swim3;
@@ -613,18 +629,15 @@
 	struct dbdma_regs *dr;
 	struct dbdma_cmd *cp;
 
-	err = in_8(&sw->error);
 	intr = in_8(&sw->intr);
-#if 0
-	printk("swim3 intr state=%d intr=%x err=%x\n", fs->state, intr, err);
-#endif
+	err = (intr & ERROR_INTR)? in_8(&sw->error): 0;
 	if ((intr & ERROR_INTR) && fs->state != do_transfer)
 		printk(KERN_ERR "swim3_interrupt, state=%d, dir=%lx, intr=%x, err=%x\n",
 		       fs->state, rq_data_dir(fd_req), intr, err);
 	switch (fs->state) {
 	case locating:
 		if (intr & SEEN_SECTOR) {
-			out_8(&sw->control_bic, DO_ACTION);
+			out_8(&sw->control_bic, DO_ACTION | WRITE_SECTORS);
 			out_8(&sw->select, RELAX);
 			out_8(&sw->intr_enable, 0);
 			del_timer(&fs->timeout);
@@ -674,19 +687,33 @@
 	case do_transfer:
 		if ((intr & (ERROR_INTR | TRANSFER_DONE)) == 0)
 			break;
-		dr = fs->dma;
-		cp = fs->dma_cmd;
-		/* We must wait a bit for dbdma to complete */
-		for (n=0; (in_le32(&dr->status) & ACTIVE) && n < 1000; n++)
-			udelay(10);
-		DBDMA_DO_STOP(dr);
 		out_8(&sw->intr_enable, 0);
 		out_8(&sw->control_bic, WRITE_SECTORS | DO_ACTION);
 		out_8(&sw->select, RELAX);
 		del_timer(&fs->timeout);
 		fs->timeout_pending = 0;
+		dr = fs->dma;
+		cp = fs->dma_cmd;
 		if (rq_data_dir(fd_req) == WRITE)
 			++cp;
+		/*
+		 * Check that the main data transfer has finished.
+		 * On writing, the swim3 sometimes doesn't use
+		 * up all the bytes of the postamble, so we can still
+		 * see DMA active here.  That doesn't matter as long
+		 * as all the sector data has been transferred.
+		 */
+		if ((intr & ERROR_INTR) == 0 && cp->xfer_status == 0) {
+			/* wait a little while for DMA to complete */
+			for (n = 0; n < 100; ++n) {
+				if (cp->xfer_status != 0)
+					break;
+				udelay(1);
+				barrier();
+			}
+		}
+		/* turn off DMA */
+		out_le32(&dr->control, (RUN | PAUSE) << 16);
 		stat = ld_le16(&cp->xfer_status);
 		resid = ld_le16(&cp->res_count);
 		if (intr & ERROR_INTR) {
@@ -742,6 +769,7 @@
 	default:
 		printk(KERN_ERR "swim3: don't know what to do in state %d\n", fs->state);
 	}
+	return IRQ_HANDLED;
 }
 
 /*
@@ -793,16 +821,19 @@
 	if (err)
 		return err;
 	swim3_action(fs, EJECT);
-	for (n = 2*HZ; n > 0; --n) {
-		if (swim3_readbit(fs, RELAX))
-			break;
+	for (n = 20; n > 0; --n) {
 		if (signal_pending(current)) {
 			err = -EINTR;
 			break;
 		}
+		swim3_select(fs, RELAX);
 		current->state = TASK_INTERRUPTIBLE;
 		schedule_timeout(1);
+		if (swim3_readbit(fs, DISK_IN) == 0)
+			break;
 	}
+	swim3_select(fs, RELAX);
+	udelay(150);
 	fs->ejected = 1;
 	release_drive(fs);
 	return err;
@@ -847,29 +878,31 @@
 	if (fs->ref_count == 0) {
 		if (fs->media_bay && check_media_bay(fs->media_bay, MB_FD))
 			return -ENXIO;
-		out_8(&sw->mode, 0x95);
-		out_8(&sw->control_bic, 0xff);
 		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 = HZ; n > 0; --n) {
-			if (swim3_readbit(fs, SEEK_COMPLETE))
+		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);
 			current->state = TASK_INTERRUPTIBLE;
 			schedule_timeout(1);
 		}
 		if (err == 0 && (swim3_readbit(fs, SEEK_COMPLETE) == 0
 				 || swim3_readbit(fs, DISK_IN) == 0))
 			err = -ENXIO;
-		swim3_action(fs, 9);
+		swim3_action(fs, SETMFM);
+		swim3_select(fs, RELAX);
 
 	} else if (fs->ref_count == -1 || filp->f_flags & O_EXCL)
 		return -EBUSY;
@@ -892,6 +925,7 @@
 		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;
 	}
@@ -911,6 +945,7 @@
 	if (fs->ref_count > 0 && --fs->ref_count == 0) {
 		swim3_action(fs, MOTOR_OFF);
 		out_8(&sw->control_bic, 0xff);
+		swim3_select(fs, RELAX);
 	}
 	return 0;
 }
@@ -933,15 +968,17 @@
 	sw = fs->swim3;
 	grab_drive(fs, revalidating, 0);
 	out_8(&sw->intr_enable, 0);
-	out_8(&sw->control_bis, DRIVE_ENABLE | INTR_ENABLE);
-	swim3_action(fs, MOTOR_ON);
+	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);
 		current->state = TASK_INTERRUPTIBLE;
 		schedule_timeout(1);
 	}
@@ -951,17 +988,14 @@
 		swim3_action(fs, MOTOR_OFF);
 	else {
 		fs->ejected = 0;
-		swim3_action(fs, 9);
+		swim3_action(fs, SETMFM);
 	}
+	swim3_select(fs, RELAX);
 
 	release_drive(fs);
 	return ret;
 }
 
-static void floppy_off(unsigned int nr)
-{
-}
-
 static struct block_device_operations floppy_fops = {
 	.open		= floppy_open,
 	.release	= floppy_release,
@@ -1104,3 +1138,5 @@
 	
 	return 0;
 }
+
+module_init(swim3_init)

^ permalink raw reply	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2003-12-01  0:12 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2003-11-30  9:19 PowerMac floppy (SWIM-3) doesn't compile Sebastiaan
2003-11-30 11:25 Mikael Pettersson
2003-11-30 13:35 ` Sebastiaan
2003-12-01  0:11 ` Benjamin Herrenschmidt

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).