Hi John, I prepared two patch files. The xilinx_sysace_patch.txt fixes the write problem with systemACE due to a spurius interrupt that hangs the kernel and add a printk with error code in case of initialization failed (have to be applied to uClinux-2.4.x/drivers/block/xilinx_sysace). The vendors_patch.txt adds systemace devices to the uclinux vendor Makefile only if DEVFS is not enabled and systemace drived is enabled (have to be applied to uClinux-dist/vendors/Xilinx/uclinux-auto). Specially the first one is a MUST to avoid kernel hang when mounting the systemace device read/write. Include them in your official version, please. Cheers, Claudio Lanconelli
Attachment:
patch.tar.gz
Description: application/tgz
*** Makefile 22 Dec 2004 12:00:47 -0000 1.1.1.1 --- Makefile 30 Mar 2005 08:10:17 -0000 *************** *** 56,61 **** --- 56,68 ---- mtd6,c,90,12 mtdr6,c,90,13 mtdblock6,b,31,6 \ mtd7,c,90,14 mtdr7,c,90,15 mtdblock7,b,31,7 + SYSACE_DEVICES = \ + xsysacea,b,254,0 xsysacea1,b,254,1 xsysacea2,b,254,2 \ + xsysacea3,b,254,3 xsysacea4,b,254,4 xsysacea5,b,254,5 \ + xsysacea6,b,254,6 xsysacea7,b,254,7 xsysacea8,b,254,8 \ + xsysacea9,b,254,9 xsysacea10,b,254,10 xsysacea11,b,254,11 \ + xsysacea12,b,254,12 xsysacea12,b,254,13 xsysacea14,b,254,14 \ + xsysacea15,b,254,15 FLASH_DEVICES = \ boot,c,90,0 \ *************** *** 122,127 **** --- 129,141 ---- # these permissions are needed for openpty and family to work # on non-ptmx ptys chmod 620 $(ROMFSDIR)/dev/@[pt]ty[pqrsPQRS][0-9a-f],* + if [ "$(CONFIG_XILINX_SYSACE)" = "y" ]; then \ + if [ "$(CONFIG_DEVFS_FS)" != "y" ]; then \ + for i in $(SYSACE_DEVICES); do \ + touch $(ROMFSDIR)/dev/@$$i; \ + done; \ + fi; \ + fi for i in $(FLASH_DEVICES); do \ touch $(ROMFSDIR)/dev/flash/@$$i; \ done
*** adapter.c 15 Feb 2005 22:44:29 -0000 1.2
--- adapter.c 30 Mar 2005 08:05:54 -0000
***************
*** 303,308 ****
--- 303,314 ----
{
unsigned long flags;
+ if ( req_active == 0 )
+ {
+ printk(KERN_ERR "%s: spurius interrupt\n", DEVICE_NAME);
+ return;
+ }
+
XSysAce_Unlock(&SysAce);
spin_lock_irqsave(&io_request_lock, flags);
end_request(uptodate);
***************
*** 331,350 ****
XSysAce_InterruptHandler(&SysAce);
}
- /* Called by the Xilinx interrupt handler to give us an event. */
static void
! EventHandler(void *CallbackRef, int Event)
{
- u32 ErrorMask;
-
- switch (Event) {
- case XSA_EVENT_DATA_DONE:
- xsa_complete_request(1); /* The request succeeded. */
- break;
-
- case XSA_EVENT_ERROR:
- ErrorMask = XSysAce_GetErrors(&SysAce);
-
/* Print out what went wrong. */
if (ErrorMask & XSA_ER_CARD_RESET)
printk(KERN_ERR "CompactFlash failed to reset\n");
--- 337,345 ----
XSysAce_InterruptHandler(&SysAce);
}
static void
! xsysace_printerrcode(u32 ErrorMask)
{
/* Print out what went wrong. */
if (ErrorMask & XSA_ER_CARD_RESET)
printk(KERN_ERR "CompactFlash failed to reset\n");
***************
*** 382,387 ****
--- 377,399 ----
"Invalid instruction during JTAG configuration\n");
if (ErrorMask & XSA_ER_CFG_INIT)
printk(KERN_ERR "JTAG CFGINIT pin error\n");
+ }
+
+ /* Called by the Xilinx interrupt handler to give us an event. */
+ static void
+ EventHandler(void *CallbackRef, int Event)
+ {
+ u32 ErrorMask;
+
+ switch (Event) {
+ case XSA_EVENT_DATA_DONE:
+ xsa_complete_request(1); /* The request succeeded. */
+ break;
+
+ case XSA_EVENT_ERROR:
+ ErrorMask = XSysAce_GetErrors(&SysAce);
+
+ xsysace_printerrcode(ErrorMask);
/* Check for errors that should reset the CompactFlash */
if (ErrorMask & (XSA_ER_CARD_RESET |
***************
*** 741,746 ****
--- 753,759 ----
// ppc_md.restart = old_restart;
}
+
static int __init
xsysace_init(void)
{
***************
*** 790,795 ****
--- 803,810 ----
if (stat != XST_SUCCESS) {
printk(KERN_ERR "%s: Could not send identify command.\n",
DEVICE_NAME);
+ if ( stat == XST_FAILURE )
+ xsysace_printerrcode( XSysAce_GetErrors(&SysAce) );
cleanup();
return -ENODEV;
}
*** xsysace_intr.c 28 Nov 2003 05:11:30 -0000 1.1
--- xsysace_intr.c 30 Mar 2005 08:05:57 -0000
***************
*** 58,64 ****
/************************** Function Prototypes ******************************/
static void HandleDataBuffer(XSysAce *InstancePtr, u32 StatusReg);
! static void DataComplete(XSysAce *InstancePtr);
/*****************************************************************************/
--- 58,64 ----
/************************** Function Prototypes ******************************/
static void HandleDataBuffer(XSysAce *InstancePtr, u32 StatusReg);
! static void DataComplete(XSysAce *InstancePtr, int notify);
/*****************************************************************************/
***************
*** 303,325 ****
static void HandleDataBuffer(XSysAce *InstancePtr, u32 StatusReg)
{
/* By default, transfer a whole data buffer */
! int BytesToTransfer = XSA_DATA_BUFFER_SIZE;
/*
* Check to see if number of bytes remaining is less than the data buffer
* size. If it is, we need to adjust the remaining bytes to transfer.
*/
! if (InstancePtr->NumRemaining < XSA_DATA_BUFFER_SIZE)
{
BytesToTransfer = InstancePtr->NumRemaining;
}
/*
* Transfer only one data buffer at a time, which is 32 bytes. Note that
* errors will be handled by an error interrupt occurring, so no need to
* check for them here.
*/
! if (StatusReg & XSA_SR_DATABUFMODE_MASK)
{
/*
* A write operation in progress, so if there is data remaining then
--- 303,332 ----
static void HandleDataBuffer(XSysAce *InstancePtr, u32 StatusReg)
{
/* By default, transfer a whole data buffer */
! int BytesToTransfer;
! int last_transfer;
/*
* Check to see if number of bytes remaining is less than the data buffer
* size. If it is, we need to adjust the remaining bytes to transfer.
*/
! if (InstancePtr->NumRemaining <= XSA_DATA_BUFFER_SIZE)
{
BytesToTransfer = InstancePtr->NumRemaining;
+ last_transfer = TRUE;
}
+ else
+ {
+ BytesToTransfer = XSA_DATA_BUFFER_SIZE;
+ last_transfer = FALSE;
+ }
/*
* Transfer only one data buffer at a time, which is 32 bytes. Note that
* errors will be handled by an error interrupt occurring, so no need to
* check for them here.
*/
! if ( (StatusReg & XSA_SR_DATABUFMODE_MASK) != 0 )
{
/*
* A write operation in progress, so if there is data remaining then
***************
*** 337,347 ****
*/
InstancePtr->NumRemaining -= BytesToTransfer;
InstancePtr->BufferPtr += BytesToTransfer;
}
else
! {
! /* Done writing data, so clean up */
! DataComplete(InstancePtr);
}
}
else
--- 344,358 ----
*/
InstancePtr->NumRemaining -= BytesToTransfer;
InstancePtr->BufferPtr += BytesToTransfer;
+
+ if ( last_transfer )
+ { /* Done writing data, so clean up */
+ DataComplete(InstancePtr, TRUE);
+ }
}
else
! { /* Spurius interrupt! It should never happens */
! DataComplete(InstancePtr, FALSE);
}
}
else
***************
*** 362,368 ****
if (InstancePtr->NumRemaining == 0)
{
/* Done reading data, so clean up */
! DataComplete(InstancePtr);
}
}
}
--- 373,379 ----
if (InstancePtr->NumRemaining == 0)
{
/* Done reading data, so clean up */
! DataComplete(InstancePtr, TRUE);
}
}
}
***************
*** 385,391 ****
* None.
*
******************************************************************************/
! static void DataComplete(XSysAce *InstancePtr)
{
InstancePtr->NumRequested = 0;
InstancePtr->NumRemaining = 0;
--- 396,402 ----
* None.
*
******************************************************************************/
! static void DataComplete(XSysAce *InstancePtr, int notify)
{
InstancePtr->NumRequested = 0;
InstancePtr->NumRemaining = 0;
***************
*** 408,415 ****
* to determine if an MPU JTAG config process has just completed. The
* CFG_DONE event is passed up later by the main interrupt handler.
*/
! if ((XSysAce_mGetControlReg(InstancePtr->BaseAddress)
! & XSA_CR_CFGSEL_MASK) == 0)
{
/* no JTAG configuration in progress */
InstancePtr->EventHandler(InstancePtr->EventRef, XSA_EVENT_DATA_DONE);
--- 419,425 ----
* to determine if an MPU JTAG config process has just completed. The
* CFG_DONE event is passed up later by the main interrupt handler.
*/
! if ( (XSysAce_mGetControlReg(InstancePtr->BaseAddress) & XSA_CR_CFGSEL_MASK) == 0 && notify )
{
/* no JTAG configuration in progress */
InstancePtr->EventHandler(InstancePtr->EventRef, XSA_EVENT_DATA_DONE);
*** xsysace_l.c 15 Feb 2005 22:44:29 -0000 1.2
--- xsysace_l.c 30 Mar 2005 08:06:02 -0000
***************
*** 35,40 ****
--- 35,41 ----
* Ver Who Date Changes
* ----- ---- -------- -----------------------------------------------
* 1.00a rpm 06/14/02 work in progress
+ * 1.00a rpm 02/17/04 Fixed WriteSector function command
* </pre>
*
******************************************************************************/
***************
*** 367,373 ****
/* Send a write command of one sector to the controller */
XSysAce_RegWrite16(BaseAddress + XSA_SCCR_OFFSET,
! XSA_SCCR_READDATA_MASK | 1);
/* Reset configuration controller (be sure to keep the lock) */
XSysAce_mOrControlReg(BaseAddress, XSA_CR_CFGRESET_MASK);
--- 368,374 ----
/* Send a write command of one sector to the controller */
XSysAce_RegWrite16(BaseAddress + XSA_SCCR_OFFSET,
! XSA_SCCR_WRITEDATA_MASK | 1);
/* Reset configuration controller (be sure to keep the lock) */
XSysAce_mOrControlReg(BaseAddress, XSA_CR_CFGRESET_MASK);