summaryrefslogtreecommitdiff
path: root/linux/src/drivers
diff options
context:
space:
mode:
authorThomas Schwinge <tschwinge@gnu.org>2006-10-08 13:57:26 +0000
committerThomas Schwinge <tschwinge@gnu.org>2009-06-18 00:26:43 +0200
commit28a9a30f1be07f5262957d879a6a9b311605fae8 (patch)
treed8f8be2eedbc9f445a41efb6a372cade8b1710f0 /linux/src/drivers
parent5bde205d1b42d031e6bb1422337ab9a37752b2e7 (diff)
2006-10-08 Thomas Schwinge <tschwinge@gnu.org>
* linux/dev/drivers/scsi/seagate.c: Move file... * linux/src/drivers/scsi/seagate.c: ... here.
Diffstat (limited to 'linux/src/drivers')
-rw-r--r--linux/src/drivers/scsi/seagate.c186
1 files changed, 55 insertions, 131 deletions
diff --git a/linux/src/drivers/scsi/seagate.c b/linux/src/drivers/scsi/seagate.c
index 9e94274..3dd8f9d 100644
--- a/linux/src/drivers/scsi/seagate.c
+++ b/linux/src/drivers/scsi/seagate.c
@@ -46,6 +46,12 @@
* transfer rate if handshaking isn't working correctly.
*/
+#ifdef MACH
+#define ARBITRATE
+#define SLOW_HANDSHAKE
+#define FAST32
+#endif
+
#include <linux/module.h>
#include <asm/io.h>
@@ -136,6 +142,8 @@ static unsigned char irq = IRQ;
#define STATUS (*(volatile unsigned char *) st0x_cr_sr)
#define CONTROL STATUS
#define DATA (*(volatile unsigned char *) st0x_dr)
+#define WRITE_CONTROL(d) { writeb((d), st0x_cr_sr); }
+#define WRITE_DATA(d) { writeb((d), st0x_dr); }
void st0x_setup (char *str, int *ints) {
controller_type = SEAGATE;
@@ -557,7 +565,7 @@ int seagate_st0x_queue_command (Scsi_Cmnd * SCpnt, void (*done)(Scsi_Cmnd *))
done_fn = done;
current_target = SCpnt->target;
current_lun = SCpnt->lun;
- (const void *) current_cmnd = SCpnt->cmnd;
+ current_cmnd = SCpnt->cmnd;
current_data = (unsigned char *) SCpnt->request_buffer;
current_bufflen = SCpnt->request_bufflen;
SCint = SCpnt;
@@ -1091,24 +1099,19 @@ if (fast && transfersize && !(len % transfersize) && (len >= transfersize)
SCint->transfersize, len, data);
#endif
- __asm__("
- cld;
-"
+ {
#ifdef FAST32
-" shr $2, %%ecx;
-1: lodsl;
- movl %%eax, (%%edi);
-"
+ unsigned int *iop = phys_to_virt (st0x_dr);
+ const unsigned int *dp = (unsigned int *) data;
+ int xferlen = transfersize >> 2;
#else
-"1: lodsb;
- movb %%al, (%%edi);
-"
+ unsigned char *iop = phys_to_virt (st0x_dr);
+ const unsigned char *dp = data;
+ int xferlen = transfersize;
#endif
-" loop 1b;" : :
- /* input */
- "D" (st0x_dr), "S" (data), "c" (SCint->transfersize) :
- /* clobbered */
- "eax", "ecx", "esi" );
+ for (; xferlen; --xferlen)
+ *iop = *dp++;
+ }
len -= transfersize;
data += transfersize;
@@ -1127,55 +1130,20 @@ if (fast && transfersize && !(len % transfersize) && (len >= transfersize)
* We loop as long as we are in a data out phase, there is data to send,
* and BSY is still active.
*/
- __asm__ (
-
-/*
- Local variables :
- len = ecx
- data = esi
- st0x_cr_sr = ebx
- st0x_dr = edi
-
- Test for any data here at all.
-*/
- "\torl %%ecx, %%ecx
- jz 2f
- cld
-
- movl " SYMBOL_NAME_STR(st0x_cr_sr) ", %%ebx
- movl " SYMBOL_NAME_STR(st0x_dr) ", %%edi
-
-1: movb (%%ebx), %%al\n"
-/*
- Test for BSY
-*/
-
- "\ttest $1, %%al
- jz 2f\n"
-
-/*
- Test for data out phase - STATUS & REQ_MASK should be REQ_DATAOUT, which is 0.
-*/
- "\ttest $0xe, %%al
- jnz 2f \n"
-/*
- Test for REQ
-*/
- "\ttest $0x10, %%al
- jz 1b
- lodsb
- movb %%al, (%%edi)
- loop 1b
-
-2:
- ":
-/* output */
-"=S" (data), "=c" (len) :
-/* input */
-"0" (data), "1" (len) :
-/* clobbered */
-"eax", "ebx", "edi");
+ while (len)
+ {
+ unsigned char stat;
+
+ stat = STATUS;
+ if (!(stat & STAT_BSY) || ((stat & REQ_MASK) != REQ_DATAOUT))
+ break;
+ if (stat & STAT_REQ)
+ {
+ WRITE_DATA (*data++);
+ --len;
+ }
+ }
}
if (!len && nobuffs) {
@@ -1217,25 +1185,19 @@ if (fast && transfersize && !(len % transfersize) && (len >= transfersize)
" len = %d, data = %08x\n", hostno, SCint->underflow,
SCint->transfersize, len, data);
#endif
- __asm__("
- cld;
-"
+ {
#ifdef FAST32
-" shr $2, %%ecx;
-1: movl (%%esi), %%eax;
- stosl;
-"
+ const unsigned int *iop = phys_to_virt (st0x_dr);
+ unsigned int *dp = (unsigned int *) data;
+ int xferlen = len >> 2;
#else
-"1: movb (%%esi), %%al;
- stosb;
-"
+ const unsigned char *iop = phys_to_virt (st0x_dr);
+ unsigned char *dp = data;
+ int xferlen = len;
#endif
-
-" loop 1b;" : :
- /* input */
- "S" (st0x_dr), "D" (data), "c" (SCint->transfersize) :
- /* clobbered */
- "eax", "ecx", "edi");
+ for (; xferlen; --xferlen)
+ *dp++ = *iop;
+ }
len -= transfersize;
data += transfersize;
@@ -1265,57 +1227,19 @@ if (fast && transfersize && !(len % transfersize) && (len >= transfersize)
* and BSY is still active
*/
- __asm__ (
-/*
- Local variables :
- ecx = len
- edi = data
- esi = st0x_cr_sr
- ebx = st0x_dr
-
- Test for room to read
-*/
- "\torl %%ecx, %%ecx
- jz 2f
-
- cld
- movl " SYMBOL_NAME_STR(st0x_cr_sr) ", %%esi
- movl " SYMBOL_NAME_STR(st0x_dr) ", %%ebx
-
-1: movb (%%esi), %%al\n"
-/*
- Test for BSY
-*/
-
- "\ttest $1, %%al
- jz 2f\n"
-
-/*
- Test for data in phase - STATUS & REQ_MASK should be REQ_DATAIN, = STAT_IO, which is 4.
-*/
- "\tmovb $0xe, %%ah
- andb %%al, %%ah
- cmpb $0x04, %%ah
- jne 2f\n"
-
-/*
- Test for REQ
-*/
- "\ttest $0x10, %%al
- jz 1b
-
- movb (%%ebx), %%al
- stosb
- loop 1b\n"
-
-"2:\n"
- :
-/* output */
-"=D" (data), "=c" (len) :
-/* input */
-"0" (data), "1" (len) :
-/* clobbered */
-"eax","ebx", "esi");
+ while (len)
+ {
+ unsigned char stat;
+
+ stat = STATUS;
+ if (!(stat & STAT_BSY) || ((stat & REQ_MASK) != REQ_DATAIN))
+ break;
+ if (stat & STAT_REQ)
+ {
+ *data++ = DATA;
+ --len;
+ }
+ }
#if (DEBUG & PHASE_DATAIN)
printk("scsi%d: transfered -= %d\n", hostno, len);