patch-2.4.19 linux-2.4.19/drivers/scsi/aic7xxx/aic7xxx_93cx6.c
Next file: linux-2.4.19/drivers/scsi/aic7xxx/aic7xxx_93cx6.h
Previous file: linux-2.4.19/drivers/scsi/aic7xxx/aic7xxx.seq
Back to the patch index
Back to the overall index
- Lines: 228
- Date:
Fri Aug 2 17:39:44 2002
- Orig file:
linux-2.4.18/drivers/scsi/aic7xxx/aic7xxx_93cx6.c
- Orig date:
Thu Oct 25 13:53:49 2001
diff -urN linux-2.4.18/drivers/scsi/aic7xxx/aic7xxx_93cx6.c linux-2.4.19/drivers/scsi/aic7xxx/aic7xxx_93cx6.c
@@ -28,9 +28,9 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
- * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#10 $
+ * $Id: //depot/aic7xxx/aic7xxx/aic7xxx_93cx6.c#15 $
*
- * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_93cx6.c,v 1.9 2000/11/10 20:13:41 gibbs Exp $
+ * $FreeBSD: src/sys/dev/aic7xxx/aic7xxx_93cx6.c,v 1.8.2.5 2002/04/29 19:36:31 gibbs Exp $
*/
/*
@@ -67,9 +67,15 @@
*
*/
+#ifdef __linux__
#include "aic7xxx_osm.h"
#include "aic7xxx_inline.h"
#include "aic7xxx_93cx6.h"
+#else
+#include <dev/aic7xxx/aic7xxx_osm.h>
+#include <dev/aic7xxx/aic7xxx_inline.h>
+#include <dev/aic7xxx/aic7xxx_93cx6.h>
+#endif
/*
* Right now, we only have to read the SEEPROM. But we make it easier to
@@ -77,9 +83,13 @@
*/
static struct seeprom_cmd {
uint8_t len;
- uint8_t bits[3];
+ uint8_t bits[9];
} seeprom_read = {3, {1, 1, 0}};
+static struct seeprom_cmd seeprom_ewen = {9, {1, 0, 0, 1, 1, 0, 0, 0, 0}};
+static struct seeprom_cmd seeprom_ewds = {9, {1, 0, 0, 0, 0, 0, 0, 0, 0}};
+static struct seeprom_cmd seeprom_write = {3, {1, 0, 1}};
+
/*
* Wait for the SEERDY to go high; about 800 ns.
*/
@@ -90,15 +100,55 @@
(void)SEEPROM_INB(sd); /* Clear clock */
/*
+ * Send a START condition and the given command
+ */
+static void
+send_seeprom_cmd(struct seeprom_descriptor *sd, struct seeprom_cmd *cmd)
+{
+ uint8_t temp;
+ int i = 0;
+
+ /* Send chip select for one clock cycle. */
+ temp = sd->sd_MS ^ sd->sd_CS;
+ SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
+ CLOCK_PULSE(sd, sd->sd_RDY);
+
+ for (i = 0; i < cmd->len; i++) {
+ if (cmd->bits[i] != 0)
+ temp ^= sd->sd_DO;
+ SEEPROM_OUTB(sd, temp);
+ CLOCK_PULSE(sd, sd->sd_RDY);
+ SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
+ CLOCK_PULSE(sd, sd->sd_RDY);
+ if (cmd->bits[i] != 0)
+ temp ^= sd->sd_DO;
+ }
+}
+
+/*
+ * Clear CS put the chip in the reset state, where it can wait for new commands.
+ */
+static void
+reset_seeprom(struct seeprom_descriptor *sd)
+{
+ uint8_t temp;
+
+ temp = sd->sd_MS;
+ SEEPROM_OUTB(sd, temp);
+ CLOCK_PULSE(sd, sd->sd_RDY);
+ SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
+ CLOCK_PULSE(sd, sd->sd_RDY);
+ SEEPROM_OUTB(sd, temp);
+ CLOCK_PULSE(sd, sd->sd_RDY);
+}
+
+/*
* Read the serial EEPROM and returns 1 if successful and 0 if
* not successful.
*/
int
-read_seeprom(sd, buf, start_addr, count)
- struct seeprom_descriptor *sd;
- uint16_t *buf;
- u_int start_addr;
- u_int count;
+ahc_read_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
+ u_int start_addr, u_int count)
{
int i = 0;
u_int k = 0;
@@ -110,26 +160,14 @@
* will range from 0 to count-1.
*/
for (k = start_addr; k < count + start_addr; k++) {
- /* Send chip select for one clock cycle. */
- temp = sd->sd_MS ^ sd->sd_CS;
- SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
- CLOCK_PULSE(sd, sd->sd_RDY);
-
/*
* Now we're ready to send the read command followed by the
* address of the 16-bit register we want to read.
*/
- for (i = 0; i < seeprom_read.len; i++) {
- if (seeprom_read.bits[i] != 0)
- temp ^= sd->sd_DO;
- SEEPROM_OUTB(sd, temp);
- CLOCK_PULSE(sd, sd->sd_RDY);
- SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
- CLOCK_PULSE(sd, sd->sd_RDY);
- if (seeprom_read.bits[i] != 0)
- temp ^= sd->sd_DO;
- }
+ send_seeprom_cmd(sd, &seeprom_read);
+
/* Send the 6 or 8 bit address (MSB first, LSB last). */
+ temp = sd->sd_MS ^ sd->sd_CS;
for (i = (sd->sd_chip - 1); i >= 0; i--) {
if ((k & (1 << i)) != 0)
temp ^= sd->sd_DO;
@@ -161,13 +199,7 @@
buf[k - start_addr] = v;
/* Reset the chip select for the next command cycle. */
- temp = sd->sd_MS;
- SEEPROM_OUTB(sd, temp);
- CLOCK_PULSE(sd, sd->sd_RDY);
- SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
- CLOCK_PULSE(sd, sd->sd_RDY);
- SEEPROM_OUTB(sd, temp);
- CLOCK_PULSE(sd, sd->sd_RDY);
+ reset_seeprom(sd);
}
#ifdef AHC_DUMP_EEPROM
printf("\nSerial EEPROM:\n\t");
@@ -182,8 +214,77 @@
return (1);
}
+/*
+ * Write the serial EEPROM and return 1 if successful and 0 if
+ * not successful.
+ */
+int
+ahc_write_seeprom(struct seeprom_descriptor *sd, uint16_t *buf,
+ u_int start_addr, u_int count)
+{
+ uint16_t v;
+ uint8_t temp;
+ int i, k;
+
+ /* Place the chip into write-enable mode */
+ send_seeprom_cmd(sd, &seeprom_ewen);
+ reset_seeprom(sd);
+
+ /* Write all requested data out to the seeprom. */
+ temp = sd->sd_MS ^ sd->sd_CS;
+ for (k = start_addr; k < count + start_addr; k++) {
+ /* Send the write command */
+ send_seeprom_cmd(sd, &seeprom_write);
+
+ /* Send the 6 or 8 bit address (MSB first). */
+ for (i = (sd->sd_chip - 1); i >= 0; i--) {
+ if ((k & (1 << i)) != 0)
+ temp ^= sd->sd_DO;
+ SEEPROM_OUTB(sd, temp);
+ CLOCK_PULSE(sd, sd->sd_RDY);
+ SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
+ CLOCK_PULSE(sd, sd->sd_RDY);
+ if ((k & (1 << i)) != 0)
+ temp ^= sd->sd_DO;
+ }
+
+ /* Write the 16 bit value, MSB first */
+ v = buf[k - start_addr];
+ for (i = 15; i >= 0; i--) {
+ if ((v & (1 << i)) != 0)
+ temp ^= sd->sd_DO;
+ SEEPROM_OUTB(sd, temp);
+ CLOCK_PULSE(sd, sd->sd_RDY);
+ SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
+ CLOCK_PULSE(sd, sd->sd_RDY);
+ if ((v & (1 << i)) != 0)
+ temp ^= sd->sd_DO;
+ }
+
+ /* Wait for the chip to complete the write */
+ temp = sd->sd_MS;
+ SEEPROM_OUTB(sd, temp);
+ CLOCK_PULSE(sd, sd->sd_RDY);
+ temp = sd->sd_MS ^ sd->sd_CS;
+ do {
+ SEEPROM_OUTB(sd, temp);
+ CLOCK_PULSE(sd, sd->sd_RDY);
+ SEEPROM_OUTB(sd, temp ^ sd->sd_CK);
+ CLOCK_PULSE(sd, sd->sd_RDY);
+ } while ((SEEPROM_DATA_INB(sd) & sd->sd_DI) == 0);
+
+ reset_seeprom(sd);
+ }
+
+ /* Put the chip back into write-protect mode */
+ send_seeprom_cmd(sd, &seeprom_ewds);
+ reset_seeprom(sd);
+
+ return (1);
+}
+
int
-verify_cksum(struct seeprom_config *sc)
+ahc_verify_cksum(struct seeprom_config *sc)
{
int i;
int maxaddr;
FUNET's LINUX-ADM group, linux-adm@nic.funet.fi
TCL-scripts by Sam Shen (who was at: slshen@lbl.gov)