<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2//EN">
<HTML>
<HEAD>
<META HTTP-EQUIV="Content-Type" CONTENT="text/html; charset=iso-8859-1">
<META NAME="Generator" CONTENT="MS Exchange Server version 6.5.7652.24">
<TITLE>RE: [PATCH] Xilinx SystemACE device driver</TITLE>
</HEAD>
<BODY>
<!-- Converted from text/plain format -->

<P><FONT SIZE=2>Hi,<BR>
<BR>
Ok, so outlook is a problem.&nbsp; The horror is that, where I work thats all I can use.&nbsp; They block all the outside systems like gmail, yahoo, etc.&nbsp; So under linux, I have to use the web access for outlook.&nbsp; ugh.&nbsp;<BR>
Why I work here I don't know, they think all software HAS to be bought.<BR>
<BR>
Um, so your patch creates another xsysace.c file, all by itself, which is a NEW driver?&nbsp;<BR>
This replaces the 8 files of the previous driver?&nbsp; What happens to all the low level funcs?<BR>
<BR>
Where can I get your 2.6.22 tree to see how this is all supposed to go together?&nbsp; Is there a tar.bz2 package?<BR>
<BR>
Thanks for your patience.<BR>
<BR>
<BR>
Joe Robertson<BR>
x8259<BR>
Joseph.Robertson@sanmina-sci.com<BR>
<BR>
<BR>
<BR>
-----Original Message-----<BR>
From: glikely@secretlab.ca on behalf of Grant Likely<BR>
Sent: Fri 7/13/2007 10:41 AM<BR>
To: Robertson, Joseph M.; Linux PPC Linux PPC<BR>
Subject: Re: [PATCH] Xilinx SystemACE device driver<BR>
<BR>
On 7/13/07, Robertson, Joseph M. &lt;joseph.robertson@sanmina-sci.com&gt; wrote:<BR>
&gt;<BR>
&gt;<BR>
&gt;<BR>
&gt; Hi,<BR>
&gt;<BR>
&gt;&nbsp; I apologize if I am just being dense, but cannot get this patch to work.<BR>
<BR>
BTW, please make sure you CC the mailing list when asking questions.<BR>
That way more people than just me can offer answers.<BR>
<BR>
You will probably get conflicts when applying the patch which you need<BR>
to fixup, but the conflicts should be limited to Kconfig and Makefile.<BR>
<BR>
&gt;&nbsp; I get the same problem.<BR>
&gt;&nbsp; What command do you use to apply the patch?&nbsp; patch -p1 &lt; filename<BR>
&gt;&nbsp; I put file in kernel root and change b/drivers/block/xsysace.c -&gt;<BR>
&gt; b/drivers/block/xilinx_sysace/xsysace.c&nbsp; (the 'old'<BR>
&gt; location?)<BR>
<BR>
Yes, 'patch -p1 &lt; file' is the correct command.&nbsp; Make sure you start<BR>
at the top of the Linux kernel source tree.&nbsp; Also make sure that you<BR>
are using the raw email that I sent you.&nbsp; Do *NOT* try to copy and<BR>
paste from your mail client.&nbsp; It will not work.&nbsp; Outlook is<BR>
particularly bad for working with patches, so if you can change mail<BR>
clients, or start using a gmail account, your life will get easier.<BR>
<BR>
&gt;&nbsp; I thought I had a too old version of patch, but its actually later than the<BR>
&gt; gnu website(2.5.4), I have 2.5.9<BR>
<BR>
The patch format is *very* stable.&nbsp; This is certainly not your problem.<BR>
&gt;<BR>
&gt;&nbsp; Can you post the complete file for xsysace v1.01a somewhere?<BR>
&gt;&nbsp; Or tell me, does the xsysace.c code completely replace the previous<BR>
&gt; xsysace.c file?<BR>
<BR>
The new driver is a 100% rewrite.&nbsp; In fact, the old and new drivers<BR>
can coexist side-by-side.&nbsp; The new driver is fully contained in a<BR>
single source file (xsysace.c).<BR>
<BR>
&gt;<BR>
&gt;&nbsp; Or perhaps point out what xsysace bug we need to fix?<BR>
<BR>
I have no idea.&nbsp; I cannot say without trying to reproduce the problem,<BR>
and 2.6.17 is far to old for me to want to twiddle with.<BR>
<BR>
What xilinx devices are you using?&nbsp; TEMAC, SystemACE I know.&nbsp; Any others?<BR>
<BR>
&gt;<BR>
&gt;&nbsp; Thanks a lot.&nbsp; I hope to be able to contribute one day.<BR>
<BR>
:-)<BR>
<BR>
&gt;<BR>
&gt;&nbsp; Joe Robertson<BR>
&gt;&nbsp; x8259<BR>
&gt;&nbsp; Joseph.Robertson@sanmina-sci.com<BR>
&gt;<BR>
&gt;<BR>
&gt;<BR>
&gt;&nbsp; -----Original Message-----<BR>
&gt;&nbsp; From: Grant Likely [<A HREF="mailto:grant.likely@secretlab.ca">mailto:grant.likely@secretlab.ca</A>]<BR>
&gt;&nbsp; Sent: Thu 7/12/2007 5:51 PM<BR>
&gt;&nbsp; To: Robertson@secretlab.ca; Robertson, Joseph M.<BR>
&gt;&nbsp; Subject: [PATCH] Xilinx SystemACE device driver<BR>
&gt;<BR>
&gt;&nbsp; From: Grant Likely &lt;grant.likely@secretlab.ca&gt;<BR>
&gt;<BR>
&gt;&nbsp; Add support for block device access to the Xilinx SystemACE Compact<BR>
&gt;&nbsp; flash interface<BR>
&gt;<BR>
&gt;&nbsp; Signed-off-by: Grant Likely &lt;grant.likely@secretlab.ca&gt;<BR>
&gt;&nbsp; ---<BR>
&gt;<BR>
&gt;&nbsp;&nbsp; drivers/block/Kconfig&nbsp;&nbsp; |&nbsp;&nbsp;&nbsp; 6<BR>
&gt;&nbsp;&nbsp; drivers/block/Makefile&nbsp; |&nbsp;&nbsp;&nbsp; 1<BR>
&gt;&nbsp;&nbsp; drivers/block/xsysace.c | 1167<BR>
&gt; +++++++++++++++++++++++++++++++++++++++++++++++<BR>
&gt;&nbsp;&nbsp; 3 files changed, 1174 insertions(+), 0 deletions(-)<BR>
&gt;<BR>
&gt;&nbsp; diff --git a/drivers/block/Kconfig b/drivers/block/Kconfig<BR>
&gt;&nbsp; index b4c8319..184b30d 100644<BR>
&gt;&nbsp; --- a/drivers/block/Kconfig<BR>
&gt;&nbsp; +++ b/drivers/block/Kconfig<BR>
&gt;&nbsp; @@ -453,6 +453,12 @@ config ATA_OVER_ETH<BR>
&gt;<BR>
&gt;&nbsp;&nbsp; source &quot;drivers/s390/block/Kconfig&quot;<BR>
&gt;<BR>
&gt;&nbsp; +config XILINX_SYSACE<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tristate &quot;Xilinx SystemACE support&quot;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; depends on 4xx<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; help<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; Include support for the Xilinx SystemACE CompactFlash interface<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp;&nbsp; endmenu<BR>
&gt;<BR>
&gt;&nbsp;&nbsp; endif<BR>
&gt;&nbsp; diff --git a/drivers/block/Makefile b/drivers/block/Makefile<BR>
&gt;&nbsp; index dd88e33..31ea323 100644<BR>
&gt;&nbsp; --- a/drivers/block/Makefile<BR>
&gt;&nbsp; +++ b/drivers/block/Makefile<BR>
&gt;&nbsp; @@ -28,4 +28,5 @@ obj-$(CONFIG_BLK_DEV_CRYPTOLOOP) +=<BR>
&gt; cryptoloop.o<BR>
&gt;&nbsp;&nbsp; obj-$(CONFIG_VIODASD)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; += viodasd.o<BR>
&gt;&nbsp;&nbsp; obj-$(CONFIG_BLK_DEV_SX8)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; += sx8.o<BR>
&gt;&nbsp;&nbsp; obj-$(CONFIG_BLK_DEV_UB)&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; += ub.o<BR>
&gt;&nbsp; +obj-$(CONFIG_XILINX_SYSACE)&nbsp;&nbsp;&nbsp; += xsysace.o<BR>
&gt;<BR>
&gt;&nbsp; diff --git a/drivers/block/xsysace.c b/drivers/block/xsysace.c<BR>
&gt;&nbsp; new file mode 100644<BR>
&gt;&nbsp; index 0000000..f8602e6<BR>
&gt;&nbsp; --- /dev/null<BR>
&gt;&nbsp; +++ b/drivers/block/xsysace.c<BR>
&gt;&nbsp; @@ -0,0 +1,1167 @@<BR>
&gt;&nbsp; +/*<BR>
&gt;&nbsp; + * Xilinx SystemACE device driver<BR>
&gt;&nbsp; + *<BR>
&gt;&nbsp; + * Copyright 2007 Secret Lab Technologies Ltd.<BR>
&gt;&nbsp; + *<BR>
&gt;&nbsp; + * This program is free software; you can redistribute it and/or modify it<BR>
&gt;&nbsp; + * under the terms of the GNU General Public License version 2 as<BR>
&gt; published<BR>
&gt;&nbsp; + * by the Free Software Foundation.<BR>
&gt;&nbsp; + */<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/*<BR>
&gt;&nbsp; + * The SystemACE chip is designed to configure FPGAs by loading an FPGA<BR>
&gt;&nbsp; + * bitstream from a file on a CF card and squirting it into FPGAs<BR>
&gt; connected<BR>
&gt;&nbsp; + * to the SystemACE JTAG chain.&nbsp; It also has the advantage of providing an<BR>
&gt;&nbsp; + * MPU interface which can be used to control the FPGA configuration<BR>
&gt; process<BR>
&gt;&nbsp; + * and to use the attached CF card for general purpose storage.<BR>
&gt;&nbsp; + *<BR>
&gt;&nbsp; + * This driver is a block device driver for the SystemACE.<BR>
&gt;&nbsp; + *<BR>
&gt;&nbsp; + * Initialization:<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; The driver registers itself as a platform_device driver at module<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; load time.&nbsp; The platform bus will take care of calling the<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; ace_probe() method for all SystemACE instances in the system.&nbsp; Any<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; number of SystemACE instances are supported.&nbsp; ace_probe() calls<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; ace_setup() which initialized all data structures, reads the CF<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; id structure and registers the device.<BR>
&gt;&nbsp; + *<BR>
&gt;&nbsp; + * Processing:<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; Just about all of the heavy lifting in this driver is performed by<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; a Finite State Machine (FSM).&nbsp; The driver needs to wait on a number<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; of events; some raised by interrupts, some which need to be polled<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; for.&nbsp; Describing all of the behaviour in a FSM seems to be the<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; easiest way to keep the complexity low and make it easy to<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; understand what the driver is doing.&nbsp; If the block ops or the<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; request function need to interact with the hardware, then they<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; simply need to flag the request and kick of FSM processing.<BR>
&gt;&nbsp; + *<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; The FSM itself is atomic-safe code which can be run from any<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; context.&nbsp; The general process flow is:<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; 1. obtain the ace-&gt;lock spinlock.<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; 2. loop on ace_fsm_dostate() until the ace-&gt;fsm_continue flag is<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; cleared.<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; 3. release the lock.<BR>
&gt;&nbsp; + *<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; Individual states do not sleep in any way.&nbsp; If a condition needs to<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; be waited for then the state much clear the fsm_continue flag and<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; either schedule the FSM to be run again at a later time, or expect<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; an interrupt to call the FSM when the desired condition is met.<BR>
&gt;&nbsp; + *<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; In normal operation, the FSM is processed at interrupt context<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; either when the driver's tasklet is scheduled, or when an irq is<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; raised by the hardware.&nbsp; The tasklet can be scheduled at any time.<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; The request method in particular schedules the tasklet when a new<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; request has been indicated by the block layer.&nbsp; Once started, the<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; FSM proceeds as far as it can processing the request until it<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; needs on a hardware event.&nbsp; At this point, it must yield execution.<BR>
&gt;&nbsp; + *<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; A state has two options when yielding execution:<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; 1. ace_fsm_yield()<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - Call if need to poll for event.<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - clears the fsm_continue flag to exit the processing loop<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - reschedules the tasklet to run again as soon as possible<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; 2. ace_fsm_yieldirq()<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - Call if an irq is expected from the HW<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - clears the fsm_continue flag to exit the processing loop<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; - does not reschedule the tasklet so the FSM will not be<BR>
&gt; processed<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; again until an irq is received.<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; After calling a yield function, the state must return control back<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; to the FSM main loop.<BR>
&gt;&nbsp; + *<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; Additionally, the driver maintains a kernel timer which can process<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; the FSM.&nbsp; If the FSM gets stalled, typically due to a missed<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; interrupt, then the kernel timer will expire and the driver can<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; continue where it left off.<BR>
&gt;&nbsp; + *<BR>
&gt;&nbsp; + * To Do:<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; - Add FPGA configuration control interface.<BR>
&gt;&nbsp; + *&nbsp;&nbsp;&nbsp; - Request major number from lanana<BR>
&gt;&nbsp; + */<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +#undef DEBUG<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +#include &lt;linux/module.h&gt;<BR>
&gt;&nbsp; +#include &lt;linux/ctype.h&gt;<BR>
&gt;&nbsp; +#include &lt;linux/init.h&gt;<BR>
&gt;&nbsp; +#include &lt;linux/interrupt.h&gt;<BR>
&gt;&nbsp; +#include &lt;linux/errno.h&gt;<BR>
&gt;&nbsp; +#include &lt;linux/kernel.h&gt;<BR>
&gt;&nbsp; +#include &lt;linux/delay.h&gt;<BR>
&gt;&nbsp; +#include &lt;linux/slab.h&gt;<BR>
&gt;&nbsp; +#include &lt;linux/blkdev.h&gt;<BR>
&gt;&nbsp; +#include &lt;linux/hdreg.h&gt;<BR>
&gt;&nbsp; +#include &lt;linux/platform_device.h&gt;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +MODULE_AUTHOR(&quot;Grant Likely &lt;grant.likely@secretlab.ca&gt;&quot;);<BR>
&gt;&nbsp; +MODULE_DESCRIPTION(&quot;Xilinx SystemACE device driver&quot;);<BR>
&gt;&nbsp; +MODULE_LICENSE(&quot;GPL&quot;);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/* SystemACE register definitions */<BR>
&gt;&nbsp; +#define ACE_BUSMODE (0x00)<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +#define ACE_STATUS (0x04)<BR>
&gt;&nbsp; +#define ACE_STATUS_CFGLOCK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x00000001)<BR>
&gt;&nbsp; +#define ACE_STATUS_MPULOCK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x00000002)<BR>
&gt;&nbsp; +#define ACE_STATUS_CFGERROR&nbsp;&nbsp;&nbsp;&nbsp; (0x00000004)&nbsp;&nbsp; /* config controller error<BR>
&gt; */<BR>
&gt;&nbsp; +#define ACE_STATUS_CFCERROR&nbsp;&nbsp;&nbsp;&nbsp; (0x00000008)&nbsp;&nbsp; /* CF controller error */<BR>
&gt;&nbsp; +#define ACE_STATUS_CFDETECT&nbsp;&nbsp;&nbsp;&nbsp; (0x00000010)<BR>
&gt;&nbsp; +#define ACE_STATUS_DATABUFRDY&nbsp;&nbsp; (0x00000020)<BR>
&gt;&nbsp; +#define ACE_STATUS_DATABUFMODE&nbsp; (0x00000040)<BR>
&gt;&nbsp; +#define ACE_STATUS_CFGDONE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x00000080)<BR>
&gt;&nbsp; +#define ACE_STATUS_RDYFORCFCMD&nbsp; (0x00000100)<BR>
&gt;&nbsp; +#define ACE_STATUS_CFGMODEPIN&nbsp;&nbsp; (0x00000200)<BR>
&gt;&nbsp; +#define ACE_STATUS_CFGADDR_MASK (0x0000e000)<BR>
&gt;&nbsp; +#define ACE_STATUS_CFBSY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x00020000)<BR>
&gt;&nbsp; +#define ACE_STATUS_CFRDY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x00040000)<BR>
&gt;&nbsp; +#define ACE_STATUS_CFDWF&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x00080000)<BR>
&gt;&nbsp; +#define ACE_STATUS_CFDSC&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x00100000)<BR>
&gt;&nbsp; +#define ACE_STATUS_CFDRQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x00200000)<BR>
&gt;&nbsp; +#define ACE_STATUS_CFCORR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x00400000)<BR>
&gt;&nbsp; +#define ACE_STATUS_CFERR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x00800000)<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +#define ACE_ERROR (0x08)<BR>
&gt;&nbsp; +#define ACE_CFGLBA (0x0c)<BR>
&gt;&nbsp; +#define ACE_MPULBA (0x10)<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +#define ACE_SECCNTCMD (0x14)<BR>
&gt;&nbsp; +#define ACE_SECCNTCMD_RESET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x0100)<BR>
&gt;&nbsp; +#define ACE_SECCNTCMD_IDENTIFY&nbsp;&nbsp; (0x0200)<BR>
&gt;&nbsp; +#define ACE_SECCNTCMD_READ_DATA&nbsp; (0x0300)<BR>
&gt;&nbsp; +#define ACE_SECCNTCMD_WRITE_DATA (0x0400)<BR>
&gt;&nbsp; +#define ACE_SECCNTCMD_ABORT&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x0600)<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +#define ACE_VERSION (0x16)<BR>
&gt;&nbsp; +#define ACE_VERSION_REVISION_MASK (0x00FF)<BR>
&gt;&nbsp; +#define ACE_VERSION_MINOR_MASK&nbsp;&nbsp;&nbsp; (0x0F00)<BR>
&gt;&nbsp; +#define ACE_VERSION_MAJOR_MASK&nbsp;&nbsp;&nbsp; (0xF000)<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +#define ACE_CTRL (0x18)<BR>
&gt;&nbsp; +#define ACE_CTRL_FORCELOCKREQ&nbsp;&nbsp; (0x0001)<BR>
&gt;&nbsp; +#define ACE_CTRL_LOCKREQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x0002)<BR>
&gt;&nbsp; +#define ACE_CTRL_FORCECFGADDR&nbsp;&nbsp; (0x0004)<BR>
&gt;&nbsp; +#define ACE_CTRL_FORCECFGMODE&nbsp;&nbsp; (0x0008)<BR>
&gt;&nbsp; +#define ACE_CTRL_CFGMODE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x0010)<BR>
&gt;&nbsp; +#define ACE_CTRL_CFGSTART&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x0020)<BR>
&gt;&nbsp; +#define ACE_CTRL_CFGSEL&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x0040)<BR>
&gt;&nbsp; +#define ACE_CTRL_CFGRESET&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x0080)<BR>
&gt;&nbsp; +#define ACE_CTRL_DATABUFRDYIRQ&nbsp; (0x0100)<BR>
&gt;&nbsp; +#define ACE_CTRL_ERRORIRQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x0200)<BR>
&gt;&nbsp; +#define ACE_CTRL_CFGDONEIRQ&nbsp;&nbsp;&nbsp;&nbsp; (0x0400)<BR>
&gt;&nbsp; +#define ACE_CTRL_RESETIRQ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x0800)<BR>
&gt;&nbsp; +#define ACE_CTRL_CFGPROG&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (0x1000)<BR>
&gt;&nbsp; +#define ACE_CTRL_CFGADDR_MASK&nbsp;&nbsp; (0xe000)<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +#define ACE_FATSTAT (0x1c)<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +#define ACE_NUM_MINORS 16<BR>
&gt;&nbsp; +#define ACE_SECTOR_SIZE (512)<BR>
&gt;&nbsp; +#define ACE_FIFO_SIZE (32)<BR>
&gt;&nbsp; +#define ACE_BUF_PER_SECTOR (ACE_SECTOR_SIZE / ACE_FIFO_SIZE)<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +struct ace_reg_ops;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +struct ace_device {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* driver state data */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int id;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int media_change;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int users;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct list_head list;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* finite state machine data */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct tasklet_struct fsm_tasklet;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uint fsm_task;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Current activity (ACE_TASK_*) */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uint fsm_state;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Current state (ACE_FSM_STATE_*) */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uint fsm_continue_flag; /* cleared to exit FSM mainloop */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; uint fsm_iter_num;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct timer_list stall_timer;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Transfer state/result, use for both id and block request */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct request *req;&nbsp;&nbsp;&nbsp; /* request being processed */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *data_ptr;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* pointer to I/O buffer */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int data_count;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* number of buffers remaining */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int data_result;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Result of transfer; 0 := success */<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int id_req_count;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* count of id requests */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int id_result;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct completion id_completion;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* used when id req<BR>
&gt; finishes */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int in_irq;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Details of hardware device */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long physaddr;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *baseaddr;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int irq;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int bus_width;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 0 := 8 bit; 1 := 16 bit */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct ace_reg_ops *reg_ops;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int lock_count;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Block device data structures */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spinlock_t lock;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct device *dev;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct request_queue *queue;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct gendisk *gd;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Inserted CF card parameters */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct hd_driveid cf_id;<BR>
&gt;&nbsp; +};<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static int ace_major;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/*<BR>
&gt; ---------------------------------------------------------------------<BR>
&gt;&nbsp; + * Low level register access<BR>
&gt;&nbsp; + */<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +struct ace_reg_ops {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16(*in) (struct ace_device * ace, int reg);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void (*out) (struct ace_device * ace, int reg, u16 val);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void (*datain) (struct ace_device * ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void (*dataout) (struct ace_device * ace);<BR>
&gt;&nbsp; +};<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/* 8 Bit bus width */<BR>
&gt;&nbsp; +static u16 ace_in_8(struct ace_device *ace, int reg)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *r = ace-&gt;baseaddr + reg;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return in_8(r) | (in_8(r + 1) &lt;&lt; 8);<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static void ace_out_8(struct ace_device *ace, int reg, u16 val)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *r = ace-&gt;baseaddr + reg;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_8(r, val);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_8(r + 1, val &gt;&gt; 8);<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static void ace_datain_8(struct ace_device *ace)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *r = ace-&gt;baseaddr + 0x40;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 *dst = ace-&gt;data_ptr;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i = ACE_FIFO_SIZE;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (i--)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *dst++ = in_8(r++);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_ptr = dst;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static void ace_dataout_8(struct ace_device *ace)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; void *r = ace-&gt;baseaddr + 0x40;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u8 *src = ace-&gt;data_ptr;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i = ACE_FIFO_SIZE;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (i--)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_8(r++, *src++);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_ptr = src;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static struct ace_reg_ops ace_reg_8_ops = {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .in = ace_in_8,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .out = ace_out_8,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .datain = ace_datain_8,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .dataout = ace_dataout_8,<BR>
&gt;&nbsp; +};<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/* 16 bit big endian bus attachment */<BR>
&gt;&nbsp; +static u16 ace_in_be16(struct ace_device *ace, int reg)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return in_be16(ace-&gt;baseaddr + reg);<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static void ace_out_be16(struct ace_device *ace, int reg, u16 val)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_be16(ace-&gt;baseaddr + reg, val);<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static void ace_datain_be16(struct ace_device *ace)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i = ACE_FIFO_SIZE / 2;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 *dst = ace-&gt;data_ptr;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (i--)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *dst++ = in_le16(ace-&gt;baseaddr + 0x40);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_ptr = dst;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static void ace_dataout_be16(struct ace_device *ace)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i = ACE_FIFO_SIZE / 2;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 *src = ace-&gt;data_ptr;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (i--)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_le16(ace-&gt;baseaddr + 0x40, *src++);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_ptr = src;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/* 16 bit little endian bus attachment */<BR>
&gt;&nbsp; +static u16 ace_in_le16(struct ace_device *ace, int reg)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return in_le16(ace-&gt;baseaddr + reg);<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static void ace_out_le16(struct ace_device *ace, int reg, u16 val)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_le16(ace-&gt;baseaddr + reg, val);<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static void ace_datain_le16(struct ace_device *ace)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i = ACE_FIFO_SIZE / 2;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 *dst = ace-&gt;data_ptr;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (i--)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *dst++ = in_be16(ace-&gt;baseaddr + 0x40);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_ptr = dst;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static void ace_dataout_le16(struct ace_device *ace)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i = ACE_FIFO_SIZE / 2;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 *src = ace-&gt;data_ptr;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (i--)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; out_be16(ace-&gt;baseaddr + 0x40, *src++);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_ptr = src;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static struct ace_reg_ops ace_reg_be16_ops = {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .in = ace_in_be16,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .out = ace_out_be16,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .datain = ace_datain_be16,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .dataout = ace_dataout_be16,<BR>
&gt;&nbsp; +};<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static struct ace_reg_ops ace_reg_le16_ops = {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .in = ace_in_le16,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .out = ace_out_le16,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .datain = ace_datain_le16,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .dataout = ace_dataout_le16,<BR>
&gt;&nbsp; +};<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static inline u16 ace_in(struct ace_device *ace, int reg)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ace-&gt;reg_ops-&gt;in(ace, reg);<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static inline u32 ace_in32(struct ace_device *ace, int reg)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ace_in(ace, reg) | (ace_in(ace, reg + 2) &lt;&lt; 16);<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static inline void ace_out(struct ace_device *ace, int reg, u16 val)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;reg_ops-&gt;out(ace, reg, val);<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static inline void ace_out32(struct ace_device *ace, int reg, u32 val)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_out(ace, reg, val);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_out(ace, reg + 2, val &gt;&gt; 16);<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/*<BR>
&gt; ---------------------------------------------------------------------<BR>
&gt;&nbsp; + * Debug support functions<BR>
&gt;&nbsp; + */<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +#if defined(DEBUG)<BR>
&gt;&nbsp; +static void ace_dump_mem(void *base, int len)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const char *ptr = base;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i, j;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; len; i += 16) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_INFO &quot;%.8x:&quot;, i);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (j = 0; j &lt; 16; j++) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!(j % 4))<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(&quot; &quot;);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(&quot;%.2x&quot;, ptr[i + j]);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(&quot; &quot;);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (j = 0; j &lt; 16; j++)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(&quot;%c&quot;, isprint(ptr[i + j]) ? ptr[i + j] :<BR>
&gt; '.');<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(&quot;\n&quot;);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +#else<BR>
&gt;&nbsp; +static inline void ace_dump_mem(void *base, int len)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +#endif<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static void ace_dump_regs(struct ace_device *ace)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_info(ace-&gt;dev, &quot;&nbsp;&nbsp;&nbsp; ctrl:&nbsp; %.8x&nbsp; seccnt/cmd: %.4x<BR>
&gt; ver:%.4x\n&quot;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;&nbsp;&nbsp;&nbsp; status:%.8x&nbsp; mpu_lba:%.8x&nbsp; busmode:%4x\n&quot;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;&nbsp;&nbsp;&nbsp; error: %.8x&nbsp; cfg_lba:%.8x&nbsp; fatstat:%.4x\n&quot;,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_in32(ace, ACE_CTRL),<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_in(ace, ACE_SECCNTCMD),<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_in(ace, ACE_VERSION),<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_in32(ace, ACE_STATUS),<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_in32(ace, ACE_MPULBA),<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_in(ace, ACE_BUSMODE),<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_in32(ace, ACE_ERROR),<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_in32(ace, ACE_CFGLBA), ace_in(ace, ACE_FATSTAT));<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +void ace_fix_driveid(struct hd_driveid *id)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +#if defined(__BIG_ENDIAN)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 *buf = (void *)id;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* All half words have wrong byte order; swap the bytes */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; sizeof(struct hd_driveid); i += 2, buf++)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *buf = le16_to_cpu(*buf);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Some of the data values are 32bit; swap the half words&nbsp; */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id-&gt;lba_capacity = ((id-&gt;lba_capacity &gt;&gt; 16) &amp; 0x0000FFFF) |<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((id-&gt;lba_capacity &lt;&lt; 16) &amp; 0xFFFF0000);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; id-&gt;spg = ((id-&gt;spg &gt;&gt; 16) &amp; 0x0000FFFF) |<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ((id-&gt;spg &lt;&lt; 16) &amp; 0xFFFF0000);<BR>
&gt;&nbsp; +#endif<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/*<BR>
&gt; ---------------------------------------------------------------------<BR>
&gt;&nbsp; + * Finite State Machine (FSM) implementation<BR>
&gt;&nbsp; + */<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/* FSM tasks; used to direct state transitions */<BR>
&gt;&nbsp; +#define ACE_TASK_IDLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0<BR>
&gt;&nbsp; +#define ACE_TASK_IDENTIFY&nbsp; 1<BR>
&gt;&nbsp; +#define ACE_TASK_READ&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<BR>
&gt;&nbsp; +#define ACE_TASK_WRITE&nbsp;&nbsp;&nbsp;&nbsp; 3<BR>
&gt;&nbsp; +#define ACE_FSM_NUM_TASKS&nbsp; 4<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/* FSM state definitions */<BR>
&gt;&nbsp; +#define ACE_FSM_STATE_IDLE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 0<BR>
&gt;&nbsp; +#define ACE_FSM_STATE_REQ_LOCK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 1<BR>
&gt;&nbsp; +#define ACE_FSM_STATE_WAIT_LOCK&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 2<BR>
&gt;&nbsp; +#define ACE_FSM_STATE_WAIT_CFREADY&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 3<BR>
&gt;&nbsp; +#define ACE_FSM_STATE_IDENTIFY_PREPARE&nbsp;&nbsp; 4<BR>
&gt;&nbsp; +#define ACE_FSM_STATE_IDENTIFY_TRANSFER&nbsp; 5<BR>
&gt;&nbsp; +#define ACE_FSM_STATE_IDENTIFY_COMPLETE&nbsp; 6<BR>
&gt;&nbsp; +#define ACE_FSM_STATE_REQ_PREPARE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 7<BR>
&gt;&nbsp; +#define ACE_FSM_STATE_REQ_TRANSFER&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 8<BR>
&gt;&nbsp; +#define ACE_FSM_STATE_REQ_COMPLETE&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 9<BR>
&gt;&nbsp; +#define ACE_FSM_STATE_ERROR&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 10<BR>
&gt;&nbsp; +#define ACE_FSM_NUM_STATES&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 11<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/* Set flag to exit FSM loop and reschedule tasklet */<BR>
&gt;&nbsp; +static inline void ace_fsm_yield(struct ace_device *ace)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev, &quot;ace_fsm_yield()\n&quot;);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tasklet_schedule(&amp;ace-&gt;fsm_tasklet);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_continue_flag = 0;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/* Set flag to exit FSM loop and wait for IRQ to reschedule tasklet */<BR>
&gt;&nbsp; +static inline void ace_fsm_yieldirq(struct ace_device *ace)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev, &quot;ace_fsm_yieldirq()\n&quot;);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;irq == NO_IRQ)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* No IRQ assigned, so need to poll */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tasklet_schedule(&amp;ace-&gt;fsm_tasklet);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_continue_flag = 0;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/* Get the next read/write request; ending requests that we don't handle<BR>
&gt; */<BR>
&gt;&nbsp; +struct request *ace_get_next_request(request_queue_t * q)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct request *req;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while ((req = elv_next_request(q)) != NULL) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (blk_fs_request(req))<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end_request(req, 0);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return req;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static void ace_fsm_dostate(struct ace_device *ace)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct request *req;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 status;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 val;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int count;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +#if defined(DEBUG)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev, &quot;fsm_state=%i, id_req_count=%i\n&quot;,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_state, ace-&gt;id_req_count);<BR>
&gt;&nbsp; +#endif<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (ace-&gt;fsm_state) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case ACE_FSM_STATE_IDLE:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* See if there is anything to do */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;id_req_count ||<BR>
&gt; ace_get_next_request(ace-&gt;queue)) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_iter_num++;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_state = ACE_FSM_STATE_REQ_LOCK;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mod_timer(&amp;ace-&gt;stall_timer, jiffies + HZ);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if<BR>
&gt; (!timer_pending(&amp;ace-&gt;stall_timer))<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add_timer(&amp;ace-&gt;stall_timer);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; del_timer(&amp;ace-&gt;stall_timer);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_continue_flag = 0;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case ACE_FSM_STATE_REQ_LOCK:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace_in(ace, ACE_STATUS) &amp; ACE_STATUS_MPULOCK) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Already have the lock, jump to next state */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_state = ACE_FSM_STATE_WAIT_CFREADY;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Request the lock */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; val = ace_in(ace, ACE_CTRL);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_out(ace, ACE_CTRL, val | ACE_CTRL_LOCKREQ);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_state = ACE_FSM_STATE_WAIT_LOCK;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case ACE_FSM_STATE_WAIT_LOCK:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace_in(ace, ACE_STATUS) &amp; ACE_STATUS_MPULOCK) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* got the lock; move to next state */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_state = ACE_FSM_STATE_WAIT_CFREADY;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* wait a bit for the lock */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_fsm_yield(ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case ACE_FSM_STATE_WAIT_CFREADY:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = ace_in32(ace, ACE_STATUS);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!(status &amp; ACE_STATUS_RDYFORCFCMD) ||<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (status &amp; ACE_STATUS_CFBSY)) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* CF card isn't ready; it needs to be polled */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_fsm_yield(ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Device is ready for command; determine what to do next<BR>
&gt; */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;id_req_count)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_state = ACE_FSM_STATE_IDENTIFY_PREPARE;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_state = ACE_FSM_STATE_REQ_PREPARE;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case ACE_FSM_STATE_IDENTIFY_PREPARE:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Send identify command */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_task = ACE_TASK_IDENTIFY;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_ptr = &amp;ace-&gt;cf_id;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_count = ACE_BUF_PER_SECTOR;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_out(ace, ACE_SECCNTCMD, ACE_SECCNTCMD_IDENTIFY);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* As per datasheet, put config controller in reset */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; val = ace_in(ace, ACE_CTRL);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_out(ace, ACE_CTRL, val | ACE_CTRL_CFGRESET);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* irq handler takes over from this point; wait for the<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * transfer to complete */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_state =<BR>
&gt; ACE_FSM_STATE_IDENTIFY_TRANSFER;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_fsm_yieldirq(ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case ACE_FSM_STATE_IDENTIFY_TRANSFER:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Check that the sysace is ready to receive data */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = ace_in32(ace, ACE_STATUS);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status &amp; ACE_STATUS_CFBSY) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev, &quot;CFBSY set; t=%i iter=%i<BR>
&gt; dc=%i\n&quot;,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_task, ace-&gt;fsm_iter_num,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_count);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_fsm_yield(ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!(status &amp; ACE_STATUS_DATABUFRDY)) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_fsm_yield(ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Transfer the next buffer */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;reg_ops-&gt;datain(ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_count--;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* If there are still buffers to be transfers; jump out<BR>
&gt; here */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;data_count != 0) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_fsm_yieldirq(ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* transfer finished; kick state machine */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev, &quot;identify finished\n&quot;);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_state =<BR>
&gt; ACE_FSM_STATE_IDENTIFY_COMPLETE;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case ACE_FSM_STATE_IDENTIFY_COMPLETE:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_fix_driveid(&amp;ace-&gt;cf_id);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_dump_mem(&amp;ace-&gt;cf_id, 512); /* Debug: Dump out disk ID<BR>
&gt; */<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;data_result) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Error occured, disable the disk */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;media_change = 1;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set_capacity(ace-&gt;gd, 0);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(ace-&gt;dev, &quot;error fetching CF id (%i)\n&quot;,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_result);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;media_change = 0;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Record disk parameters */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; set_capacity(ace-&gt;gd, ace-&gt;cf_id.lba_capacity);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_info(ace-&gt;dev, &quot;capacity: %i sectors\n&quot;,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;cf_id.lba_capacity);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* We're done, drop to IDLE state and notify waiters */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_state = ACE_FSM_STATE_IDLE;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;id_result = ace-&gt;data_result;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (ace-&gt;id_req_count) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; complete(&amp;ace-&gt;id_completion);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;id_req_count--;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case ACE_FSM_STATE_REQ_PREPARE:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; req = ace_get_next_request(ace-&gt;queue);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!req) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_state = ACE_FSM_STATE_IDLE;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Okay, it's a data request, set it up for transfer */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;request: sec=%lx hcnt=%lx, ccnt=%x, dir=%i\n&quot;,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; req-&gt;sector, req-&gt;hard_nr_sectors,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; req-&gt;current_nr_sectors, rq_data_dir(req));<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;req = req;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_ptr = req-&gt;buffer;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_count = req-&gt;current_nr_sectors *<BR>
&gt; ACE_BUF_PER_SECTOR;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_out32(ace, ACE_MPULBA, req-&gt;sector &amp; 0x0FFFFFFF);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count = req-&gt;hard_nr_sectors;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rq_data_dir(req)) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Kick off write request */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev, &quot;write data\n&quot;);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_task = ACE_TASK_WRITE;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_out(ace, ACE_SECCNTCMD,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count | ACE_SECCNTCMD_WRITE_DATA);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Kick off read request */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev, &quot;read data\n&quot;);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_task = ACE_TASK_READ;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_out(ace, ACE_SECCNTCMD,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; count | ACE_SECCNTCMD_READ_DATA);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* As per datasheet, put config controller in reset */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; val = ace_in(ace, ACE_CTRL);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_out(ace, ACE_CTRL, val | ACE_CTRL_CFGRESET);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Move to the transfer state.&nbsp; The systemace will raise<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * an interrupt once there is something to do<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_state = ACE_FSM_STATE_REQ_TRANSFER;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;fsm_task == ACE_TASK_READ)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_fsm_yieldirq(ace);&nbsp; /* wait for data ready */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case ACE_FSM_STATE_REQ_TRANSFER:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Check that the sysace is ready to receive data */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; status = ace_in32(ace, ACE_STATUS);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (status &amp; ACE_STATUS_CFBSY) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;CFBSY set; t=%i iter=%i c=%i dc=%i<BR>
&gt; irq=%i\n&quot;,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_task, ace-&gt;fsm_iter_num,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;req-&gt;current_nr_sectors * 16,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_count, ace-&gt;in_irq);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_fsm_yield(ace);&nbsp;&nbsp;&nbsp;&nbsp; /* need to poll CFBSY bit<BR>
&gt; */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!(status &amp; ACE_STATUS_DATABUFRDY)) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;DATABUF not set; t=%i iter=%i c=%i dc=%i<BR>
&gt; irq=%i\n&quot;,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_task, ace-&gt;fsm_iter_num,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;req-&gt;current_nr_sectors * 16,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_count, ace-&gt;in_irq);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_fsm_yieldirq(ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Transfer the next buffer */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i = 16;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;fsm_task == ACE_TASK_WRITE)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;reg_ops-&gt;dataout(ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;reg_ops-&gt;datain(ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_count--;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* If there are still buffers to be transfers; jump out<BR>
&gt; here */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;data_count != 0) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_fsm_yieldirq(ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* bio finished; is there another one? */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; i = ace-&gt;req-&gt;current_nr_sectors;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (end_that_request_first(ace-&gt;req, 1,<BR>
&gt; i)) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* dev_dbg(ace-&gt;dev, &quot;next block; h=%li c=%i\n&quot;,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;req-&gt;hard_nr_sectors,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; *&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;req-&gt;current_nr_sectors);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_ptr = ace-&gt;req-&gt;buffer;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_count = ace-&gt;req-&gt;current_nr_sectors *<BR>
&gt; 16;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_fsm_yieldirq(ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_state = ACE_FSM_STATE_REQ_COMPLETE;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case ACE_FSM_STATE_REQ_COMPLETE:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Complete the block request */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; blkdev_dequeue_request(ace-&gt;req);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; end_that_request_last(ace-&gt;req, 1);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;req = NULL;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Finished request; go to idle state */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_state = ACE_FSM_STATE_IDLE;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_state = ACE_FSM_STATE_IDLE;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; break;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static void ace_fsm_tasklet(unsigned long data)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct ace_device *ace = (void *)data;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long flags;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_lock_irqsave(&amp;ace-&gt;lock, flags);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Loop over state machine until told to stop */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_continue_flag = 1;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (ace-&gt;fsm_continue_flag)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_fsm_dostate(ace);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_unlock_irqrestore(&amp;ace-&gt;lock, flags);<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static void ace_stall_timer(unsigned long data)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct ace_device *ace = (void *)data;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long flags;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_warn(ace-&gt;dev,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;kicking stalled fsm; state=%i task=%i iter=%i dc=%i\n&quot;,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_state, ace-&gt;fsm_task, ace-&gt;fsm_iter_num,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_count);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_lock_irqsave(&amp;ace-&gt;lock, flags);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Rearm the stall timer *before* entering FSM (which may then<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * delete the timer) */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; mod_timer(&amp;ace-&gt;stall_timer, jiffies + HZ);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Loop over state machine until told to stop */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_continue_flag = 1;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (ace-&gt;fsm_continue_flag)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_fsm_dostate(ace);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_unlock_irqrestore(&amp;ace-&gt;lock, flags);<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/*<BR>
&gt; ---------------------------------------------------------------------<BR>
&gt;&nbsp; + * Interrupt handling routines<BR>
&gt;&nbsp; + */<BR>
&gt;&nbsp; +static int ace_interrupt_checkstate(struct ace_device *ace)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u32 sreg = ace_in32(ace, ACE_STATUS);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 creg = ace_in(ace, ACE_CTRL);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Check for error occurance */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((sreg &amp; (ACE_STATUS_CFGERROR | ACE_STATUS_CFCERROR)) &amp;&amp;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (creg &amp; ACE_CTRL_ERRORIRQ)) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(ace-&gt;dev, &quot;transfer failure\n&quot;);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_dump_regs(ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -EIO;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static irqreturn_t ace_interrupt(int irq, void *dev_id)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 creg;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct ace_device *ace = dev_id;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* be safe and get the lock */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_lock(&amp;ace-&gt;lock);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;in_irq = 1;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* clear the interrupt */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; creg = ace_in(ace, ACE_CTRL);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_out(ace, ACE_CTRL, creg | ACE_CTRL_RESETIRQ);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_out(ace, ACE_CTRL, creg);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* check for IO failures */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace_interrupt_checkstate(ace))<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;data_result = -EIO;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;fsm_task == 0) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(ace-&gt;dev,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &quot;spurious irq; stat=%.8x ctrl=%.8x cmd=%.4x\n&quot;,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_in32(ace, ACE_STATUS), ace_in32(ace, ACE_CTRL),<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_in(ace, ACE_SECCNTCMD));<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(ace-&gt;dev, &quot;fsm_task=%i fsm_state=%i<BR>
&gt; data_count=%i\n&quot;,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_task, ace-&gt;fsm_state, ace-&gt;data_count);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Loop over state machine until told to stop */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;fsm_continue_flag = 1;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; while (ace-&gt;fsm_continue_flag)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_fsm_dostate(ace);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* done with interrupt; drop the lock */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;in_irq = 0;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_unlock(&amp;ace-&gt;lock);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return IRQ_HANDLED;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/*<BR>
&gt; ---------------------------------------------------------------------<BR>
&gt;&nbsp; + * Block ops<BR>
&gt;&nbsp; + */<BR>
&gt;&nbsp; +static void ace_request(request_queue_t * q)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct request *req;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct ace_device *ace;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; req = ace_get_next_request(q);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (req) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace = req-&gt;rq_disk-&gt;private_data;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tasklet_schedule(&amp;ace-&gt;fsm_tasklet);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static int ace_media_changed(struct gendisk *gd)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct ace_device *ace = gd-&gt;private_data;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev, &quot;ace_media_changed(): %i\n&quot;, ace-&gt;media_change);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ace-&gt;media_change;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static int ace_revalidate_disk(struct gendisk *gd)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct ace_device *ace = gd-&gt;private_data;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long flags;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev, &quot;ace_revalidate_disk()\n&quot;);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;media_change) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev, &quot;requesting cf id and scheduling<BR>
&gt; tasklet\n&quot;);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_lock_irqsave(&amp;ace-&gt;lock, flags);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;id_req_count++;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_unlock_irqrestore(&amp;ace-&gt;lock, flags);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tasklet_schedule(&amp;ace-&gt;fsm_tasklet);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; wait_for_completion(&amp;ace-&gt;id_completion);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev, &quot;revalidate complete\n&quot;);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ace-&gt;id_result;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static int ace_open(struct inode *inode, struct file *filp)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct ace_device *ace =<BR>
&gt; inode-&gt;i_bdev-&gt;bd_disk-&gt;private_data;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long flags;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev, &quot;ace_open() users=%i\n&quot;, ace-&gt;users + 1);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; filp-&gt;private_data = ace;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_lock_irqsave(&amp;ace-&gt;lock, flags);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;users++;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_unlock_irqrestore(&amp;ace-&gt;lock, flags);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; check_disk_change(inode-&gt;i_bdev);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static int ace_release(struct inode *inode, struct file *filp)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct ace_device *ace =<BR>
&gt; inode-&gt;i_bdev-&gt;bd_disk-&gt;private_data;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned long flags;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 val;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev, &quot;ace_release() users=%i\n&quot;, ace-&gt;users - 1);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_lock_irqsave(&amp;ace-&gt;lock, flags);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;users--;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;users == 0) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; val = ace_in(ace, ACE_CTRL);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_out(ace, ACE_CTRL, val &amp; ~ACE_CTRL_LOCKREQ);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_unlock_irqrestore(&amp;ace-&gt;lock, flags);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static int ace_ioctl(struct inode *inode, struct file *filp,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; unsigned int cmd, unsigned long arg)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct ace_device *ace =<BR>
&gt; inode-&gt;i_bdev-&gt;bd_disk-&gt;private_data;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct hd_geometry __user *geo = (struct hd_geometry __user *)arg;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct hd_geometry g;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev, &quot;ace_ioctl()\n&quot;);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; switch (cmd) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; case HDIO_GETGEO:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g.heads = ace-&gt;cf_id.heads;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g.sectors = ace-&gt;cf_id.sectors;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g.cylinders = ace-&gt;cf_id.cyls;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; g.start = 0;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return copy_to_user(geo, &amp;g, sizeof(g)) ? -EFAULT : 0;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; default:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENOTTY;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENOTTY;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static struct block_device_operations ace_fops = {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .owner = THIS_MODULE,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .open = ace_open,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .release = ace_release,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .media_changed = ace_media_changed,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .revalidate_disk = ace_revalidate_disk,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .ioctl = ace_ioctl,<BR>
&gt;&nbsp; +};<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/*<BR>
&gt; --------------------------------------------------------------------<BR>
&gt;&nbsp; + * SystemACE device setup/teardown code<BR>
&gt;&nbsp; + */<BR>
&gt;&nbsp; +static int __devinit ace_setup(struct ace_device *ace)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 version;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; u16 val;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int rc;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; spin_lock_init(&amp;ace-&gt;lock);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; init_completion(&amp;ace-&gt;id_completion);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Map the device<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;baseaddr = ioremap(ace-&gt;physaddr, 0x80);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!ace-&gt;baseaddr)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto err_ioremap;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;irq != NO_IRQ) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; rc = request_irq(ace-&gt;irq, ace_interrupt, 0, &quot;systemace&quot;,<BR>
&gt; ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (rc) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Failure - fall back to polled mode */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_err(ace-&gt;dev, &quot;request_irq failed\n&quot;);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;irq = NO_IRQ;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Initialize the state machine tasklet and stall timer<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tasklet_init(&amp;ace-&gt;fsm_tasklet, ace_fsm_tasklet, (unsigned<BR>
&gt; long)ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setup_timer(&amp;ace-&gt;stall_timer, ace_stall_timer, (unsigned<BR>
&gt; long)ace);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Initialize the request queue<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;queue = blk_init_queue(ace_request, &amp;ace-&gt;lock);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;queue == NULL)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto err_blk_initq;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; blk_queue_hardsect_size(ace-&gt;queue, 512);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Allocate and initialize GD structure<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;gd = alloc_disk(ACE_NUM_MINORS);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!ace-&gt;gd)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto err_alloc_disk;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;gd-&gt;major = ace_major;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;gd-&gt;first_minor = ace-&gt;id * ACE_NUM_MINORS;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;gd-&gt;fops = &amp;ace_fops;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;gd-&gt;queue = ace-&gt;queue;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;gd-&gt;private_data = ace;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; snprintf(ace-&gt;gd-&gt;disk_name, 32, &quot;xs%c&quot;, ace-&gt;id + 'a');<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; device_rename(ace-&gt;dev, ace-&gt;gd-&gt;disk_name);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* set bus width */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;bus_width == 1) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* 0x0101 should work regardless of endianess */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_out_le16(ace, ACE_BUSMODE, 0x0101);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* read it back to determine endianess */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace_in_le16(ace, ACE_BUSMODE) == 0x0001)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;reg_ops = &amp;ace_reg_le16_ops;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; else<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;reg_ops = &amp;ace_reg_be16_ops;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; } else {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_out_8(ace, ACE_BUSMODE, 0x00);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;reg_ops = &amp;ace_reg_8_ops;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Make sure version register is sane */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; version = ace_in(ace, ACE_VERSION);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ((version == 0) || (version == 0xFFFF))<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto err_read;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Put sysace in a sane state by clearing most control reg bits */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_out(ace, ACE_CTRL, ACE_CTRL_FORCECFGMODE |<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ACE_CTRL_DATABUFRDYIRQ | ACE_CTRL_ERRORIRQ);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Enable interrupts */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; val = ace_in(ace, ACE_CTRL);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; val |= ACE_CTRL_DATABUFRDYIRQ | ACE_CTRL_ERRORIRQ;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_out(ace, ACE_CTRL, val);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Print the identification */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_info(ace-&gt;dev, &quot;Xilinx SystemACE revision %i.%i.%i\n&quot;,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; (version &gt;&gt; 12) &amp; 0xf, (version &gt;&gt; 8) &amp; 0x0f, version &amp;<BR>
&gt; 0xff);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(ace-&gt;dev, &quot;physaddr 0x%lx, mapped to 0x%p, irq=%i\n&quot;,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;physaddr, ace-&gt;baseaddr, ace-&gt;irq);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;media_change = 1;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_revalidate_disk(ace-&gt;gd);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Make the sysace device 'live' */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; add_disk(ace-&gt;gd);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; err_read:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; put_disk(ace-&gt;gd);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; err_alloc_disk:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; blk_cleanup_queue(ace-&gt;queue);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; err_blk_initq:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iounmap(ace-&gt;baseaddr);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;irq != NO_IRQ)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free_irq(ace-&gt;irq, ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; err_ioremap:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_INFO &quot;xsysace: error initializing device at 0x%lx\n&quot;,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;physaddr);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENOMEM;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static void __devexit ace_teardown(struct ace_device *ace)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;gd) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; del_gendisk(ace-&gt;gd);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; put_disk(ace-&gt;gd);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;queue)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; blk_cleanup_queue(ace-&gt;queue);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; tasklet_kill(&amp;ace-&gt;fsm_tasklet);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace-&gt;irq != NO_IRQ)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; free_irq(ace-&gt;irq, ace);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; iounmap(ace-&gt;baseaddr);<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/*<BR>
&gt; ---------------------------------------------------------------------<BR>
&gt;&nbsp; + * Platform Bus Support<BR>
&gt;&nbsp; + */<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static int __devinit ace_probe(struct device *device)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct platform_device *dev = to_platform_device(device);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct ace_device *ace;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; int i;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(device, &quot;ace_probe(%p)\n&quot;, device);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /*<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; * Allocate the ace device structure<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace = kzalloc(sizeof(struct ace_device), GFP_KERNEL);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (!ace)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto err_alloc;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;dev = device;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;id = dev-&gt;id;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;irq = NO_IRQ;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for (i = 0; i &lt; dev-&gt;num_resources; i++) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dev-&gt;resource[i].flags &amp; IORESOURCE_MEM)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;physaddr = dev-&gt;resource[i].start;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (dev-&gt;resource[i].flags &amp; IORESOURCE_IRQ)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;irq = dev-&gt;resource[i].start;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* FIXME: Should get bus_width from the platform_device struct */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace-&gt;bus_width = 1;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_set_drvdata(&amp;dev-&gt;dev, ace);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; /* Call the bus-independant setup code */<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace_setup(ace) != 0)<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; goto err_setup;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; err_setup:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_set_drvdata(&amp;dev-&gt;dev, NULL);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kfree(ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; err_alloc:<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_ERR &quot;xsysace: could not initialize device\n&quot;);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return -ENOMEM;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/*<BR>
&gt;&nbsp; + * Platform bus remove() method<BR>
&gt;&nbsp; + */<BR>
&gt;&nbsp; +static int __devexit ace_remove(struct device *device)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; struct ace_device *ace = dev_get_drvdata(device);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; dev_dbg(device, &quot;ace_remove(%p)\n&quot;, device);<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_teardown(ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; kfree(ace);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return 0;<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static struct device_driver ace_driver = {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .name = &quot;xsysace&quot;,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .bus = &amp;platform_bus_type,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .probe = ace_probe,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; .remove = __devexit_p(ace_remove),<BR>
&gt;&nbsp; +};<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +/*<BR>
&gt; ---------------------------------------------------------------------<BR>
&gt;&nbsp; + * Module init/exit routines<BR>
&gt;&nbsp; + */<BR>
&gt;&nbsp; +static int __init ace_init(void)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_major = register_blkdev(ace_major, &quot;xsysace&quot;);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (ace_major &lt;= 0) {<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_WARNING &quot;xsysace: register_blkdev() failed\n&quot;);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return ace_major;<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; }<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pr_debug(&quot;Registering Xilinx SystemACE driver, major=%i\n&quot;,<BR>
&gt; ace_major);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return driver_register(&amp;ace_driver);<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +static void __exit ace_exit(void)<BR>
&gt;&nbsp; +{<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; pr_debug(&quot;Unregistering Xilinx SystemACE driver\n&quot;);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; driver_unregister(&amp;ace_driver);<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if (unregister_blkdev(ace_major, &quot;xsysace&quot;))<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; printk(KERN_WARNING &quot;systemace unregister_blkdev(%i)<BR>
&gt; failed\n&quot;,<BR>
&gt;&nbsp; +&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; ace_major);<BR>
&gt;&nbsp; +}<BR>
&gt;&nbsp; +<BR>
&gt;&nbsp; +module_init(ace_init);<BR>
&gt;&nbsp; +module_exit(ace_exit);<BR>
&gt;<BR>
&gt;<BR>
&gt;&nbsp; CONFIDENTIALITY<BR>
&gt;&nbsp; This e-mail message and any attachments thereto, is intended only for use<BR>
&gt; by the addressee(s) named herein and may contain legally privileged and/or<BR>
&gt; confidential information. If you are not the intended recipient of this<BR>
&gt; e-mail message, you are hereby notified that any dissemination, distribution<BR>
&gt; or copying of this e-mail message, and any attachments thereto, is strictly<BR>
&gt; prohibited. If you have received this e-mail message in error, please<BR>
&gt; immediately notify the sender and permanently delete the original and any<BR>
&gt; copies of this email and any prints thereof.<BR>
&gt;&nbsp; ABSENT AN EXPRESS STATEMENT TO THE CONTRARY HEREINABOVE, THIS E-MAIL IS NOT<BR>
&gt; INTENDED AS A SUBSTITUTE FOR A WRITING. Notwithstanding the Uniform<BR>
&gt; Electronic Transactions Act or the applicability of any other law of similar<BR>
&gt; substance and effect, absent an express statement to the contrary<BR>
&gt; hereinabove, this e-mail message its contents, and any attachments hereto<BR>
&gt; are not intended to represent an offer or acceptance to enter into a<BR>
&gt; contract and are not otherwise intended to bind the sender, Sanmina-SCI<BR>
&gt; Corporation (or any of its subsidiaries), or any other person or entity.<BR>
&gt;<BR>
<BR>
<BR>
--<BR>
Grant Likely, B.Sc., P.Eng.<BR>
Secret Lab Technologies Ltd.<BR>
grant.likely@secretlab.ca<BR>
(403) 399-0195<BR>
<BR>
</FONT>
</P>


<BR>
CONFIDENTIALITY<BR>
This e-mail message and any attachments thereto, is intended only for use by the addressee(s) named herein and may contain legally privileged and/or confidential information. If you are not the intended recipient of this e-mail message, you are hereby notified that any dissemination, distribution or copying of this e-mail message, and any attachments thereto, is strictly prohibited.  If you have received this e-mail message in error, please immediately notify the sender and permanently delete the original and any copies of this email and any prints thereof.<BR>
ABSENT AN EXPRESS STATEMENT TO THE CONTRARY HEREINABOVE, THIS E-MAIL IS NOT INTENDED AS A SUBSTITUTE FOR A WRITING.  Notwithstanding the Uniform Electronic Transactions Act or the applicability of any other law of similar substance and effect, absent an express statement to the contrary hereinabove, this e-mail message its contents, and any attachments hereto are not intended to represent an offer or acceptance to enter into a contract and are not otherwise intended to bind the sender, Sanmina-SCI Corporation (or any of its subsidiaries), or any other person or entity.<BR>
</BODY>
</HTML>