--- cfi.c.orig	2009-01-16 08:02:24.000000000 +0100
+++ cfi.c	2009-04-14 15:33:09.000000000 +0200
@@ -309,6 +309,36 @@
 	return status;
 }
 
+
+int cfi_spansion_wait_write(flash_bank_t *bank, u32 address, u32 check, int timeout)
+{
+	//wait until check is returned from flash.
+	time_t curtime;
+	time_t timer;
+	u32 val;
+	target_t *target = bank->target;
+
+	timer=(timeout/1000) +1;  //calculate timeout value
+
+	curtime=time(NULL);
+	
+	do
+	  {
+	  target->type->read_memory(target, address, bank->bus_width, 1, (u8*) &val);
+	  
+	  if ((time(NULL)-curtime)>timer) 
+	    {
+	    return(ERROR_FLASH_BUSY);
+	    }
+	  keep_alive();	//keep sending poll messages to GDB if necessary
+	  }
+	while (val!=check);
+	
+	return ERROR_OK;
+
+}
+
+
 int cfi_spansion_wait_status_busy(flash_bank_t *bank, int timeout)
 {
 	u8 status, oldstatus;
@@ -1589,7 +1619,7 @@
 	u8 command[8];
 
 	/* Calculate buffer size and boundary mask */
-	u32 buffersize = 1UL << cfi_info->max_buf_write_size;
+	u32 buffersize = (1UL << cfi_info->max_buf_write_size) * (bank->bus_width / bank->chip_width);
 	u32 buffermask = buffersize-1;
 	u32 bufferwsize;
 
@@ -1609,6 +1639,9 @@
 		return ERROR_FLASH_OPERATION_FAILED;
 	}
 
+	bufferwsize/=(bank->bus_width / bank->chip_width);
+
+
 	/* Check for valid size */
 	if (wordcount > bufferwsize)
 	{
@@ -1673,6 +1706,7 @@
 int cfi_spansion_write_word(struct flash_bank_s *bank, u8 *word, u32 address)
 {
 	int retval;
+	u32 check_val, check_address;
 	cfi_flash_bank_t *cfi_info = bank->driver_priv;
 	cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext;
 	target_t *target = bank->target;
@@ -1701,7 +1735,12 @@
 		return retval;
 	}
 
-	if (cfi_spansion_wait_status_busy(bank, 1000 * (1 << cfi_info->word_write_timeout_max)) != ERROR_OK)
+	check_val=*((u32*)word);	//Todo: check for endianess
+	check_address=address;
+
+
+	//if (cfi_spansion_wait_status_busy(bank, 1000 * (1 << cfi_info->word_write_timeout_max)) != ERROR_OK)
+	if (cfi_spansion_wait_write(bank, check_address,  check_val, 1000 * (1 << cfi_info->word_write_timeout_max)) != ERROR_OK)
 	{
 		cfi_command(bank, 0xf0, command);
 		if((retval = target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command)) != ERROR_OK)
@@ -1719,13 +1758,15 @@
 int cfi_spansion_write_words(struct flash_bank_s *bank, u8 *word, u32 wordcount, u32 address)
 {
 	int retval;
+	u32 check_val, check_address;
+	
 	cfi_flash_bank_t *cfi_info = bank->driver_priv;
 	target_t *target = bank->target;
 	u8 command[8];
 	cfi_spansion_pri_ext_t *pri_ext = cfi_info->pri_ext;
 
 	/* Calculate buffer size and boundary mask */
-	u32 buffersize = 1UL << cfi_info->max_buf_write_size;
+	u32 buffersize = (1UL << cfi_info->max_buf_write_size) * (bank->bus_width / bank->chip_width);
 	u32 buffermask = buffersize-1;
 	u32 bufferwsize;
 
@@ -1745,6 +1786,8 @@
 		return ERROR_FLASH_OPERATION_FAILED;
 	}
 
+	bufferwsize/=(bank->bus_width / bank->chip_width);
+
 	/* Check for valid size */
 	if (wordcount > bufferwsize)
 	{
@@ -1784,6 +1827,9 @@
 		return retval;
 	}
 
+	check_val=*((u32*)word);	//Todo: check for endianess
+	check_address=address;
+
 	/* Commit write operation */
 	cfi_command(bank, 0x29, command);
 	if((retval = target->type->write_memory(target, address, bank->bus_width, 1, command)) != ERROR_OK)
@@ -1791,7 +1837,10 @@
 		return retval;
 	}
 
-	if (cfi_spansion_wait_status_busy(bank, 1000 * (1 << cfi_info->word_write_timeout_max)) != ERROR_OK)
+	
+
+//	if (cfi_spansion_wait_status_busy(bank, 1000 * (1 << cfi_info->word_write_timeout_max)) != ERROR_OK)
+	if (cfi_spansion_wait_write(bank, check_address,  check_val, 1000 * (1 << cfi_info->word_write_timeout_max)) != ERROR_OK)
 	{
 		cfi_command(bank, 0xf0, command);
 		if((retval = target->type->write_memory(target, flash_address(bank, 0, 0x0), bank->bus_width, 1, command)) != ERROR_OK)
@@ -1946,7 +1995,8 @@
 	{
 		if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
 		{
-			u32 buffersize = 1UL << cfi_info->max_buf_write_size;
+			//adjust buffersize for chip width
+			u32 buffersize = (1UL << cfi_info->max_buf_write_size) * (bank->bus_width / bank->chip_width);
 			u32 buffermask = buffersize-1;
 			u32 bufferwsize;
 
@@ -1959,6 +2009,8 @@
 				LOG_ERROR("Unsupported chip width %d", bank->chip_width);
 				return ERROR_FLASH_OPERATION_FAILED;
 			}
+			
+			bufferwsize/=(bank->bus_width / bank->chip_width);
 
 			/* fall back to memory writes */
 			while (count >= bank->bus_width)
