|
Lines 1-4
Link Here
|
| 1 |
/* |
1 |
/* |
| 2 |
* Copyright (C) 1997 Wu Ching Chen |
2 |
* Copyright (C) 1997 Wu Ching Chen |
| 3 |
* 2.1.x update (C) 1998 Krzysztof G. Baranowski |
3 |
* 2.1.x update (C) 1998 Krzysztof G. Baranowski |
| 4 |
* 2.5.x update (C) 2002 Red Hat <alan@redhat.com> |
4 |
* 2.5.x update (C) 2002 Red Hat <alan@redhat.com> |
|
Lines 13-21
Link Here
|
| 13 |
* fix disconnect bug 2000/12/21 |
13 |
* fix disconnect bug 2000/12/21 |
| 14 |
* support atp880 chip lvd u160 2001/05/15 |
14 |
* support atp880 chip lvd u160 2001/05/15 |
| 15 |
* fix prd table bug 2001/09/12 (7.1) |
15 |
* fix prd table bug 2001/09/12 (7.1) |
| 16 |
* |
|
|
| 17 |
* atp885 support add by ACARD Hao Ping Lian 2005/01/05 |
| 18 |
*/ |
16 |
*/ |
|
|
17 |
|
| 19 |
#include <linux/module.h> |
18 |
#include <linux/module.h> |
| 20 |
#include <linux/init.h> |
19 |
#include <linux/init.h> |
| 21 |
#include <linux/interrupt.h> |
20 |
#include <linux/interrupt.h> |
|
Lines 39-92
Link Here
|
| 39 |
#include "atp870u.h" |
38 |
#include "atp870u.h" |
| 40 |
|
39 |
|
| 41 |
static struct scsi_host_template atp870u_template; |
40 |
static struct scsi_host_template atp870u_template; |
| 42 |
static void send_s870(struct atp_unit *dev,unsigned char c); |
41 |
static void send_s870(struct Scsi_Host *host); |
| 43 |
static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c); |
|
|
| 44 |
static void tscam_885(void); |
| 45 |
|
42 |
|
| 46 |
static irqreturn_t atp870u_intr_handle(int irq, void *dev_id, struct pt_regs *regs) |
43 |
|
|
|
44 |
static irqreturn_t atp870u_intr_handle(int irq, void *dev_id, |
| 45 |
struct pt_regs *regs) |
| 47 |
{ |
46 |
{ |
| 48 |
unsigned long flags; |
47 |
unsigned long flags; |
| 49 |
unsigned short int tmpcip, id; |
48 |
unsigned short int tmpcip, id; |
| 50 |
unsigned char i, j, c, target_id, lun,cmdp; |
49 |
unsigned char i, j, target_id, lun; |
| 51 |
unsigned char *prd; |
50 |
unsigned char *prd; |
| 52 |
struct scsi_cmnd *workreq; |
51 |
struct scsi_cmnd *workrequ; |
| 53 |
unsigned int workport, tmport, tmport1; |
52 |
unsigned int workportu, tmport; |
| 54 |
unsigned long adrcnt, k; |
53 |
unsigned long adrcntu, k; |
| 55 |
#ifdef ED_DBGP |
|
|
| 56 |
unsigned long l; |
| 57 |
#endif |
| 58 |
int errstus; |
54 |
int errstus; |
| 59 |
struct Scsi_Host *host = dev_id; |
55 |
struct Scsi_Host *host = dev_id; |
| 60 |
struct atp_unit *dev = (struct atp_unit *)&host->hostdata; |
56 |
struct atp_unit *dev = (struct atp_unit *)&host->hostdata; |
| 61 |
|
57 |
|
| 62 |
for (c = 0; c < 2; c++) { |
58 |
dev->in_int = 1; |
| 63 |
tmport = dev->ioport[c] + 0x1f; |
59 |
workportu = dev->ioport; |
|
|
60 |
tmport = workportu; |
| 61 |
|
| 62 |
if (dev->working != 0) { |
| 63 |
tmport += 0x1f; |
| 64 |
j = inb(tmport); |
64 |
j = inb(tmport); |
| 65 |
if ((j & 0x80) != 0) |
65 |
if ((j & 0x80) == 0) { |
| 66 |
{ |
66 |
dev->in_int = 0; |
| 67 |
goto ch_sel; |
67 |
return IRQ_NONE; |
| 68 |
} |
68 |
} |
| 69 |
dev->in_int[c] = 0; |
69 |
|
| 70 |
} |
70 |
tmpcip = dev->pciport; |
| 71 |
return IRQ_NONE; |
71 |
if ((inb(tmpcip) & 0x08) != 0) { |
| 72 |
ch_sel: |
|
|
| 73 |
#ifdef ED_DBGP |
| 74 |
printk("atp870u_intr_handle enter\n"); |
| 75 |
#endif |
| 76 |
dev->in_int[c] = 1; |
| 77 |
cmdp = inb(dev->ioport[c] + 0x10); |
| 78 |
workport = dev->ioport[c]; |
| 79 |
if (dev->working[c] != 0) { |
| 80 |
if (dev->dev_id == ATP885_DEVID) { |
| 81 |
tmport1 = workport + 0x16; |
| 82 |
if ((inb(tmport1) & 0x80) == 0) |
| 83 |
outb((inb(tmport1) | 0x80), tmport1); |
| 84 |
} |
| 85 |
tmpcip = dev->pciport[c]; |
| 86 |
if ((inb(tmpcip) & 0x08) != 0) |
| 87 |
{ |
| 88 |
tmpcip += 0x2; |
72 |
tmpcip += 0x2; |
| 89 |
for (k=0; k < 1000; k++) { |
73 |
for (k = 0; k < 1000; k++) { |
| 90 |
if ((inb(tmpcip) & 0x08) == 0) { |
74 |
if ((inb(tmpcip) & 0x08) == 0) { |
| 91 |
goto stop_dma; |
75 |
goto stop_dma; |
| 92 |
} |
76 |
} |
|
Lines 96-119
Link Here
|
| 96 |
} |
80 |
} |
| 97 |
} |
81 |
} |
| 98 |
stop_dma: |
82 |
stop_dma: |
| 99 |
tmpcip = dev->pciport[c]; |
83 |
tmpcip = dev->pciport; |
| 100 |
outb(0x00, tmpcip); |
84 |
outb(0x00, tmpcip); |
| 101 |
tmport -= 0x08; |
85 |
tmport -= 0x08; |
| 102 |
|
86 |
|
| 103 |
i = inb(tmport); |
87 |
i = inb(tmport); |
| 104 |
|
|
|
| 105 |
if (dev->dev_id == ATP885_DEVID) { |
| 106 |
tmpcip += 2; |
| 107 |
outb(0x06, tmpcip); |
| 108 |
tmpcip -= 2; |
| 109 |
} |
| 110 |
|
88 |
|
| 111 |
tmport -= 0x02; |
89 |
tmport -= 0x02; |
| 112 |
target_id = inb(tmport); |
90 |
target_id = inb(tmport); |
| 113 |
tmport += 0x02; |
91 |
tmport += 0x02; |
| 114 |
|
92 |
|
| 115 |
/* |
93 |
/* |
| 116 |
* Remap wide devices onto id numbers |
94 |
* Remap wide devices onto id numbers |
| 117 |
*/ |
95 |
*/ |
| 118 |
|
96 |
|
| 119 |
if ((target_id & 0x40) != 0) { |
97 |
if ((target_id & 0x40) != 0) { |
|
Lines 123-582
Link Here
|
| 123 |
} |
101 |
} |
| 124 |
|
102 |
|
| 125 |
if ((j & 0x40) != 0) { |
103 |
if ((j & 0x40) != 0) { |
| 126 |
if (dev->last_cmd[c] == 0xff) { |
104 |
if (dev->last_cmd == 0xff) { |
| 127 |
dev->last_cmd[c] = target_id; |
105 |
dev->last_cmd = target_id; |
| 128 |
} |
|
|
| 129 |
dev->last_cmd[c] |= 0x40; |
| 130 |
} |
| 131 |
if (dev->dev_id == ATP885_DEVID) |
| 132 |
dev->r1f[c][target_id] |= j; |
| 133 |
#ifdef ED_DBGP |
| 134 |
printk("atp870u_intr_handle status = %x\n",i); |
| 135 |
#endif |
| 136 |
if (i == 0x85) { |
| 137 |
if ((dev->last_cmd[c] & 0xf0) != 0x40) { |
| 138 |
dev->last_cmd[c] = 0xff; |
| 139 |
} |
| 140 |
if (dev->dev_id == ATP885_DEVID) { |
| 141 |
tmport -= 0x05; |
| 142 |
adrcnt = 0; |
| 143 |
((unsigned char *) &adrcnt)[2] = inb(tmport++); |
| 144 |
((unsigned char *) &adrcnt)[1] = inb(tmport++); |
| 145 |
((unsigned char *) &adrcnt)[0] = inb(tmport); |
| 146 |
if (dev->id[c][target_id].last_len != adrcnt) |
| 147 |
{ |
| 148 |
k = dev->id[c][target_id].last_len; |
| 149 |
k -= adrcnt; |
| 150 |
dev->id[c][target_id].tran_len = k; |
| 151 |
dev->id[c][target_id].last_len = adrcnt; |
| 152 |
} |
| 153 |
#ifdef ED_DBGP |
| 154 |
printk("tmport = %x dev->id[c][target_id].last_len = %d dev->id[c][target_id].tran_len = %d\n",tmport,dev->id[c][target_id].last_len,dev->id[c][target_id].tran_len); |
| 155 |
#endif |
| 156 |
} |
106 |
} |
|
|
107 |
dev->last_cmd |= 0x40; |
| 108 |
} |
| 157 |
|
109 |
|
|
|
110 |
if (i == 0x85) { |
| 111 |
if ((dev->last_cmd & 0xf0) != 0x40) { |
| 112 |
dev->last_cmd = 0xff; |
| 113 |
} |
| 158 |
/* |
114 |
/* |
| 159 |
* Flip wide |
115 |
* Flip wide |
| 160 |
*/ |
116 |
*/ |
| 161 |
if (dev->wide_id[c] != 0) { |
117 |
if (dev->wide_idu != 0) { |
| 162 |
tmport = workport + 0x1b; |
118 |
tmport = workportu + 0x1b; |
| 163 |
outb(0x01, tmport); |
119 |
outb(0x01, tmport); |
| 164 |
while ((inb(tmport) & 0x01) != 0x01) { |
120 |
while ((inb(tmport) & 0x01) != 0x01) { |
| 165 |
outb(0x01, tmport); |
121 |
outb(0x01, tmport); |
| 166 |
} |
122 |
} |
| 167 |
} |
123 |
} |
| 168 |
/* |
124 |
/* |
| 169 |
* Issue more commands |
125 |
* Issue more commands |
| 170 |
*/ |
126 |
*/ |
| 171 |
spin_lock_irqsave(dev->host->host_lock, flags); |
127 |
spin_lock_irqsave(dev->host->host_lock, flags); |
| 172 |
if (((dev->quhd[c] != dev->quend[c]) || (dev->last_cmd[c] != 0xff)) && |
128 |
if (((dev->quhdu != dev->quendu) || (dev->last_cmd != 0xff)) && (dev->in_snd == 0)) { |
| 173 |
(dev->in_snd[c] == 0)) { |
129 |
send_s870(host); |
| 174 |
#ifdef ED_DBGP |
|
|
| 175 |
printk("Call sent_s870\n"); |
| 176 |
#endif |
| 177 |
send_s870(dev,c); |
| 178 |
} |
130 |
} |
| 179 |
spin_unlock_irqrestore(dev->host->host_lock, flags); |
131 |
spin_unlock_irqrestore(dev->host->host_lock, flags); |
| 180 |
/* |
132 |
/* |
| 181 |
* Done |
133 |
* Done |
| 182 |
*/ |
134 |
*/ |
| 183 |
dev->in_int[c] = 0; |
135 |
dev->in_int = 0; |
| 184 |
#ifdef ED_DBGP |
136 |
goto out; |
| 185 |
printk("Status 0x85 return\n"); |
|
|
| 186 |
#endif |
| 187 |
goto handled; |
| 188 |
} |
137 |
} |
| 189 |
|
138 |
|
| 190 |
if (i == 0x40) { |
139 |
if (i == 0x40) { |
| 191 |
dev->last_cmd[c] |= 0x40; |
140 |
dev->last_cmd |= 0x40; |
| 192 |
dev->in_int[c] = 0; |
141 |
dev->in_int = 0; |
| 193 |
goto handled; |
142 |
goto out; |
| 194 |
} |
143 |
} |
| 195 |
|
144 |
|
| 196 |
if (i == 0x21) { |
145 |
if (i == 0x21) { |
| 197 |
if ((dev->last_cmd[c] & 0xf0) != 0x40) { |
146 |
if ((dev->last_cmd & 0xf0) != 0x40) { |
| 198 |
dev->last_cmd[c] = 0xff; |
147 |
dev->last_cmd = 0xff; |
| 199 |
} |
148 |
} |
| 200 |
tmport -= 0x05; |
149 |
tmport -= 0x05; |
| 201 |
adrcnt = 0; |
150 |
adrcntu = 0; |
| 202 |
((unsigned char *) &adrcnt)[2] = inb(tmport++); |
151 |
((unsigned char *) &adrcntu)[2] = inb(tmport++); |
| 203 |
((unsigned char *) &adrcnt)[1] = inb(tmport++); |
152 |
((unsigned char *) &adrcntu)[1] = inb(tmport++); |
| 204 |
((unsigned char *) &adrcnt)[0] = inb(tmport); |
153 |
((unsigned char *) &adrcntu)[0] = inb(tmport); |
| 205 |
k = dev->id[c][target_id].last_len; |
154 |
k = dev->id[target_id].last_lenu; |
| 206 |
k -= adrcnt; |
155 |
k -= adrcntu; |
| 207 |
dev->id[c][target_id].tran_len = k; |
156 |
dev->id[target_id].tran_lenu = k; |
| 208 |
dev->id[c][target_id].last_len = adrcnt; |
157 |
dev->id[target_id].last_lenu = adrcntu; |
| 209 |
tmport -= 0x04; |
158 |
tmport -= 0x04; |
| 210 |
outb(0x41, tmport); |
159 |
outb(0x41, tmport); |
| 211 |
tmport += 0x08; |
160 |
tmport += 0x08; |
| 212 |
outb(0x08, tmport); |
161 |
outb(0x08, tmport); |
| 213 |
dev->in_int[c] = 0; |
162 |
dev->in_int = 0; |
| 214 |
goto handled; |
163 |
goto out; |
| 215 |
} |
|
|
| 216 |
|
| 217 |
if (dev->dev_id == ATP885_DEVID) { |
| 218 |
if ((i == 0x4c) || (i == 0x4d) || (i == 0x8c) || (i == 0x8d)) { |
| 219 |
if ((i == 0x4c) || (i == 0x8c)) |
| 220 |
i=0x48; |
| 221 |
else |
| 222 |
i=0x49; |
| 223 |
} |
| 224 |
|
| 225 |
} |
164 |
} |
| 226 |
if ((i == 0x80) || (i == 0x8f)) { |
165 |
if ((i == 0x80) || (i == 0x8f)) { |
| 227 |
#ifdef ED_DBGP |
|
|
| 228 |
printk(KERN_DEBUG "Device reselect\n"); |
| 229 |
#endif |
| 230 |
lun = 0; |
166 |
lun = 0; |
| 231 |
tmport -= 0x07; |
167 |
tmport -= 0x07; |
| 232 |
if (cmdp == 0x44 || i==0x80) { |
168 |
j = inb(tmport); |
|
|
169 |
if (j == 0x44 || i == 0x80) { |
| 233 |
tmport += 0x0d; |
170 |
tmport += 0x0d; |
| 234 |
lun = inb(tmport) & 0x07; |
171 |
lun = inb(tmport) & 0x07; |
| 235 |
} else { |
172 |
} else { |
| 236 |
if ((dev->last_cmd[c] & 0xf0) != 0x40) { |
173 |
if ((dev->last_cmd & 0xf0) != 0x40) { |
| 237 |
dev->last_cmd[c] = 0xff; |
174 |
dev->last_cmd = 0xff; |
| 238 |
} |
175 |
} |
| 239 |
if (cmdp == 0x41) { |
176 |
if (j == 0x41) { |
| 240 |
#ifdef ED_DBGP |
|
|
| 241 |
printk("cmdp = 0x41\n"); |
| 242 |
#endif |
| 243 |
tmport += 0x02; |
177 |
tmport += 0x02; |
| 244 |
adrcnt = 0; |
178 |
adrcntu = 0; |
| 245 |
((unsigned char *) &adrcnt)[2] = inb(tmport++); |
179 |
((unsigned char *) &adrcntu)[2] = inb(tmport++); |
| 246 |
((unsigned char *) &adrcnt)[1] = inb(tmport++); |
180 |
((unsigned char *) &adrcntu)[1] = inb(tmport++); |
| 247 |
((unsigned char *) &adrcnt)[0] = inb(tmport); |
181 |
((unsigned char *) &adrcntu)[0] = inb(tmport); |
| 248 |
k = dev->id[c][target_id].last_len; |
182 |
k = dev->id[target_id].last_lenu; |
| 249 |
k -= adrcnt; |
183 |
k -= adrcntu; |
| 250 |
dev->id[c][target_id].tran_len = k; |
184 |
dev->id[target_id].tran_lenu = k; |
| 251 |
dev->id[c][target_id].last_len = adrcnt; |
185 |
dev->id[target_id].last_lenu = adrcntu; |
| 252 |
tmport += 0x04; |
186 |
tmport += 0x04; |
| 253 |
outb(0x08, tmport); |
187 |
outb(0x08, tmport); |
| 254 |
dev->in_int[c] = 0; |
188 |
dev->in_int = 0; |
| 255 |
goto handled; |
189 |
goto out; |
| 256 |
} else { |
190 |
} else { |
| 257 |
#ifdef ED_DBGP |
|
|
| 258 |
printk("cmdp != 0x41\n"); |
| 259 |
#endif |
| 260 |
outb(0x46, tmport); |
191 |
outb(0x46, tmport); |
| 261 |
dev->id[c][target_id].dirct = 0x00; |
192 |
dev->id[target_id].dirctu = 0x00; |
| 262 |
tmport += 0x02; |
193 |
tmport += 0x02; |
| 263 |
outb(0x00, tmport++); |
194 |
outb(0x00, tmport++); |
| 264 |
outb(0x00, tmport++); |
195 |
outb(0x00, tmport++); |
| 265 |
outb(0x00, tmport++); |
196 |
outb(0x00, tmport++); |
| 266 |
tmport += 0x03; |
197 |
tmport += 0x03; |
| 267 |
outb(0x08, tmport); |
198 |
outb(0x08, tmport); |
| 268 |
dev->in_int[c] = 0; |
199 |
dev->in_int = 0; |
| 269 |
goto handled; |
200 |
goto out; |
| 270 |
} |
201 |
} |
| 271 |
} |
202 |
} |
| 272 |
if (dev->last_cmd[c] != 0xff) { |
203 |
if (dev->last_cmd != 0xff) { |
| 273 |
dev->last_cmd[c] |= 0x40; |
204 |
dev->last_cmd |= 0x40; |
| 274 |
} |
|
|
| 275 |
if (dev->dev_id == ATP885_DEVID) { |
| 276 |
j = inb(dev->baseport + 0x29) & 0xfe; |
| 277 |
outb(j, dev->baseport + 0x29); |
| 278 |
tmport = workport + 0x16; |
| 279 |
} else { |
| 280 |
tmport = workport + 0x10; |
| 281 |
outb(0x45, tmport); |
| 282 |
tmport += 0x06; |
| 283 |
} |
205 |
} |
| 284 |
|
206 |
tmport = workportu + 0x10; |
|
|
207 |
outb(0x45, tmport); |
| 208 |
tmport += 0x06; |
| 285 |
target_id = inb(tmport); |
209 |
target_id = inb(tmport); |
| 286 |
/* |
210 |
/* |
| 287 |
* Remap wide identifiers |
211 |
* Remap wide identifiers |
| 288 |
*/ |
212 |
*/ |
| 289 |
if ((target_id & 0x10) != 0) { |
213 |
if ((target_id & 0x10) != 0) { |
| 290 |
target_id = (target_id & 0x07) | 0x08; |
214 |
target_id = (target_id & 0x07) | 0x08; |
| 291 |
} else { |
215 |
} else { |
| 292 |
target_id &= 0x07; |
216 |
target_id &= 0x07; |
| 293 |
} |
217 |
} |
| 294 |
if (dev->dev_id == ATP885_DEVID) { |
218 |
workrequ = dev->id[target_id].curr_req; |
| 295 |
tmport = workport + 0x10; |
219 |
tmport = workportu + 0x0f; |
| 296 |
outb(0x45, tmport); |
|
|
| 297 |
} |
| 298 |
workreq = dev->id[c][target_id].curr_req; |
| 299 |
#ifdef ED_DBGP |
| 300 |
printk(KERN_DEBUG "Channel = %d ID = %d LUN = %d CDB",c,workreq->device->id,workreq->device->lun); |
| 301 |
for(l=0;l<workreq->cmd_len;l++) |
| 302 |
{ |
| 303 |
printk(KERN_DEBUG " %x",workreq->cmnd[l]); |
| 304 |
} |
| 305 |
#endif |
| 306 |
|
| 307 |
tmport = workport + 0x0f; |
| 308 |
outb(lun, tmport); |
220 |
outb(lun, tmport); |
| 309 |
tmport += 0x02; |
221 |
tmport += 0x02; |
| 310 |
outb(dev->id[c][target_id].devsp, tmport++); |
222 |
outb(dev->id[target_id].devspu, tmport++); |
| 311 |
adrcnt = dev->id[c][target_id].tran_len; |
223 |
adrcntu = dev->id[target_id].tran_lenu; |
| 312 |
k = dev->id[c][target_id].last_len; |
224 |
k = dev->id[target_id].last_lenu; |
| 313 |
|
|
|
| 314 |
outb(((unsigned char *) &k)[2], tmport++); |
225 |
outb(((unsigned char *) &k)[2], tmport++); |
| 315 |
outb(((unsigned char *) &k)[1], tmport++); |
226 |
outb(((unsigned char *) &k)[1], tmport++); |
| 316 |
outb(((unsigned char *) &k)[0], tmport++); |
227 |
outb(((unsigned char *) &k)[0], tmport++); |
| 317 |
#ifdef ED_DBGP |
|
|
| 318 |
printk("k %x, k[0] 0x%x k[1] 0x%x k[2] 0x%x\n", k, inb(tmport-1), inb(tmport-2), inb(tmport-3)); |
| 319 |
#endif |
| 320 |
/* Remap wide */ |
228 |
/* Remap wide */ |
| 321 |
j = target_id; |
229 |
j = target_id; |
| 322 |
if (target_id > 7) { |
230 |
if (target_id > 7) { |
| 323 |
j = (j & 0x07) | 0x40; |
231 |
j = (j & 0x07) | 0x40; |
| 324 |
} |
232 |
} |
| 325 |
/* Add direction */ |
233 |
/* Add direction */ |
| 326 |
j |= dev->id[c][target_id].dirct; |
234 |
j |= dev->id[target_id].dirctu; |
| 327 |
outb(j, tmport++); |
235 |
outb(j, tmport++); |
| 328 |
outb(0x80,tmport); |
236 |
outb(0x80, tmport); |
| 329 |
|
237 |
|
| 330 |
/* enable 32 bit fifo transfer */ |
238 |
/* enable 32 bit fifo transfer */ |
| 331 |
if (dev->dev_id == ATP885_DEVID) { |
239 |
if (dev->deviceid != 0x8081) { |
| 332 |
tmpcip = dev->pciport[c] + 1; |
240 |
tmport = workportu + 0x3a; |
| 333 |
i=inb(tmpcip) & 0xf3; |
241 |
if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) || (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a)) { |
| 334 |
//j=workreq->cmnd[0]; |
242 |
outb((unsigned char) ((inb(tmport) & 0xf3) | 0x08), tmport); |
| 335 |
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { |
243 |
} else { |
| 336 |
i |= 0x0c; |
244 |
outb((unsigned char) (inb(tmport) & 0xf3), tmport); |
| 337 |
} |
245 |
} |
| 338 |
outb(i,tmpcip); |
246 |
} else { |
| 339 |
} else if ((dev->dev_id == ATP880_DEVID1) || |
247 |
tmport = workportu - 0x05; |
| 340 |
(dev->dev_id == ATP880_DEVID2) ) { |
248 |
if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) || (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a)) { |
| 341 |
tmport = workport - 0x05; |
|
|
| 342 |
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { |
| 343 |
outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport); |
249 |
outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport); |
| 344 |
} else { |
250 |
} else { |
| 345 |
outb((unsigned char) (inb(tmport) & 0x3f), tmport); |
251 |
outb((unsigned char) (inb(tmport) & 0x3f), tmport); |
| 346 |
} |
252 |
} |
| 347 |
} else { |
253 |
} |
| 348 |
tmport = workport + 0x3a; |
254 |
|
| 349 |
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { |
255 |
tmport = workportu + 0x1b; |
| 350 |
outb((unsigned char) ((inb(tmport) & 0xf3) | 0x08), tmport); |
|
|
| 351 |
} else { |
| 352 |
outb((unsigned char) (inb(tmport) & 0xf3), tmport); |
| 353 |
} |
| 354 |
} |
| 355 |
tmport = workport + 0x1b; |
| 356 |
j = 0; |
256 |
j = 0; |
| 357 |
id = 1; |
257 |
id = 1; |
| 358 |
id = id << target_id; |
258 |
id = id << target_id; |
| 359 |
/* |
259 |
/* |
| 360 |
* Is this a wide device |
260 |
* Is this a wide device |
| 361 |
*/ |
261 |
*/ |
| 362 |
if ((id & dev->wide_id[c]) != 0) { |
262 |
if ((id & dev->wide_idu) != 0) { |
| 363 |
j |= 0x01; |
263 |
j |= 0x01; |
| 364 |
} |
264 |
} |
| 365 |
outb(j, tmport); |
265 |
outb(j, tmport); |
| 366 |
while ((inb(tmport) & 0x01) != j) { |
266 |
while ((inb(tmport) & 0x01) != j) { |
| 367 |
outb(j,tmport); |
267 |
outb(j, tmport); |
| 368 |
} |
268 |
} |
| 369 |
if (dev->id[c][target_id].last_len == 0) { |
269 |
|
| 370 |
tmport = workport + 0x18; |
270 |
if (dev->id[target_id].last_lenu == 0) { |
|
|
271 |
tmport = workportu + 0x18; |
| 371 |
outb(0x08, tmport); |
272 |
outb(0x08, tmport); |
| 372 |
dev->in_int[c] = 0; |
273 |
dev->in_int = 0; |
| 373 |
#ifdef ED_DBGP |
274 |
goto out; |
| 374 |
printk("dev->id[c][target_id].last_len = 0\n"); |
275 |
} |
| 375 |
#endif |
276 |
prd = dev->id[target_id].prd_posu; |
| 376 |
goto handled; |
277 |
while (adrcntu != 0) { |
| 377 |
} |
278 |
id = ((unsigned short int *) (prd))[2]; |
| 378 |
#ifdef ED_DBGP |
|
|
| 379 |
printk("target_id = %d adrcnt = %d\n",target_id,adrcnt); |
| 380 |
#endif |
| 381 |
prd = dev->id[c][target_id].prd_pos; |
| 382 |
while (adrcnt != 0) { |
| 383 |
id = ((unsigned short int *)prd)[2]; |
| 384 |
if (id == 0) { |
279 |
if (id == 0) { |
| 385 |
k = 0x10000; |
280 |
k = 0x10000; |
| 386 |
} else { |
281 |
} else { |
| 387 |
k = id; |
282 |
k = id; |
| 388 |
} |
283 |
} |
| 389 |
if (k > adrcnt) { |
284 |
if (k > adrcntu) { |
| 390 |
((unsigned short int *)prd)[2] = (unsigned short int) |
285 |
((unsigned short int *) (prd))[2] = (unsigned short int) |
| 391 |
(k - adrcnt); |
286 |
(k - adrcntu); |
| 392 |
((unsigned long *)prd)[0] += adrcnt; |
287 |
((unsigned long *) (prd))[0] += adrcntu; |
| 393 |
adrcnt = 0; |
288 |
adrcntu = 0; |
| 394 |
dev->id[c][target_id].prd_pos = prd; |
289 |
dev->id[target_id].prd_posu = prd; |
| 395 |
} else { |
290 |
} else { |
| 396 |
adrcnt -= k; |
291 |
adrcntu -= k; |
| 397 |
dev->id[c][target_id].prdaddr += 0x08; |
292 |
dev->id[target_id].prdaddru += 0x08; |
| 398 |
prd += 0x08; |
293 |
prd += 0x08; |
| 399 |
if (adrcnt == 0) { |
294 |
if (adrcntu == 0) { |
| 400 |
dev->id[c][target_id].prd_pos = prd; |
295 |
dev->id[target_id].prd_posu = prd; |
| 401 |
} |
296 |
} |
| 402 |
} |
297 |
} |
| 403 |
} |
|
|
| 404 |
tmpcip = dev->pciport[c] + 0x04; |
| 405 |
outl(dev->id[c][target_id].prdaddr, tmpcip); |
| 406 |
#ifdef ED_DBGP |
| 407 |
printk("dev->id[%d][%d].prdaddr 0x%8x\n", c, target_id, dev->id[c][target_id].prdaddr); |
| 408 |
#endif |
| 409 |
if (dev->dev_id == ATP885_DEVID) { |
| 410 |
tmpcip -= 0x04; |
| 411 |
} else { |
| 412 |
tmpcip -= 0x02; |
| 413 |
outb(0x06, tmpcip); |
| 414 |
outb(0x00, tmpcip); |
| 415 |
tmpcip -= 0x02; |
| 416 |
} |
298 |
} |
| 417 |
tmport = workport + 0x18; |
299 |
tmpcip = dev->pciport + 0x04; |
|
|
300 |
outl(dev->id[target_id].prdaddru, tmpcip); |
| 301 |
tmpcip -= 0x02; |
| 302 |
outb(0x06, tmpcip); |
| 303 |
outb(0x00, tmpcip); |
| 304 |
tmpcip -= 0x02; |
| 305 |
tmport = workportu + 0x18; |
| 418 |
/* |
306 |
/* |
| 419 |
* Check transfer direction |
307 |
* Check transfer direction |
| 420 |
*/ |
308 |
*/ |
| 421 |
if (dev->id[c][target_id].dirct != 0) { |
309 |
if (dev->id[target_id].dirctu != 0) { |
| 422 |
outb(0x08, tmport); |
310 |
outb(0x08, tmport); |
| 423 |
outb(0x01, tmpcip); |
311 |
outb(0x01, tmpcip); |
| 424 |
dev->in_int[c] = 0; |
312 |
dev->in_int = 0; |
| 425 |
#ifdef ED_DBGP |
313 |
goto out; |
| 426 |
printk("status 0x80 return dirct != 0\n"); |
|
|
| 427 |
#endif |
| 428 |
goto handled; |
| 429 |
} |
314 |
} |
| 430 |
outb(0x08, tmport); |
315 |
outb(0x08, tmport); |
| 431 |
outb(0x09, tmpcip); |
316 |
outb(0x09, tmpcip); |
| 432 |
dev->in_int[c] = 0; |
317 |
dev->in_int = 0; |
| 433 |
#ifdef ED_DBGP |
318 |
goto out; |
| 434 |
printk("status 0x80 return dirct = 0\n"); |
|
|
| 435 |
#endif |
| 436 |
goto handled; |
| 437 |
} |
319 |
} |
| 438 |
|
320 |
|
| 439 |
/* |
321 |
/* |
| 440 |
* Current scsi request on this target |
322 |
* Current scsi request on this target |
| 441 |
*/ |
323 |
*/ |
| 442 |
|
324 |
|
| 443 |
workreq = dev->id[c][target_id].curr_req; |
325 |
workrequ = dev->id[target_id].curr_req; |
| 444 |
|
326 |
|
| 445 |
if (i == 0x42) { |
327 |
if (i == 0x42) { |
| 446 |
if ((dev->last_cmd[c] & 0xf0) != 0x40) |
328 |
if ((dev->last_cmd & 0xf0) != 0x40) { |
| 447 |
{ |
329 |
dev->last_cmd = 0xff; |
| 448 |
dev->last_cmd[c] = 0xff; |
|
|
| 449 |
} |
330 |
} |
| 450 |
errstus = 0x02; |
331 |
errstus = 0x02; |
| 451 |
workreq->result = errstus; |
332 |
workrequ->result = errstus; |
| 452 |
goto go_42; |
333 |
goto go_42; |
| 453 |
} |
334 |
} |
| 454 |
if (i == 0x16) { |
335 |
if (i == 0x16) { |
| 455 |
if ((dev->last_cmd[c] & 0xf0) != 0x40) { |
336 |
if ((dev->last_cmd & 0xf0) != 0x40) { |
| 456 |
dev->last_cmd[c] = 0xff; |
337 |
dev->last_cmd = 0xff; |
| 457 |
} |
338 |
} |
| 458 |
errstus = 0; |
339 |
errstus = 0; |
| 459 |
tmport -= 0x08; |
340 |
tmport -= 0x08; |
| 460 |
errstus = inb(tmport); |
341 |
errstus = inb(tmport); |
| 461 |
if (((dev->r1f[c][target_id] & 0x10) != 0)&&(dev->dev_id==ATP885_DEVID)) { |
342 |
workrequ->result = errstus; |
| 462 |
printk(KERN_WARNING "AEC67162 CRC ERROR !\n"); |
|
|
| 463 |
errstus = 0x02; |
| 464 |
} |
| 465 |
workreq->result = errstus; |
| 466 |
go_42: |
343 |
go_42: |
| 467 |
if (dev->dev_id == ATP885_DEVID) { |
|
|
| 468 |
j = inb(dev->baseport + 0x29) | 0x01; |
| 469 |
outb(j, dev->baseport + 0x29); |
| 470 |
} |
| 471 |
/* |
344 |
/* |
| 472 |
* Complete the command |
345 |
* Complete the command |
| 473 |
*/ |
346 |
*/ |
| 474 |
if (workreq->use_sg) { |
347 |
|
|
|
348 |
if (workrequ->use_sg) { |
| 475 |
pci_unmap_sg(dev->pdev, |
349 |
pci_unmap_sg(dev->pdev, |
| 476 |
(struct scatterlist *)workreq->buffer, |
350 |
(struct scatterlist *)workrequ->buffer, |
| 477 |
workreq->use_sg, |
351 |
workrequ->use_sg, |
| 478 |
workreq->sc_data_direction); |
352 |
workrequ->sc_data_direction); |
| 479 |
} else if (workreq->request_bufflen && |
353 |
} else if (workrequ->request_bufflen && |
| 480 |
workreq->sc_data_direction != DMA_NONE) { |
354 |
workrequ->sc_data_direction != DMA_NONE) { |
| 481 |
pci_unmap_single(dev->pdev, |
355 |
pci_unmap_single(dev->pdev, |
| 482 |
workreq->SCp.dma_handle, |
356 |
workrequ->SCp.dma_handle, |
| 483 |
workreq->request_bufflen, |
357 |
workrequ->request_bufflen, |
| 484 |
workreq->sc_data_direction); |
358 |
workrequ->sc_data_direction); |
| 485 |
} |
359 |
} |
| 486 |
spin_lock_irqsave(dev->host->host_lock, flags); |
360 |
spin_lock_irqsave(dev->host->host_lock, flags); |
| 487 |
(*workreq->scsi_done) (workreq); |
361 |
(*workrequ->scsi_done) (workrequ); |
| 488 |
#ifdef ED_DBGP |
362 |
|
| 489 |
printk("workreq->scsi_done\n"); |
|
|
| 490 |
#endif |
| 491 |
/* |
363 |
/* |
| 492 |
* Clear it off the queue |
364 |
* Clear it off the queue |
| 493 |
*/ |
365 |
*/ |
| 494 |
dev->id[c][target_id].curr_req = NULL; |
366 |
dev->id[target_id].curr_req = NULL; |
| 495 |
dev->working[c]--; |
367 |
dev->working--; |
| 496 |
spin_unlock_irqrestore(dev->host->host_lock, flags); |
368 |
spin_unlock_irqrestore(dev->host->host_lock, flags); |
| 497 |
/* |
369 |
/* |
| 498 |
* Take it back wide |
370 |
* Take it back wide |
| 499 |
*/ |
371 |
*/ |
| 500 |
if (dev->wide_id[c] != 0) { |
372 |
if (dev->wide_idu != 0) { |
| 501 |
tmport = workport + 0x1b; |
373 |
tmport = workportu + 0x1b; |
| 502 |
outb(0x01, tmport); |
374 |
outb(0x01, tmport); |
| 503 |
while ((inb(tmport) & 0x01) != 0x01) { |
375 |
while ((inb(tmport) & 0x01) != 0x01) { |
| 504 |
outb(0x01, tmport); |
376 |
outb(0x01, tmport); |
| 505 |
} |
377 |
} |
| 506 |
} |
378 |
} |
| 507 |
/* |
379 |
/* |
| 508 |
* If there is stuff to send and nothing going then send it |
380 |
* If there is stuff to send and nothing going then send it |
| 509 |
*/ |
381 |
*/ |
| 510 |
spin_lock_irqsave(dev->host->host_lock, flags); |
382 |
spin_lock_irqsave(dev->host->host_lock, flags); |
| 511 |
if (((dev->last_cmd[c] != 0xff) || (dev->quhd[c] != dev->quend[c])) && |
383 |
if (((dev->last_cmd != 0xff) || (dev->quhdu != dev->quendu)) && (dev->in_snd == 0)) { |
| 512 |
(dev->in_snd[c] == 0)) { |
384 |
send_s870(host); |
| 513 |
#ifdef ED_DBGP |
|
|
| 514 |
printk("Call sent_s870(scsi_done)\n"); |
| 515 |
#endif |
| 516 |
send_s870(dev,c); |
| 517 |
} |
385 |
} |
| 518 |
spin_unlock_irqrestore(dev->host->host_lock, flags); |
386 |
spin_unlock_irqrestore(dev->host->host_lock, flags); |
| 519 |
dev->in_int[c] = 0; |
387 |
dev->in_int = 0; |
| 520 |
goto handled; |
388 |
goto out; |
| 521 |
} |
389 |
} |
| 522 |
if ((dev->last_cmd[c] & 0xf0) != 0x40) { |
390 |
if ((dev->last_cmd & 0xf0) != 0x40) { |
| 523 |
dev->last_cmd[c] = 0xff; |
391 |
dev->last_cmd = 0xff; |
| 524 |
} |
392 |
} |
| 525 |
if (i == 0x4f) { |
393 |
if (i == 0x4f) { |
| 526 |
i = 0x89; |
394 |
i = 0x89; |
| 527 |
} |
395 |
} |
| 528 |
i &= 0x0f; |
396 |
i &= 0x0f; |
| 529 |
if (i == 0x09) { |
397 |
if (i == 0x09) { |
| 530 |
tmpcip += 4; |
398 |
tmpcip = tmpcip + 4; |
| 531 |
outl(dev->id[c][target_id].prdaddr, tmpcip); |
399 |
outl(dev->id[target_id].prdaddru, tmpcip); |
| 532 |
tmpcip = tmpcip - 2; |
400 |
tmpcip = tmpcip - 2; |
| 533 |
outb(0x06, tmpcip); |
401 |
outb(0x06, tmpcip); |
| 534 |
outb(0x00, tmpcip); |
402 |
outb(0x00, tmpcip); |
| 535 |
tmpcip = tmpcip - 2; |
403 |
tmpcip = tmpcip - 2; |
| 536 |
tmport = workport + 0x10; |
404 |
tmport = workportu + 0x10; |
| 537 |
outb(0x41, tmport); |
405 |
outb(0x41, tmport); |
| 538 |
if (dev->dev_id == ATP885_DEVID) { |
406 |
dev->id[target_id].dirctu = 0x00; |
| 539 |
tmport += 2; |
407 |
tmport += 0x08; |
| 540 |
k = dev->id[c][target_id].last_len; |
|
|
| 541 |
outb((unsigned char) (((unsigned char *) (&k))[2]), tmport++); |
| 542 |
outb((unsigned char) (((unsigned char *) (&k))[1]), tmport++); |
| 543 |
outb((unsigned char) (((unsigned char *) (&k))[0]), tmport); |
| 544 |
dev->id[c][target_id].dirct = 0x00; |
| 545 |
tmport += 0x04; |
| 546 |
} else { |
| 547 |
dev->id[c][target_id].dirct = 0x00; |
| 548 |
tmport += 0x08; |
| 549 |
} |
| 550 |
outb(0x08, tmport); |
408 |
outb(0x08, tmport); |
| 551 |
outb(0x09, tmpcip); |
409 |
outb(0x09, tmpcip); |
| 552 |
dev->in_int[c] = 0; |
410 |
dev->in_int = 0; |
| 553 |
goto handled; |
411 |
goto out; |
| 554 |
} |
412 |
} |
| 555 |
if (i == 0x08) { |
413 |
if (i == 0x08) { |
| 556 |
tmpcip += 4; |
414 |
tmpcip = tmpcip + 4; |
| 557 |
outl(dev->id[c][target_id].prdaddr, tmpcip); |
415 |
outl(dev->id[target_id].prdaddru, tmpcip); |
| 558 |
tmpcip = tmpcip - 2; |
416 |
tmpcip = tmpcip - 2; |
| 559 |
outb(0x06, tmpcip); |
417 |
outb(0x06, tmpcip); |
| 560 |
outb(0x00, tmpcip); |
418 |
outb(0x00, tmpcip); |
| 561 |
tmpcip = tmpcip - 2; |
419 |
tmpcip = tmpcip - 2; |
| 562 |
tmport = workport + 0x10; |
420 |
tmport = workportu + 0x10; |
| 563 |
outb(0x41, tmport); |
421 |
outb(0x41, tmport); |
| 564 |
if (dev->dev_id == ATP885_DEVID) { |
422 |
tmport += 0x05; |
| 565 |
tmport += 2; |
|
|
| 566 |
k = dev->id[c][target_id].last_len; |
| 567 |
outb((unsigned char) (((unsigned char *) (&k))[2]), tmport++); |
| 568 |
outb((unsigned char) (((unsigned char *) (&k))[1]), tmport++); |
| 569 |
outb((unsigned char) (((unsigned char *) (&k))[0]), tmport++); |
| 570 |
} else { |
| 571 |
tmport += 5; |
| 572 |
} |
| 573 |
outb((unsigned char) (inb(tmport) | 0x20), tmport); |
423 |
outb((unsigned char) (inb(tmport) | 0x20), tmport); |
| 574 |
dev->id[c][target_id].dirct = 0x20; |
424 |
dev->id[target_id].dirctu = 0x20; |
| 575 |
tmport += 0x03; |
425 |
tmport += 0x03; |
| 576 |
outb(0x08, tmport); |
426 |
outb(0x08, tmport); |
| 577 |
outb(0x01, tmpcip); |
427 |
outb(0x01, tmpcip); |
| 578 |
dev->in_int[c] = 0; |
428 |
dev->in_int = 0; |
| 579 |
goto handled; |
429 |
goto out; |
| 580 |
} |
430 |
} |
| 581 |
tmport -= 0x07; |
431 |
tmport -= 0x07; |
| 582 |
if (i == 0x0a) { |
432 |
if (i == 0x0a) { |
|
Lines 584-612
Link Here
|
| 584 |
} else { |
434 |
} else { |
| 585 |
outb(0x46, tmport); |
435 |
outb(0x46, tmport); |
| 586 |
} |
436 |
} |
| 587 |
dev->id[c][target_id].dirct = 0x00; |
437 |
dev->id[target_id].dirctu = 0x00; |
| 588 |
tmport += 0x02; |
438 |
tmport += 0x02; |
| 589 |
outb(0x00, tmport++); |
439 |
outb(0x00, tmport++); |
| 590 |
outb(0x00, tmport++); |
440 |
outb(0x00, tmport++); |
| 591 |
outb(0x00, tmport++); |
441 |
outb(0x00, tmport++); |
| 592 |
tmport += 0x03; |
442 |
tmport += 0x03; |
| 593 |
outb(0x08, tmport); |
443 |
outb(0x08, tmport); |
| 594 |
dev->in_int[c] = 0; |
444 |
dev->in_int = 0; |
| 595 |
goto handled; |
445 |
goto out; |
| 596 |
} else { |
446 |
} else { |
| 597 |
// tmport = workport + 0x17; |
447 |
// tmport = workportu + 0x17; |
| 598 |
// inb(tmport); |
448 |
// inb(tmport); |
| 599 |
// dev->working[c] = 0; |
449 |
// dev->working = 0; |
| 600 |
dev->in_int[c] = 0; |
450 |
dev->in_int = 0; |
| 601 |
goto handled; |
|
|
| 602 |
} |
451 |
} |
| 603 |
|
452 |
out: |
| 604 |
handled: |
|
|
| 605 |
#ifdef ED_DBGP |
| 606 |
printk("atp870u_intr_handle exit\n"); |
| 607 |
#endif |
| 608 |
return IRQ_HANDLED; |
453 |
return IRQ_HANDLED; |
| 609 |
} |
454 |
} |
|
|
455 |
|
| 610 |
/** |
456 |
/** |
| 611 |
* atp870u_queuecommand - Queue SCSI command |
457 |
* atp870u_queuecommand - Queue SCSI command |
| 612 |
* @req_p: request block |
458 |
* @req_p: request block |
|
Lines 614-644
Link Here
|
| 614 |
* |
460 |
* |
| 615 |
* Queue a command to the ATP queue. Called with the host lock held. |
461 |
* Queue a command to the ATP queue. Called with the host lock held. |
| 616 |
*/ |
462 |
*/ |
| 617 |
static int atp870u_queuecommand(struct scsi_cmnd * req_p, |
463 |
|
| 618 |
void (*done) (struct scsi_cmnd *)) |
464 |
static int atp870u_queuecommand(struct scsi_cmnd *req_p, |
|
|
465 |
void (*done) (struct scsi_cmnd *)) |
| 619 |
{ |
466 |
{ |
| 620 |
unsigned char c; |
467 |
unsigned short int m; |
| 621 |
unsigned int tmport,m; |
468 |
unsigned int tmport; |
| 622 |
struct atp_unit *dev; |
|
|
| 623 |
struct Scsi_Host *host; |
469 |
struct Scsi_Host *host; |
|
|
470 |
struct atp_unit *dev; |
| 624 |
|
471 |
|
| 625 |
c = req_p->device->channel; |
472 |
if (req_p->device->channel != 0) { |
| 626 |
req_p->sense_buffer[0]=0; |
|
|
| 627 |
req_p->resid = 0; |
| 628 |
if (req_p->device->channel > 1) { |
| 629 |
req_p->result = 0x00040000; |
473 |
req_p->result = 0x00040000; |
| 630 |
done(req_p); |
474 |
done(req_p); |
| 631 |
#ifdef ED_DBGP |
|
|
| 632 |
printk("atp870u_queuecommand : req_p->device->channel > 1\n"); |
| 633 |
#endif |
| 634 |
return 0; |
475 |
return 0; |
| 635 |
} |
476 |
}; |
| 636 |
|
477 |
|
| 637 |
host = req_p->device->host; |
478 |
host = req_p->device->host; |
| 638 |
dev = (struct atp_unit *)&host->hostdata; |
479 |
dev = (struct atp_unit *)&host->hostdata; |
| 639 |
|
480 |
|
| 640 |
|
|
|
| 641 |
|
| 642 |
m = 1; |
481 |
m = 1; |
| 643 |
m = m << req_p->device->id; |
482 |
m = m << req_p->device->id; |
| 644 |
|
483 |
|
|
Lines 646-705
Link Here
|
| 646 |
* Fake a timeout for missing targets |
485 |
* Fake a timeout for missing targets |
| 647 |
*/ |
486 |
*/ |
| 648 |
|
487 |
|
| 649 |
if ((m & dev->active_id[c]) == 0) { |
488 |
if ((m & dev->active_idu) == 0) { |
| 650 |
req_p->result = 0x00040000; |
489 |
req_p->result = 0x00040000; |
| 651 |
done(req_p); |
490 |
done(req_p); |
| 652 |
return 0; |
491 |
return 0; |
| 653 |
} |
492 |
} |
| 654 |
|
|
|
| 655 |
if (done) { |
493 |
if (done) { |
| 656 |
req_p->scsi_done = done; |
494 |
req_p->scsi_done = done; |
| 657 |
} else { |
495 |
} else { |
| 658 |
#ifdef ED_DBGP |
496 |
printk(KERN_WARNING "atp870u_queuecommand: done can't be NULL\n"); |
| 659 |
printk( "atp870u_queuecommand: done can't be NULL\n"); |
|
|
| 660 |
#endif |
| 661 |
req_p->result = 0; |
497 |
req_p->result = 0; |
| 662 |
done(req_p); |
498 |
done(req_p); |
| 663 |
return 0; |
499 |
return 0; |
| 664 |
} |
500 |
} |
| 665 |
|
|
|
| 666 |
/* |
501 |
/* |
| 667 |
* Count new command |
502 |
* Count new command |
| 668 |
*/ |
503 |
*/ |
| 669 |
dev->quend[c]++; |
504 |
|
| 670 |
if (dev->quend[c] >= qcnt) { |
505 |
dev->quendu++; |
| 671 |
dev->quend[c] = 0; |
506 |
if (dev->quendu >= qcnt) { |
|
|
507 |
dev->quendu = 0; |
| 672 |
} |
508 |
} |
| 673 |
|
|
|
| 674 |
/* |
509 |
/* |
| 675 |
* Check queue state |
510 |
* Check queue state |
| 676 |
*/ |
511 |
*/ |
| 677 |
if (dev->quhd[c] == dev->quend[c]) { |
512 |
if (dev->quhdu == dev->quendu) { |
| 678 |
if (dev->quend[c] == 0) { |
513 |
if (dev->quendu == 0) { |
| 679 |
dev->quend[c] = qcnt; |
514 |
dev->quendu = qcnt; |
| 680 |
} |
515 |
} |
| 681 |
#ifdef ED_DBGP |
516 |
dev->quendu--; |
| 682 |
printk("atp870u_queuecommand : dev->quhd[c] == dev->quend[c]\n"); |
|
|
| 683 |
#endif |
| 684 |
dev->quend[c]--; |
| 685 |
req_p->result = 0x00020000; |
517 |
req_p->result = 0x00020000; |
| 686 |
done(req_p); |
518 |
done(req_p); |
| 687 |
return 0; |
519 |
return 0; |
| 688 |
} |
520 |
} |
| 689 |
dev->quereq[c][dev->quend[c]] = req_p; |
521 |
dev->querequ[dev->quendu] = req_p; |
| 690 |
tmport = dev->ioport[c] + 0x1c; |
522 |
tmport = dev->ioport + 0x1c; |
| 691 |
#ifdef ED_DBGP |
523 |
if ((inb(tmport) == 0) && (dev->in_int == 0) && (dev->in_snd == 0)) { |
| 692 |
printk("dev->ioport[c] = %x inb(tmport) = %x dev->in_int[%d] = %d dev->in_snd[%d] = %d\n",dev->ioport[c],inb(tmport),c,dev->in_int[c],c,dev->in_snd[c]); |
524 |
send_s870(host); |
| 693 |
#endif |
525 |
} |
| 694 |
if ((inb(tmport) == 0) && (dev->in_int[c] == 0) && (dev->in_snd[c] == 0)) { |
|
|
| 695 |
#ifdef ED_DBGP |
| 696 |
printk("Call sent_s870(atp870u_queuecommand)\n"); |
| 697 |
#endif |
| 698 |
send_s870(dev,c); |
| 699 |
} |
| 700 |
#ifdef ED_DBGP |
| 701 |
printk("atp870u_queuecommand : exit\n"); |
| 702 |
#endif |
| 703 |
return 0; |
526 |
return 0; |
| 704 |
} |
527 |
} |
| 705 |
|
528 |
|
|
Lines 712-953
Link Here
|
| 712 |
* |
535 |
* |
| 713 |
* Caller holds the host lock. |
536 |
* Caller holds the host lock. |
| 714 |
*/ |
537 |
*/ |
| 715 |
static void send_s870(struct atp_unit *dev,unsigned char c) |
538 |
|
|
|
539 |
static void send_s870(struct Scsi_Host *host) |
| 716 |
{ |
540 |
{ |
| 717 |
unsigned int tmport; |
541 |
unsigned int tmport; |
| 718 |
struct scsi_cmnd *workreq; |
542 |
struct scsi_cmnd *workrequ; |
| 719 |
unsigned int i;//,k; |
543 |
unsigned int i; |
| 720 |
unsigned char j, target_id; |
544 |
unsigned char j, target_id; |
| 721 |
unsigned char *prd; |
545 |
unsigned char *prd; |
| 722 |
unsigned short int tmpcip, w; |
546 |
unsigned short int tmpcip, w; |
| 723 |
unsigned long l, bttl = 0; |
547 |
unsigned long l; |
| 724 |
unsigned int workport; |
548 |
dma_addr_t bttl; |
|
|
549 |
unsigned int workportu; |
| 725 |
struct scatterlist *sgpnt; |
550 |
struct scatterlist *sgpnt; |
| 726 |
unsigned long sg_count; |
551 |
struct atp_unit *dev = (struct atp_unit *)&host->hostdata; |
|
|
552 |
int sg_count; |
| 727 |
|
553 |
|
| 728 |
if (dev->in_snd[c] != 0) { |
554 |
if (dev->in_snd != 0) { |
| 729 |
#ifdef ED_DBGP |
555 |
return; |
| 730 |
printk("cmnd in_snd\n"); |
556 |
} |
| 731 |
#endif |
557 |
dev->in_snd = 1; |
|
|
558 |
if ((dev->last_cmd != 0xff) && ((dev->last_cmd & 0x40) != 0)) { |
| 559 |
dev->last_cmd &= 0x0f; |
| 560 |
workrequ = dev->id[dev->last_cmd].curr_req; |
| 561 |
if (workrequ != NULL) { /* check NULL pointer */ |
| 562 |
goto cmd_subp; |
| 563 |
} |
| 564 |
dev->last_cmd = 0xff; |
| 565 |
if (dev->quhdu == dev->quendu) { |
| 566 |
dev->in_snd = 0; |
| 567 |
return; |
| 568 |
} |
| 569 |
} |
| 570 |
if ((dev->last_cmd != 0xff) && (dev->working != 0)) { |
| 571 |
dev->in_snd = 0; |
| 732 |
return; |
572 |
return; |
| 733 |
} |
573 |
} |
| 734 |
#ifdef ED_DBGP |
574 |
dev->working++; |
| 735 |
printk("Sent_s870 enter\n"); |
575 |
j = dev->quhdu; |
| 736 |
#endif |
576 |
dev->quhdu++; |
| 737 |
dev->in_snd[c] = 1; |
577 |
if (dev->quhdu >= qcnt) { |
| 738 |
if ((dev->last_cmd[c] != 0xff) && ((dev->last_cmd[c] & 0x40) != 0)) { |
578 |
dev->quhdu = 0; |
| 739 |
dev->last_cmd[c] &= 0x0f; |
579 |
} |
| 740 |
workreq = dev->id[c][dev->last_cmd[c]].curr_req; |
580 |
workrequ = dev->querequ[dev->quhdu]; |
| 741 |
if (workreq != NULL) { /* check NULL pointer */ |
581 |
if (dev->id[workrequ->device->id].curr_req == 0) { |
| 742 |
goto cmd_subp; |
582 |
dev->id[workrequ->device->id].curr_req = workrequ; |
| 743 |
} |
583 |
dev->last_cmd = workrequ->device->id; |
| 744 |
dev->last_cmd[c] = 0xff; |
|
|
| 745 |
if (dev->quhd[c] == dev->quend[c]) { |
| 746 |
dev->in_snd[c] = 0; |
| 747 |
return ; |
| 748 |
} |
| 749 |
} |
| 750 |
if ((dev->last_cmd[c] != 0xff) && (dev->working[c] != 0)) { |
| 751 |
dev->in_snd[c] = 0; |
| 752 |
return ; |
| 753 |
} |
| 754 |
dev->working[c]++; |
| 755 |
j = dev->quhd[c]; |
| 756 |
dev->quhd[c]++; |
| 757 |
if (dev->quhd[c] >= qcnt) { |
| 758 |
dev->quhd[c] = 0; |
| 759 |
} |
| 760 |
workreq = dev->quereq[c][dev->quhd[c]]; |
| 761 |
if (dev->id[c][workreq->device->id].curr_req == 0) { |
| 762 |
dev->id[c][workreq->device->id].curr_req = workreq; |
| 763 |
dev->last_cmd[c] = workreq->device->id; |
| 764 |
goto cmd_subp; |
584 |
goto cmd_subp; |
| 765 |
} |
585 |
} |
| 766 |
dev->quhd[c] = j; |
586 |
dev->quhdu = j; |
| 767 |
dev->working[c]--; |
587 |
dev->working--; |
| 768 |
dev->in_snd[c] = 0; |
588 |
dev->in_snd = 0; |
| 769 |
return; |
589 |
return; |
| 770 |
cmd_subp: |
590 |
cmd_subp: |
| 771 |
workport = dev->ioport[c]; |
591 |
workportu = dev->ioport; |
| 772 |
tmport = workport + 0x1f; |
592 |
tmport = workportu + 0x1f; |
| 773 |
if ((inb(tmport) & 0xb0) != 0) { |
593 |
if ((inb(tmport) & 0xb0) != 0) { |
| 774 |
goto abortsnd; |
594 |
goto abortsnd; |
| 775 |
} |
595 |
} |
| 776 |
tmport = workport + 0x1c; |
596 |
tmport = workportu + 0x1c; |
| 777 |
if (inb(tmport) == 0) { |
597 |
if (inb(tmport) == 0) { |
| 778 |
goto oktosend; |
598 |
goto oktosend; |
| 779 |
} |
599 |
} |
| 780 |
abortsnd: |
600 |
abortsnd: |
| 781 |
#ifdef ED_DBGP |
601 |
dev->last_cmd |= 0x40; |
| 782 |
printk("Abort to Send\n"); |
602 |
dev->in_snd = 0; |
| 783 |
#endif |
|
|
| 784 |
dev->last_cmd[c] |= 0x40; |
| 785 |
dev->in_snd[c] = 0; |
| 786 |
return; |
603 |
return; |
| 787 |
oktosend: |
604 |
oktosend: |
| 788 |
#ifdef ED_DBGP |
605 |
memcpy(&dev->ata_cdbu[0], &workrequ->cmnd[0], workrequ->cmd_len); |
| 789 |
printk("OK to Send\n"); |
606 |
if (dev->ata_cdbu[0] == READ_CAPACITY) { |
| 790 |
printk("CDB"); |
607 |
if (workrequ->request_bufflen > 8) { |
| 791 |
for(i=0;i<workreq->cmd_len;i++) { |
608 |
workrequ->request_bufflen = 0x08; |
| 792 |
printk(" %x",workreq->cmnd[i]); |
|
|
| 793 |
} |
| 794 |
printk("\nChannel = %d ID = %d LUN = %d\n",c,workreq->device->id,workreq->device->lun); |
| 795 |
#endif |
| 796 |
if (dev->dev_id == ATP885_DEVID) { |
| 797 |
j = inb(dev->baseport + 0x29) & 0xfe; |
| 798 |
outb(j, dev->baseport + 0x29); |
| 799 |
dev->r1f[c][workreq->device->id] = 0; |
| 800 |
} |
| 801 |
|
| 802 |
if (workreq->cmnd[0] == READ_CAPACITY) { |
| 803 |
if (workreq->request_bufflen > 8) { |
| 804 |
workreq->request_bufflen = 0x08; |
| 805 |
} |
609 |
} |
| 806 |
} |
610 |
} |
| 807 |
if (workreq->cmnd[0] == 0x00) { |
611 |
if (dev->ata_cdbu[0] == 0x00) { |
| 808 |
workreq->request_bufflen = 0; |
612 |
workrequ->request_bufflen = 0; |
| 809 |
} |
613 |
} |
| 810 |
|
614 |
|
| 811 |
tmport = workport + 0x1b; |
615 |
tmport = workportu + 0x1b; |
| 812 |
j = 0; |
616 |
j = 0; |
| 813 |
target_id = workreq->device->id; |
617 |
target_id = workrequ->device->id; |
| 814 |
|
618 |
|
| 815 |
/* |
619 |
/* |
| 816 |
* Wide ? |
620 |
* Wide ? |
| 817 |
*/ |
621 |
*/ |
| 818 |
w = 1; |
622 |
w = 1; |
| 819 |
w = w << target_id; |
623 |
w = w << target_id; |
| 820 |
if ((w & dev->wide_id[c]) != 0) { |
624 |
if ((w & dev->wide_idu) != 0) { |
| 821 |
j |= 0x01; |
625 |
j |= 0x01; |
| 822 |
} |
626 |
} |
| 823 |
outb(j, tmport); |
627 |
outb(j, tmport); |
| 824 |
while ((inb(tmport) & 0x01) != j) { |
628 |
while ((inb(tmport) & 0x01) != j) { |
| 825 |
outb(j,tmport); |
629 |
outb(j, tmport); |
| 826 |
#ifdef ED_DBGP |
|
|
| 827 |
printk("send_s870 while loop 1\n"); |
| 828 |
#endif |
| 829 |
} |
630 |
} |
|
|
631 |
|
| 830 |
/* |
632 |
/* |
| 831 |
* Write the command |
633 |
* Write the command |
| 832 |
*/ |
634 |
*/ |
| 833 |
|
635 |
|
| 834 |
tmport = workport; |
636 |
tmport = workportu; |
| 835 |
outb(workreq->cmd_len, tmport++); |
637 |
outb(workrequ->cmd_len, tmport++); |
| 836 |
outb(0x2c, tmport++); |
638 |
outb(0x2c, tmport++); |
| 837 |
if (dev->dev_id == ATP885_DEVID) { |
639 |
outb(0xcf, tmport++); |
| 838 |
outb(0x7f, tmport++); |
640 |
for (i = 0; i < workrequ->cmd_len; i++) { |
| 839 |
} else { |
641 |
outb(dev->ata_cdbu[i], tmport++); |
| 840 |
outb(0xcf, tmport++); |
|
|
| 841 |
} |
| 842 |
for (i = 0; i < workreq->cmd_len; i++) { |
| 843 |
outb(workreq->cmnd[i], tmport++); |
| 844 |
} |
642 |
} |
| 845 |
tmport = workport + 0x0f; |
643 |
tmport = workportu + 0x0f; |
| 846 |
outb(workreq->device->lun, tmport); |
644 |
outb(workrequ->device->lun, tmport); |
| 847 |
tmport += 0x02; |
645 |
tmport += 0x02; |
| 848 |
/* |
646 |
/* |
| 849 |
* Write the target |
647 |
* Write the target |
| 850 |
*/ |
648 |
*/ |
| 851 |
outb(dev->id[c][target_id].devsp, tmport++); |
649 |
outb(dev->id[target_id].devspu, tmport++); |
| 852 |
#ifdef ED_DBGP |
650 |
|
| 853 |
printk("dev->id[%d][%d].devsp = %2x\n",c,target_id,dev->id[c][target_id].devsp); |
|
|
| 854 |
#endif |
| 855 |
/* |
651 |
/* |
| 856 |
* Figure out the transfer size |
652 |
* Figure out the transfer size |
| 857 |
*/ |
653 |
*/ |
| 858 |
if (workreq->use_sg) { |
654 |
if (workrequ->use_sg) { |
| 859 |
#ifdef ED_DBGP |
|
|
| 860 |
printk("Using SGL\n"); |
| 861 |
#endif |
| 862 |
l = 0; |
655 |
l = 0; |
| 863 |
|
656 |
sgpnt = (struct scatterlist *) workrequ->request_buffer; |
| 864 |
sgpnt = (struct scatterlist *) workreq->request_buffer; |
657 |
sg_count = pci_map_sg(dev->pdev, sgpnt, workrequ->use_sg, |
| 865 |
sg_count = pci_map_sg(dev->pdev, sgpnt, workreq->use_sg, |
658 |
workrequ->sc_data_direction); |
| 866 |
workreq->sc_data_direction); |
659 |
for (i = 0; i < workrequ->use_sg; i++) { |
| 867 |
|
660 |
if (sgpnt[i].length == 0 || workrequ->use_sg > ATP870U_SCATTER) { |
| 868 |
for (i = 0; i < workreq->use_sg; i++) { |
|
|
| 869 |
if (sgpnt[i].length == 0 || workreq->use_sg > ATP870U_SCATTER) { |
| 870 |
panic("Foooooooood fight!"); |
661 |
panic("Foooooooood fight!"); |
| 871 |
} |
662 |
} |
| 872 |
l += sgpnt[i].length; |
663 |
l += sgpnt[i].length; |
| 873 |
} |
664 |
} |
| 874 |
#ifdef ED_DBGP |
665 |
} else if(workrequ->request_bufflen && workrequ->sc_data_direction != PCI_DMA_NONE) { |
| 875 |
printk( "send_s870: workreq->use_sg %d, sg_count %d l %8ld\n", workreq->use_sg, sg_count, l); |
666 |
workrequ->SCp.dma_handle = pci_map_single(dev->pdev, |
| 876 |
#endif |
667 |
workrequ->request_buffer, |
| 877 |
} else if(workreq->request_bufflen && workreq->sc_data_direction != PCI_DMA_NONE) { |
668 |
workrequ->request_bufflen, |
| 878 |
#ifdef ED_DBGP |
669 |
workrequ->sc_data_direction); |
| 879 |
printk("Not using SGL\n"); |
670 |
l = workrequ->request_bufflen; |
| 880 |
#endif |
671 |
} |
| 881 |
workreq->SCp.dma_handle = pci_map_single(dev->pdev, workreq->request_buffer, |
672 |
else l = 0; |
| 882 |
workreq->request_bufflen, |
|
|
| 883 |
workreq->sc_data_direction); |
| 884 |
l = workreq->request_bufflen; |
| 885 |
#ifdef ED_DBGP |
| 886 |
printk( "send_s870: workreq->use_sg %d, l %8ld\n", workreq->use_sg, l); |
| 887 |
#endif |
| 888 |
} else l = 0; |
| 889 |
/* |
673 |
/* |
| 890 |
* Write transfer size |
674 |
* Write transfer size |
| 891 |
*/ |
675 |
*/ |
| 892 |
outb((unsigned char) (((unsigned char *) (&l))[2]), tmport++); |
676 |
outb((unsigned char) (((unsigned char *) (&l))[2]), tmport++); |
| 893 |
outb((unsigned char) (((unsigned char *) (&l))[1]), tmport++); |
677 |
outb((unsigned char) (((unsigned char *) (&l))[1]), tmport++); |
| 894 |
outb((unsigned char) (((unsigned char *) (&l))[0]), tmport++); |
678 |
outb((unsigned char) (((unsigned char *) (&l))[0]), tmport++); |
| 895 |
j = target_id; |
679 |
j = target_id; |
| 896 |
dev->id[c][j].last_len = l; |
680 |
dev->id[j].last_lenu = l; |
| 897 |
dev->id[c][j].tran_len = 0; |
681 |
dev->id[j].tran_lenu = 0; |
| 898 |
#ifdef ED_DBGP |
|
|
| 899 |
printk("dev->id[%2d][%2d].last_len = %d\n",c,j,dev->id[c][j].last_len); |
| 900 |
#endif |
| 901 |
/* |
682 |
/* |
| 902 |
* Flip the wide bits |
683 |
* Flip the wide bits |
| 903 |
*/ |
684 |
*/ |
| 904 |
if ((j & 0x08) != 0) { |
685 |
if ((j & 0x08) != 0) { |
| 905 |
j = (j & 0x07) | 0x40; |
686 |
j = (j & 0x07) | 0x40; |
| 906 |
} |
687 |
} |
| 907 |
/* |
688 |
/* |
| 908 |
* Check transfer direction |
689 |
* Check transfer direction |
| 909 |
*/ |
690 |
*/ |
| 910 |
if (workreq->sc_data_direction == DMA_TO_DEVICE) { |
691 |
if (workrequ->sc_data_direction == DMA_TO_DEVICE) { |
| 911 |
outb((unsigned char) (j | 0x20), tmport++); |
692 |
outb((unsigned char) (j | 0x20), tmport++); |
| 912 |
} else { |
693 |
} else { |
| 913 |
outb(j, tmport++); |
694 |
outb(j, tmport++); |
| 914 |
} |
695 |
} |
| 915 |
outb((unsigned char) (inb(tmport) | 0x80), tmport); |
696 |
outb((unsigned char) (inb(tmport) | 0x80), tmport); |
| 916 |
outb(0x80, tmport); |
697 |
outb(0x80, tmport); |
| 917 |
tmport = workport + 0x1c; |
698 |
tmport = workportu + 0x1c; |
| 918 |
dev->id[c][target_id].dirct = 0; |
699 |
dev->id[target_id].dirctu = 0; |
| 919 |
if (l == 0) { |
700 |
if (l == 0) { |
| 920 |
if (inb(tmport) == 0) { |
701 |
if (inb(tmport) == 0) { |
| 921 |
tmport = workport + 0x18; |
702 |
tmport = workportu + 0x18; |
| 922 |
#ifdef ED_DBGP |
|
|
| 923 |
printk("change SCSI_CMD_REG 0x08\n"); |
| 924 |
#endif |
| 925 |
outb(0x08, tmport); |
703 |
outb(0x08, tmport); |
| 926 |
} else { |
704 |
} else { |
| 927 |
dev->last_cmd[c] |= 0x40; |
705 |
dev->last_cmd |= 0x40; |
| 928 |
} |
706 |
} |
| 929 |
dev->in_snd[c] = 0; |
707 |
dev->in_snd = 0; |
| 930 |
return; |
708 |
return; |
| 931 |
} |
709 |
} |
| 932 |
tmpcip = dev->pciport[c]; |
710 |
tmpcip = dev->pciport; |
| 933 |
prd = dev->id[c][target_id].prd_table; |
711 |
prd = dev->id[target_id].prd_tableu; |
| 934 |
dev->id[c][target_id].prd_pos = prd; |
712 |
dev->id[target_id].prd_posu = prd; |
| 935 |
|
713 |
|
| 936 |
/* |
714 |
/* |
| 937 |
* Now write the request list. Either as scatter/gather or as |
715 |
* Now write the request list. Either as scatter/gather or as |
| 938 |
* a linear chain. |
716 |
* a linear chain. |
| 939 |
*/ |
717 |
*/ |
| 940 |
|
718 |
|
| 941 |
if (workreq->use_sg) { |
719 |
if (workrequ->use_sg) { |
| 942 |
sgpnt = (struct scatterlist *) workreq->request_buffer; |
720 |
sgpnt = (struct scatterlist *) workrequ->request_buffer; |
| 943 |
i = 0; |
721 |
i = 0; |
| 944 |
for (j = 0; j < workreq->use_sg; j++) { |
722 |
for (j = 0; j < workrequ->use_sg; j++) { |
| 945 |
bttl = sg_dma_address(&sgpnt[j]); |
723 |
bttl = sg_dma_address(&sgpnt[j]); |
| 946 |
l=sg_dma_len(&sgpnt[j]); |
724 |
l = sg_dma_len(&sgpnt[j]); |
| 947 |
#ifdef ED_DBGP |
725 |
while (l > 0x10000) { |
| 948 |
printk("1. bttl %x, l %x\n",bttl, l); |
|
|
| 949 |
#endif |
| 950 |
while (l > 0x10000) { |
| 951 |
(((u16 *) (prd))[i + 3]) = 0x0000; |
726 |
(((u16 *) (prd))[i + 3]) = 0x0000; |
| 952 |
(((u16 *) (prd))[i + 2]) = 0x0000; |
727 |
(((u16 *) (prd))[i + 2]) = 0x0000; |
| 953 |
(((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl); |
728 |
(((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl); |
|
Lines 958-1062
Link Here
|
| 958 |
(((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl); |
733 |
(((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl); |
| 959 |
(((u16 *) (prd))[i + 2]) = cpu_to_le16(l); |
734 |
(((u16 *) (prd))[i + 2]) = cpu_to_le16(l); |
| 960 |
(((u16 *) (prd))[i + 3]) = 0; |
735 |
(((u16 *) (prd))[i + 3]) = 0; |
| 961 |
i += 0x04; |
736 |
i += 0x04; |
| 962 |
} |
737 |
} |
| 963 |
(((u16 *) (prd))[i - 1]) = cpu_to_le16(0x8000); |
738 |
(((u16 *) (prd))[i - 1]) = cpu_to_le16(0x8000); |
| 964 |
#ifdef ED_DBGP |
|
|
| 965 |
printk("prd %4x %4x %4x %4x\n",(((unsigned short int *)prd)[0]),(((unsigned short int *)prd)[1]),(((unsigned short int *)prd)[2]),(((unsigned short int *)prd)[3])); |
| 966 |
printk("2. bttl %x, l %x\n",bttl, l); |
| 967 |
#endif |
| 968 |
} else { |
739 |
} else { |
| 969 |
/* |
740 |
/* |
| 970 |
* For a linear request write a chain of blocks |
741 |
* For a linear request write a chain of blocks |
| 971 |
*/ |
742 |
*/ |
| 972 |
bttl = workreq->SCp.dma_handle; |
743 |
bttl = workrequ->SCp.dma_handle; |
| 973 |
l = workreq->request_bufflen; |
744 |
l = workrequ->request_bufflen; |
| 974 |
i = 0; |
745 |
i = 0; |
| 975 |
#ifdef ED_DBGP |
|
|
| 976 |
printk("3. bttl %x, l %x\n",bttl, l); |
| 977 |
#endif |
| 978 |
while (l > 0x10000) { |
746 |
while (l > 0x10000) { |
| 979 |
(((u16 *) (prd))[i + 3]) = 0x0000; |
747 |
(((u16 *) (prd))[i + 3]) = 0x0000; |
| 980 |
(((u16 *) (prd))[i + 2]) = 0x0000; |
748 |
(((u16 *) (prd))[i + 2]) = 0x0000; |
| 981 |
(((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl); |
749 |
(((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl); |
| 982 |
l -= 0x10000; |
750 |
l -= 0x10000; |
| 983 |
bttl += 0x10000; |
751 |
bttl += 0x10000; |
| 984 |
i += 0x04; |
752 |
i += 0x04; |
| 985 |
} |
753 |
} |
| 986 |
(((u16 *) (prd))[i + 3]) = cpu_to_le16(0x8000); |
754 |
(((u16 *) (prd))[i + 3]) = cpu_to_le16(0x8000); |
| 987 |
(((u16 *) (prd))[i + 2]) = cpu_to_le16(l); |
755 |
(((u16 *) (prd))[i + 2]) = cpu_to_le16(l); |
| 988 |
(((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl); |
756 |
(((u32 *) (prd))[i >> 1]) = cpu_to_le32(bttl); |
| 989 |
#ifdef ED_DBGP |
757 |
} |
| 990 |
printk("prd %4x %4x %4x %4x\n",(((unsigned short int *)prd)[0]),(((unsigned short int *)prd)[1]),(((unsigned short int *)prd)[2]),(((unsigned short int *)prd)[3])); |
758 |
tmpcip = tmpcip + 4; |
| 991 |
printk("4. bttl %x, l %x\n",bttl, l); |
759 |
dev->id[target_id].prdaddru = dev->id[target_id].prd_phys; |
| 992 |
#endif |
760 |
outl(dev->id[target_id].prd_phys, tmpcip); |
| 993 |
|
|
|
| 994 |
} |
| 995 |
tmpcip += 4; |
| 996 |
#ifdef ED_DBGP |
| 997 |
printk("send_s870: prdaddr_2 0x%8x tmpcip %x target_id %d\n", dev->id[c][target_id].prdaddr,tmpcip,target_id); |
| 998 |
#endif |
| 999 |
outl(dev->id[c][target_id].prdaddr, tmpcip); |
| 1000 |
tmpcip = tmpcip - 2; |
761 |
tmpcip = tmpcip - 2; |
| 1001 |
outb(0x06, tmpcip); |
762 |
outb(0x06, tmpcip); |
| 1002 |
outb(0x00, tmpcip); |
763 |
outb(0x00, tmpcip); |
| 1003 |
if (dev->dev_id == ATP885_DEVID) { |
764 |
tmpcip = tmpcip - 2; |
| 1004 |
tmpcip--; |
765 |
|
| 1005 |
j=inb(tmpcip) & 0xf3; |
766 |
if (dev->deviceid != 0x8081) { |
| 1006 |
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || |
767 |
tmport = workportu + 0x3a; |
| 1007 |
(workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { |
768 |
if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) || (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a)) { |
| 1008 |
j |= 0x0c; |
|
|
| 1009 |
} |
| 1010 |
outb(j,tmpcip); |
| 1011 |
tmpcip--; |
| 1012 |
} else if ((dev->dev_id == ATP880_DEVID1) || |
| 1013 |
(dev->dev_id == ATP880_DEVID2)) { |
| 1014 |
tmpcip =tmpcip -2; |
| 1015 |
tmport = workport - 0x05; |
| 1016 |
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { |
| 1017 |
outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport); |
| 1018 |
} else { |
| 1019 |
outb((unsigned char) (inb(tmport) & 0x3f), tmport); |
| 1020 |
} |
| 1021 |
} else { |
| 1022 |
tmpcip =tmpcip -2; |
| 1023 |
tmport = workport + 0x3a; |
| 1024 |
if ((workreq->cmnd[0] == 0x08) || (workreq->cmnd[0] == 0x28) || (workreq->cmnd[0] == 0x0a) || (workreq->cmnd[0] == 0x2a)) { |
| 1025 |
outb((inb(tmport) & 0xf3) | 0x08, tmport); |
769 |
outb((inb(tmport) & 0xf3) | 0x08, tmport); |
| 1026 |
} else { |
770 |
} else { |
| 1027 |
outb(inb(tmport) & 0xf3, tmport); |
771 |
outb(inb(tmport) & 0xf3, tmport); |
| 1028 |
} |
772 |
} |
| 1029 |
} |
773 |
} else { |
| 1030 |
tmport = workport + 0x1c; |
774 |
tmport = workportu - 0x05; |
|
|
775 |
if ((dev->ata_cdbu[0] == 0x08) || (dev->ata_cdbu[0] == 0x28) || (dev->ata_cdbu[0] == 0x0a) || (dev->ata_cdbu[0] == 0x2a)) { |
| 776 |
outb((unsigned char) ((inb(tmport) & 0x3f) | 0xc0), tmport); |
| 777 |
} else { |
| 778 |
outb((unsigned char) (inb(tmport) & 0x3f), tmport); |
| 779 |
} |
| 780 |
} |
| 781 |
tmport = workportu + 0x1c; |
| 1031 |
|
782 |
|
| 1032 |
if(workreq->sc_data_direction == DMA_TO_DEVICE) { |
783 |
if (workrequ->sc_data_direction == DMA_TO_DEVICE) { |
| 1033 |
dev->id[c][target_id].dirct = 0x20; |
784 |
dev->id[target_id].dirctu = 0x20; |
| 1034 |
if (inb(tmport) == 0) { |
785 |
if (inb(tmport) == 0) { |
| 1035 |
tmport = workport + 0x18; |
786 |
tmport = workportu + 0x18; |
| 1036 |
outb(0x08, tmport); |
787 |
outb(0x08, tmport); |
| 1037 |
outb(0x01, tmpcip); |
788 |
outb(0x01, tmpcip); |
| 1038 |
#ifdef ED_DBGP |
|
|
| 1039 |
printk( "start DMA(to target)\n"); |
| 1040 |
#endif |
| 1041 |
} else { |
789 |
} else { |
| 1042 |
dev->last_cmd[c] |= 0x40; |
790 |
dev->last_cmd |= 0x40; |
| 1043 |
} |
791 |
} |
| 1044 |
dev->in_snd[c] = 0; |
792 |
dev->in_snd = 0; |
| 1045 |
return; |
793 |
return; |
| 1046 |
} |
794 |
} |
| 1047 |
if (inb(tmport) == 0) { |
795 |
if (inb(tmport) == 0) { |
| 1048 |
tmport = workport + 0x18; |
796 |
tmport = workportu + 0x18; |
| 1049 |
outb(0x08, tmport); |
797 |
outb(0x08, tmport); |
| 1050 |
outb(0x09, tmpcip); |
798 |
outb(0x09, tmpcip); |
| 1051 |
#ifdef ED_DBGP |
|
|
| 1052 |
printk( "start DMA(to host)\n"); |
| 1053 |
#endif |
| 1054 |
} else { |
799 |
} else { |
| 1055 |
dev->last_cmd[c] |= 0x40; |
800 |
dev->last_cmd |= 0x40; |
| 1056 |
} |
801 |
} |
| 1057 |
dev->in_snd[c] = 0; |
802 |
dev->in_snd = 0; |
| 1058 |
return; |
|
|
| 1059 |
|
| 1060 |
} |
803 |
} |
| 1061 |
|
804 |
|
| 1062 |
static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val) |
805 |
static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val) |
|
Lines 1065-1071
Link Here
|
| 1065 |
unsigned short int i, k; |
808 |
unsigned short int i, k; |
| 1066 |
unsigned char j; |
809 |
unsigned char j; |
| 1067 |
|
810 |
|
| 1068 |
tmport = dev->ioport[0] + 0x1c; |
811 |
tmport = dev->ioport + 0x1c; |
| 1069 |
outw(*val, tmport); |
812 |
outw(*val, tmport); |
| 1070 |
FUN_D7: |
813 |
FUN_D7: |
| 1071 |
for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ |
814 |
for (i = 0; i < 10; i++) { /* stable >= bus settle delay(400 ns) */ |
|
Lines 1120-1143
Link Here
|
| 1120 |
} |
863 |
} |
| 1121 |
*/ |
864 |
*/ |
| 1122 |
|
865 |
|
| 1123 |
tmport = dev->ioport[0] + 1; |
866 |
tmport = dev->ioport + 1; |
| 1124 |
outb(0x08, tmport++); |
867 |
outb(0x08, tmport++); |
| 1125 |
outb(0x7f, tmport); |
868 |
outb(0x7f, tmport); |
| 1126 |
tmport = dev->ioport[0] + 0x11; |
869 |
tmport = dev->ioport + 0x11; |
| 1127 |
outb(0x20, tmport); |
870 |
outb(0x20, tmport); |
| 1128 |
|
871 |
|
| 1129 |
if ((dev->scam_on & 0x40) == 0) { |
872 |
if ((dev->scam_on & 0x40) == 0) { |
| 1130 |
return; |
873 |
return; |
| 1131 |
} |
874 |
} |
| 1132 |
m = 1; |
875 |
m = 1; |
| 1133 |
m <<= dev->host_id[0]; |
876 |
m <<= dev->host_idu; |
| 1134 |
j = 16; |
877 |
j = 16; |
| 1135 |
if (dev->chip_ver < 4) { |
878 |
if (dev->chip_veru < 4) { |
| 1136 |
m |= 0xff00; |
879 |
m |= 0xff00; |
| 1137 |
j = 8; |
880 |
j = 8; |
| 1138 |
} |
881 |
} |
| 1139 |
assignid_map = m; |
882 |
assignid_map = m; |
| 1140 |
tmport = dev->ioport[0] + 0x02; |
883 |
tmport = dev->ioport + 0x02; |
| 1141 |
outb(0x02, tmport++); /* 2*2=4ms,3EH 2/32*3E=3.9ms */ |
884 |
outb(0x02, tmport++); /* 2*2=4ms,3EH 2/32*3E=3.9ms */ |
| 1142 |
outb(0, tmport++); |
885 |
outb(0, tmport++); |
| 1143 |
outb(0, tmport++); |
886 |
outb(0, tmport++); |
|
Lines 1152-1158
Link Here
|
| 1152 |
if ((m & assignid_map) != 0) { |
895 |
if ((m & assignid_map) != 0) { |
| 1153 |
continue; |
896 |
continue; |
| 1154 |
} |
897 |
} |
| 1155 |
tmport = dev->ioport[0] + 0x0f; |
898 |
tmport = dev->ioport + 0x0f; |
| 1156 |
outb(0, tmport++); |
899 |
outb(0, tmport++); |
| 1157 |
tmport += 0x02; |
900 |
tmport += 0x02; |
| 1158 |
outb(0, tmport++); |
901 |
outb(0, tmport++); |
|
Lines 1164-1204
Link Here
|
| 1164 |
k = i; |
907 |
k = i; |
| 1165 |
} |
908 |
} |
| 1166 |
outb(k, tmport++); |
909 |
outb(k, tmport++); |
| 1167 |
tmport = dev->ioport[0] + 0x1b; |
910 |
tmport = dev->ioport + 0x1b; |
| 1168 |
if (dev->chip_ver == 4) { |
911 |
if (dev->chip_veru == 4) { |
| 1169 |
outb(0x01, tmport); |
912 |
outb(0x01, tmport); |
| 1170 |
} else { |
913 |
} else { |
| 1171 |
outb(0x00, tmport); |
914 |
outb(0x00, tmport); |
| 1172 |
} |
915 |
} |
| 1173 |
wait_rdyok: |
916 |
wait_rdyok: |
| 1174 |
tmport = dev->ioport[0] + 0x18; |
917 |
tmport = dev->ioport + 0x18; |
| 1175 |
outb(0x09, tmport); |
918 |
outb(0x09, tmport); |
| 1176 |
tmport += 0x07; |
919 |
tmport += 0x07; |
| 1177 |
|
920 |
|
| 1178 |
while ((inb(tmport) & 0x80) == 0x00) |
921 |
while ((inb(tmport) & 0x80) == 0x00); |
| 1179 |
cpu_relax(); |
|
|
| 1180 |
tmport -= 0x08; |
922 |
tmport -= 0x08; |
| 1181 |
k = inb(tmport); |
923 |
k = inb(tmport); |
| 1182 |
if (k != 0x16) { |
924 |
if (k != 0x16) { |
| 1183 |
if ((k == 0x85) || (k == 0x42)) { |
925 |
if ((k == 0x85) || (k == 0x42)) { |
| 1184 |
continue; |
926 |
continue; |
| 1185 |
} |
927 |
} |
| 1186 |
tmport = dev->ioport[0] + 0x10; |
928 |
tmport = dev->ioport + 0x10; |
| 1187 |
outb(0x41, tmport); |
929 |
outb(0x41, tmport); |
| 1188 |
goto wait_rdyok; |
930 |
goto wait_rdyok; |
| 1189 |
} |
931 |
} |
| 1190 |
assignid_map |= m; |
932 |
assignid_map |= m; |
| 1191 |
|
933 |
|
| 1192 |
} |
934 |
} |
| 1193 |
tmport = dev->ioport[0] + 0x02; |
935 |
tmport = dev->ioport + 0x02; |
| 1194 |
outb(0x7f, tmport); |
936 |
outb(0x7f, tmport); |
| 1195 |
tmport = dev->ioport[0] + 0x1b; |
937 |
tmport = dev->ioport + 0x1b; |
| 1196 |
outb(0x02, tmport); |
938 |
outb(0x02, tmport); |
| 1197 |
|
939 |
|
| 1198 |
outb(0, 0x80); |
940 |
outb(0, 0x80); |
| 1199 |
|
941 |
|
| 1200 |
val = 0x0080; /* bsy */ |
942 |
val = 0x0080; /* bsy */ |
| 1201 |
tmport = dev->ioport[0] + 0x1c; |
943 |
tmport = dev->ioport + 0x1c; |
| 1202 |
outw(val, tmport); |
944 |
outw(val, tmport); |
| 1203 |
val |= 0x0040; /* sel */ |
945 |
val |= 0x0040; /* sel */ |
| 1204 |
outw(val, tmport); |
946 |
outw(val, tmport); |
|
Lines 1242-1254
Link Here
|
| 1242 |
if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */ |
984 |
if ((inb(tmport) & 0x80) == 0x00) { /* bsy ? */ |
| 1243 |
outw(0, tmport--); |
985 |
outw(0, tmport--); |
| 1244 |
outb(0, tmport); |
986 |
outb(0, tmport); |
| 1245 |
tmport = dev->ioport[0] + 0x15; |
987 |
tmport = dev->ioport + 0x15; |
| 1246 |
outb(0, tmport); |
988 |
outb(0, tmport); |
| 1247 |
tmport += 0x03; |
989 |
tmport += 0x03; |
| 1248 |
outb(0x09, tmport); |
990 |
outb(0x09, tmport); |
| 1249 |
tmport += 0x07; |
991 |
tmport += 0x07; |
| 1250 |
while ((inb(tmport) & 0x80) == 0) |
992 |
while ((inb(tmport) & 0x80) == 0); |
| 1251 |
cpu_relax(); |
|
|
| 1252 |
tmport -= 0x08; |
993 |
tmport -= 0x08; |
| 1253 |
inb(tmport); |
994 |
inb(tmport); |
| 1254 |
return; |
995 |
return; |
|
Lines 1344-1350
Link Here
|
| 1344 |
|
1085 |
|
| 1345 |
} |
1086 |
} |
| 1346 |
|
1087 |
|
| 1347 |
static void is870(struct atp_unit *dev, unsigned int wkport) |
1088 |
static void is870(struct Scsi_Host *host, unsigned int wkport) |
| 1348 |
{ |
1089 |
{ |
| 1349 |
unsigned int tmport; |
1090 |
unsigned int tmport; |
| 1350 |
unsigned char i, j, k, rmb, n; |
1091 |
unsigned char i, j, k, rmb, n; |
|
Lines 1356-1380
Link Here
|
| 1356 |
static unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0c, 0x0e }; |
1097 |
static unsigned char synu[6] = { 0x80, 1, 3, 1, 0x0c, 0x0e }; |
| 1357 |
static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 }; |
1098 |
static unsigned char synw[6] = { 0x80, 1, 3, 1, 0x0c, 0x07 }; |
| 1358 |
static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; |
1099 |
static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; |
| 1359 |
|
1100 |
struct atp_unit *dev = (struct atp_unit *)&host->hostdata; |
|
|
1101 |
|
| 1360 |
tmport = wkport + 0x3a; |
1102 |
tmport = wkport + 0x3a; |
| 1361 |
outb((unsigned char) (inb(tmport) | 0x10), tmport); |
1103 |
outb((unsigned char) (inb(tmport) | 0x10), tmport); |
| 1362 |
|
1104 |
|
| 1363 |
for (i = 0; i < 16; i++) { |
1105 |
for (i = 0; i < 16; i++) { |
| 1364 |
if ((dev->chip_ver != 4) && (i > 7)) { |
1106 |
if ((dev->chip_veru != 4) && (i > 7)) { |
| 1365 |
break; |
1107 |
break; |
| 1366 |
} |
1108 |
} |
| 1367 |
m = 1; |
1109 |
m = 1; |
| 1368 |
m = m << i; |
1110 |
m = m << i; |
| 1369 |
if ((m & dev->active_id[0]) != 0) { |
1111 |
if ((m & dev->active_idu) != 0) { |
| 1370 |
continue; |
1112 |
continue; |
| 1371 |
} |
1113 |
} |
| 1372 |
if (i == dev->host_id[0]) { |
1114 |
if (i == dev->host_idu) { |
| 1373 |
printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[0]); |
1115 |
printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_idu); |
| 1374 |
continue; |
1116 |
continue; |
| 1375 |
} |
1117 |
} |
| 1376 |
tmport = wkport + 0x1b; |
1118 |
tmport = wkport + 0x1b; |
| 1377 |
if (dev->chip_ver == 4) { |
1119 |
if (dev->chip_veru == 4) { |
| 1378 |
outb(0x01, tmport); |
1120 |
outb(0x01, tmport); |
| 1379 |
} else { |
1121 |
} else { |
| 1380 |
outb(0x00, tmport); |
1122 |
outb(0x00, tmport); |
|
Lines 1391-1397
Link Here
|
| 1391 |
tmport += 0x06; |
1133 |
tmport += 0x06; |
| 1392 |
outb(0, tmport); |
1134 |
outb(0, tmport); |
| 1393 |
tmport += 0x02; |
1135 |
tmport += 0x02; |
| 1394 |
outb(dev->id[0][i].devsp, tmport++); |
1136 |
outb(dev->id[i].devspu, tmport++); |
| 1395 |
outb(0, tmport++); |
1137 |
outb(0, tmport++); |
| 1396 |
outb(satn[6], tmport++); |
1138 |
outb(satn[6], tmport++); |
| 1397 |
outb(satn[7], tmport++); |
1139 |
outb(satn[7], tmport++); |
|
Lines 1404-1420
Link Here
|
| 1404 |
outb(satn[8], tmport); |
1146 |
outb(satn[8], tmport); |
| 1405 |
tmport += 0x07; |
1147 |
tmport += 0x07; |
| 1406 |
|
1148 |
|
| 1407 |
while ((inb(tmport) & 0x80) == 0x00) |
1149 |
while ((inb(tmport) & 0x80) == 0x00); |
| 1408 |
cpu_relax(); |
|
|
| 1409 |
|
| 1410 |
tmport -= 0x08; |
1150 |
tmport -= 0x08; |
| 1411 |
if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) |
1151 |
if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { |
| 1412 |
continue; |
1152 |
continue; |
| 1413 |
|
1153 |
} |
| 1414 |
while (inb(tmport) != 0x8e) |
1154 |
while (inb(tmport) != 0x8e); |
| 1415 |
cpu_relax(); |
1155 |
dev->active_idu |= m; |
| 1416 |
|
|
|
| 1417 |
dev->active_id[0] |= m; |
| 1418 |
|
1156 |
|
| 1419 |
tmport = wkport + 0x10; |
1157 |
tmport = wkport + 0x10; |
| 1420 |
outb(0x30, tmport); |
1158 |
outb(0x30, tmport); |
|
Lines 1425-1432
Link Here
|
| 1425 |
tmport = wkport + 0x18; |
1163 |
tmport = wkport + 0x18; |
| 1426 |
outb(0x08, tmport); |
1164 |
outb(0x08, tmport); |
| 1427 |
tmport += 0x07; |
1165 |
tmport += 0x07; |
| 1428 |
while ((inb(tmport) & 0x80) == 0x00) |
1166 |
while ((inb(tmport) & 0x80) == 0x00); |
| 1429 |
cpu_relax(); |
|
|
| 1430 |
tmport -= 0x08; |
1167 |
tmport -= 0x08; |
| 1431 |
j = inb(tmport); |
1168 |
j = inb(tmport); |
| 1432 |
if (j != 0x16) { |
1169 |
if (j != 0x16) { |
|
Lines 1445-1472
Link Here
|
| 1445 |
tmport += 0x07; |
1182 |
tmport += 0x07; |
| 1446 |
outb(0, tmport); |
1183 |
outb(0, tmport); |
| 1447 |
tmport += 0x02; |
1184 |
tmport += 0x02; |
| 1448 |
outb(dev->id[0][i].devsp, tmport++); |
1185 |
outb(dev->id[i].devspu, tmport++); |
| 1449 |
outb(0, tmport++); |
1186 |
outb(0, tmport++); |
| 1450 |
outb(inqd[6], tmport++); |
1187 |
outb(inqd[6], tmport++); |
| 1451 |
outb(inqd[7], tmport++); |
1188 |
outb(inqd[7], tmport++); |
| 1452 |
tmport += 0x03; |
1189 |
tmport += 0x03; |
| 1453 |
outb(inqd[8], tmport); |
1190 |
outb(inqd[8], tmport); |
| 1454 |
tmport += 0x07; |
1191 |
tmport += 0x07; |
| 1455 |
|
1192 |
while ((inb(tmport) & 0x80) == 0x00); |
| 1456 |
while ((inb(tmport) & 0x80) == 0x00) |
|
|
| 1457 |
cpu_relax(); |
| 1458 |
|
| 1459 |
tmport -= 0x08; |
1193 |
tmport -= 0x08; |
| 1460 |
if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) |
1194 |
if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { |
| 1461 |
continue; |
1195 |
continue; |
| 1462 |
|
1196 |
} |
| 1463 |
while (inb(tmport) != 0x8e) |
1197 |
while (inb(tmport) != 0x8e); |
| 1464 |
cpu_relax(); |
|
|
| 1465 |
|
| 1466 |
tmport = wkport + 0x1b; |
1198 |
tmport = wkport + 0x1b; |
| 1467 |
if (dev->chip_ver == 4) |
1199 |
if (dev->chip_veru == 4) { |
| 1468 |
outb(0x00, tmport); |
1200 |
outb(0x00, tmport); |
| 1469 |
|
1201 |
} |
| 1470 |
tmport = wkport + 0x18; |
1202 |
tmport = wkport + 0x18; |
| 1471 |
outb(0x08, tmport); |
1203 |
outb(0x08, tmport); |
| 1472 |
tmport += 0x07; |
1204 |
tmport += 0x07; |
|
Lines 1496-1505
Link Here
|
| 1496 |
tmport += 0x03; |
1228 |
tmport += 0x03; |
| 1497 |
outb(0x08, tmport); |
1229 |
outb(0x08, tmport); |
| 1498 |
tmport += 0x07; |
1230 |
tmport += 0x07; |
| 1499 |
|
1231 |
while ((inb(tmport) & 0x80) == 0x00); |
| 1500 |
while ((inb(tmport) & 0x80) == 0x00) |
|
|
| 1501 |
cpu_relax(); |
| 1502 |
|
| 1503 |
tmport -= 0x08; |
1232 |
tmport -= 0x08; |
| 1504 |
if (inb(tmport) != 0x16) { |
1233 |
if (inb(tmport) != 0x16) { |
| 1505 |
goto sel_ok; |
1234 |
goto sel_ok; |
|
Lines 1507-1522
Link Here
|
| 1507 |
inq_ok: |
1236 |
inq_ok: |
| 1508 |
mbuf[36] = 0; |
1237 |
mbuf[36] = 0; |
| 1509 |
printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]); |
1238 |
printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]); |
| 1510 |
dev->id[0][i].devtype = mbuf[0]; |
1239 |
dev->id[i].devtypeu = mbuf[0]; |
| 1511 |
rmb = mbuf[1]; |
1240 |
rmb = mbuf[1]; |
| 1512 |
n = mbuf[7]; |
1241 |
n = mbuf[7]; |
| 1513 |
if (dev->chip_ver != 4) { |
1242 |
if (dev->chip_veru != 4) { |
| 1514 |
goto not_wide; |
1243 |
goto not_wide; |
| 1515 |
} |
1244 |
} |
| 1516 |
if ((mbuf[7] & 0x60) == 0) { |
1245 |
if ((mbuf[7] & 0x60) == 0) { |
| 1517 |
goto not_wide; |
1246 |
goto not_wide; |
| 1518 |
} |
1247 |
} |
| 1519 |
if ((dev->global_map[0] & 0x20) == 0) { |
1248 |
if ((dev->global_map & 0x20) == 0) { |
| 1520 |
goto not_wide; |
1249 |
goto not_wide; |
| 1521 |
} |
1250 |
} |
| 1522 |
tmport = wkport + 0x1b; |
1251 |
tmport = wkport + 0x1b; |
|
Lines 1531-1537
Link Here
|
| 1531 |
tmport += 0x06; |
1260 |
tmport += 0x06; |
| 1532 |
outb(0, tmport); |
1261 |
outb(0, tmport); |
| 1533 |
tmport += 0x02; |
1262 |
tmport += 0x02; |
| 1534 |
outb(dev->id[0][i].devsp, tmport++); |
1263 |
outb(dev->id[i].devspu, tmport++); |
| 1535 |
outb(0, tmport++); |
1264 |
outb(0, tmport++); |
| 1536 |
outb(satn[6], tmport++); |
1265 |
outb(satn[6], tmport++); |
| 1537 |
outb(satn[7], tmport++); |
1266 |
outb(satn[7], tmport++); |
|
Lines 1539-1554
Link Here
|
| 1539 |
outb(satn[8], tmport); |
1268 |
outb(satn[8], tmport); |
| 1540 |
tmport += 0x07; |
1269 |
tmport += 0x07; |
| 1541 |
|
1270 |
|
| 1542 |
while ((inb(tmport) & 0x80) == 0x00) |
1271 |
while ((inb(tmport) & 0x80) == 0x00); |
| 1543 |
cpu_relax(); |
|
|
| 1544 |
|
| 1545 |
tmport -= 0x08; |
1272 |
tmport -= 0x08; |
| 1546 |
if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) |
1273 |
if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { |
| 1547 |
continue; |
1274 |
continue; |
| 1548 |
|
1275 |
} |
| 1549 |
while (inb(tmport) != 0x8e) |
1276 |
while (inb(tmport) != 0x8e); |
| 1550 |
cpu_relax(); |
|
|
| 1551 |
|
| 1552 |
try_wide: |
1277 |
try_wide: |
| 1553 |
j = 0; |
1278 |
j = 0; |
| 1554 |
tmport = wkport + 0x14; |
1279 |
tmport = wkport + 0x14; |
|
Lines 1565-1574
Link Here
|
| 1565 |
} |
1290 |
} |
| 1566 |
} |
1291 |
} |
| 1567 |
tmport -= 0x08; |
1292 |
tmport -= 0x08; |
| 1568 |
|
1293 |
while ((inb(tmport) & 0x80) == 0x00); |
| 1569 |
while ((inb(tmport) & 0x80) == 0x00) |
|
|
| 1570 |
cpu_relax(); |
| 1571 |
|
| 1572 |
j = inb(tmport) & 0x0f; |
1294 |
j = inb(tmport) & 0x0f; |
| 1573 |
if (j == 0x0f) { |
1295 |
if (j == 0x0f) { |
| 1574 |
goto widep_in; |
1296 |
goto widep_in; |
|
Lines 1641-1650
Link Here
|
| 1641 |
tmport += 0x04; |
1363 |
tmport += 0x04; |
| 1642 |
outb(0x08, tmport); |
1364 |
outb(0x08, tmport); |
| 1643 |
tmport += 0x07; |
1365 |
tmport += 0x07; |
| 1644 |
|
1366 |
while ((inb(tmport) & 0x80) == 0x00); |
| 1645 |
while ((inb(tmport) & 0x80) == 0x00) |
|
|
| 1646 |
cpu_relax(); |
| 1647 |
|
| 1648 |
tmport -= 0x08; |
1367 |
tmport -= 0x08; |
| 1649 |
j = inb(tmport); |
1368 |
j = inb(tmport); |
| 1650 |
if (j != 0x16) { |
1369 |
if (j != 0x16) { |
|
Lines 1667-1682
Link Here
|
| 1667 |
} |
1386 |
} |
| 1668 |
m = 1; |
1387 |
m = 1; |
| 1669 |
m = m << i; |
1388 |
m = m << i; |
| 1670 |
dev->wide_id[0] |= m; |
1389 |
dev->wide_idu |= m; |
| 1671 |
not_wide: |
1390 |
not_wide: |
| 1672 |
if ((dev->id[0][i].devtype == 0x00) || (dev->id[0][i].devtype == 0x07) || ((dev->id[0][i].devtype == 0x05) && ((n & 0x10) != 0))) { |
1391 |
if ((dev->id[i].devtypeu == 0x00) || (dev->id[i].devtypeu == 0x07) || ((dev->id[i].devtypeu == 0x05) && ((n & 0x10) != 0))) { |
| 1673 |
goto set_sync; |
1392 |
goto set_sync; |
| 1674 |
} |
1393 |
} |
| 1675 |
continue; |
1394 |
continue; |
| 1676 |
set_sync: |
1395 |
set_sync: |
| 1677 |
tmport = wkport + 0x1b; |
1396 |
tmport = wkport + 0x1b; |
| 1678 |
j = 0; |
1397 |
j = 0; |
| 1679 |
if ((m & dev->wide_id[0]) != 0) { |
1398 |
if ((m & dev->wide_idu) != 0) { |
| 1680 |
j |= 0x01; |
1399 |
j |= 0x01; |
| 1681 |
} |
1400 |
} |
| 1682 |
outb(j, tmport); |
1401 |
outb(j, tmport); |
|
Lines 1690-1696
Link Here
|
| 1690 |
tmport += 0x06; |
1409 |
tmport += 0x06; |
| 1691 |
outb(0, tmport); |
1410 |
outb(0, tmport); |
| 1692 |
tmport += 0x02; |
1411 |
tmport += 0x02; |
| 1693 |
outb(dev->id[0][i].devsp, tmport++); |
1412 |
outb(dev->id[i].devspu, tmport++); |
| 1694 |
outb(0, tmport++); |
1413 |
outb(0, tmport++); |
| 1695 |
outb(satn[6], tmport++); |
1414 |
outb(satn[6], tmport++); |
| 1696 |
outb(satn[7], tmport++); |
1415 |
outb(satn[7], tmport++); |
|
Lines 1698-1713
Link Here
|
| 1698 |
outb(satn[8], tmport); |
1417 |
outb(satn[8], tmport); |
| 1699 |
tmport += 0x07; |
1418 |
tmport += 0x07; |
| 1700 |
|
1419 |
|
| 1701 |
while ((inb(tmport) & 0x80) == 0x00) |
1420 |
while ((inb(tmport) & 0x80) == 0x00); |
| 1702 |
cpu_relax(); |
|
|
| 1703 |
|
| 1704 |
tmport -= 0x08; |
1421 |
tmport -= 0x08; |
| 1705 |
if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) |
1422 |
if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { |
| 1706 |
continue; |
1423 |
continue; |
| 1707 |
|
1424 |
} |
| 1708 |
while (inb(tmport) != 0x8e) |
1425 |
while (inb(tmport) != 0x8e); |
| 1709 |
cpu_relax(); |
|
|
| 1710 |
|
| 1711 |
try_sync: |
1426 |
try_sync: |
| 1712 |
j = 0; |
1427 |
j = 0; |
| 1713 |
tmport = wkport + 0x14; |
1428 |
tmport = wkport + 0x14; |
|
Lines 1719-1728
Link Here
|
| 1719 |
while ((inb(tmport) & 0x80) == 0) { |
1434 |
while ((inb(tmport) & 0x80) == 0) { |
| 1720 |
if ((inb(tmport) & 0x01) != 0) { |
1435 |
if ((inb(tmport) & 0x01) != 0) { |
| 1721 |
tmport -= 0x06; |
1436 |
tmport -= 0x06; |
| 1722 |
if ((m & dev->wide_id[0]) != 0) { |
1437 |
if ((m & dev->wide_idu) != 0) { |
| 1723 |
outb(synw[j++], tmport); |
1438 |
outb(synw[j++], tmport); |
| 1724 |
} else { |
1439 |
} else { |
| 1725 |
if ((m & dev->ultra_map[0]) != 0) { |
1440 |
if ((m & dev->ultra_map) != 0) { |
| 1726 |
outb(synu[j++], tmport); |
1441 |
outb(synu[j++], tmport); |
| 1727 |
} else { |
1442 |
} else { |
| 1728 |
outb(synn[j++], tmport); |
1443 |
outb(synn[j++], tmport); |
|
Lines 1732-1741
Link Here
|
| 1732 |
} |
1447 |
} |
| 1733 |
} |
1448 |
} |
| 1734 |
tmport -= 0x08; |
1449 |
tmport -= 0x08; |
| 1735 |
|
1450 |
while ((inb(tmport) & 0x80) == 0x00); |
| 1736 |
while ((inb(tmport) & 0x80) == 0x00) |
|
|
| 1737 |
cpu_relax(); |
| 1738 |
|
| 1739 |
j = inb(tmport) & 0x0f; |
1451 |
j = inb(tmport) & 0x0f; |
| 1740 |
if (j == 0x0f) { |
1452 |
if (j == 0x0f) { |
| 1741 |
goto phase_ins; |
1453 |
goto phase_ins; |
|
Lines 1793-1802
Link Here
|
| 1793 |
goto phase_ins1; |
1505 |
goto phase_ins1; |
| 1794 |
} |
1506 |
} |
| 1795 |
tmport -= 0x08; |
1507 |
tmport -= 0x08; |
| 1796 |
|
1508 |
while ((inb(tmport) & 0x80) == 0x00); |
| 1797 |
while ((inb(tmport) & 0x80) == 0x00) |
|
|
| 1798 |
cpu_relax(); |
| 1799 |
|
| 1800 |
j = inb(tmport); |
1509 |
j = inb(tmport); |
| 1801 |
if (j == 0x85) { |
1510 |
if (j == 0x85) { |
| 1802 |
goto tar_dcons; |
1511 |
goto tar_dcons; |
|
Lines 1821-1830
Link Here
|
| 1821 |
tmport += 0x04; |
1530 |
tmport += 0x04; |
| 1822 |
outb(0x08, tmport); |
1531 |
outb(0x08, tmport); |
| 1823 |
tmport += 0x07; |
1532 |
tmport += 0x07; |
| 1824 |
|
1533 |
while ((inb(tmport) & 0x80) == 0x00); |
| 1825 |
while ((inb(tmport) & 0x80) == 0x00) |
|
|
| 1826 |
cpu_relax(); |
| 1827 |
|
| 1828 |
tmport -= 0x08; |
1534 |
tmport -= 0x08; |
| 1829 |
j = inb(tmport); |
1535 |
j = inb(tmport); |
| 1830 |
if (j != 0x16) { |
1536 |
if (j != 0x16) { |
|
Lines 1845-1851
Link Here
|
| 1845 |
if (mbuf[4] > 0x0c) { |
1551 |
if (mbuf[4] > 0x0c) { |
| 1846 |
mbuf[4] = 0x0c; |
1552 |
mbuf[4] = 0x0c; |
| 1847 |
} |
1553 |
} |
| 1848 |
dev->id[0][i].devsp = mbuf[4]; |
1554 |
dev->id[i].devspu = mbuf[4]; |
| 1849 |
if ((mbuf[3] < 0x0d) && (rmb == 0)) { |
1555 |
if ((mbuf[3] < 0x0d) && (rmb == 0)) { |
| 1850 |
j = 0xa0; |
1556 |
j = 0xa0; |
| 1851 |
goto set_syn_ok; |
1557 |
goto set_syn_ok; |
|
Lines 1864-1876
Link Here
|
| 1864 |
} |
1570 |
} |
| 1865 |
j = 0x60; |
1571 |
j = 0x60; |
| 1866 |
set_syn_ok: |
1572 |
set_syn_ok: |
| 1867 |
dev->id[0][i].devsp = (dev->id[0][i].devsp & 0x0f) | j; |
1573 |
dev->id[i].devspu = (dev->id[i].devspu & 0x0f) | j; |
| 1868 |
} |
1574 |
} |
| 1869 |
tmport = wkport + 0x3a; |
1575 |
tmport = wkport + 0x3a; |
| 1870 |
outb((unsigned char) (inb(tmport) & 0xef), tmport); |
1576 |
outb((unsigned char) (inb(tmport) & 0xef), tmport); |
| 1871 |
} |
1577 |
} |
| 1872 |
|
1578 |
|
| 1873 |
static void is880(struct atp_unit *dev, unsigned int wkport) |
1579 |
static void is880(struct Scsi_Host *host, unsigned int wkport) |
| 1874 |
{ |
1580 |
{ |
| 1875 |
unsigned int tmport; |
1581 |
unsigned int tmport; |
| 1876 |
unsigned char i, j, k, rmb, n, lvdmode; |
1582 |
unsigned char i, j, k, rmb, n, lvdmode; |
|
Lines 1884-1900
Link Here
|
| 1884 |
unsigned char synuw[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e }; |
1590 |
unsigned char synuw[6] = { 0x80, 1, 3, 1, 0x0a, 0x0e }; |
| 1885 |
static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; |
1591 |
static unsigned char wide[6] = { 0x80, 1, 2, 3, 1, 0 }; |
| 1886 |
static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 }; |
1592 |
static unsigned char u3[9] = { 0x80, 1, 6, 4, 0x09, 00, 0x0e, 0x01, 0x02 }; |
|
|
1593 |
struct atp_unit *dev = (struct atp_unit *)&host->hostdata; |
| 1887 |
|
1594 |
|
| 1888 |
lvdmode = inb(wkport + 0x3f) & 0x40; |
1595 |
lvdmode = inb(wkport + 0x3f) & 0x40; |
| 1889 |
|
1596 |
|
| 1890 |
for (i = 0; i < 16; i++) { |
1597 |
for (i = 0; i < 16; i++) { |
| 1891 |
m = 1; |
1598 |
m = 1; |
| 1892 |
m = m << i; |
1599 |
m = m << i; |
| 1893 |
if ((m & dev->active_id[0]) != 0) { |
1600 |
if ((m & dev->active_idu) != 0) { |
| 1894 |
continue; |
1601 |
continue; |
| 1895 |
} |
1602 |
} |
| 1896 |
if (i == dev->host_id[0]) { |
1603 |
if (i == dev->host_idu) { |
| 1897 |
printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[0]); |
1604 |
printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_idu); |
| 1898 |
continue; |
1605 |
continue; |
| 1899 |
} |
1606 |
} |
| 1900 |
tmport = wkport + 0x5b; |
1607 |
tmport = wkport + 0x5b; |
|
Lines 1911-1917
Link Here
|
| 1911 |
tmport += 0x06; |
1618 |
tmport += 0x06; |
| 1912 |
outb(0, tmport); |
1619 |
outb(0, tmport); |
| 1913 |
tmport += 0x02; |
1620 |
tmport += 0x02; |
| 1914 |
outb(dev->id[0][i].devsp, tmport++); |
1621 |
outb(dev->id[i].devspu, tmport++); |
| 1915 |
outb(0, tmport++); |
1622 |
outb(0, tmport++); |
| 1916 |
outb(satn[6], tmport++); |
1623 |
outb(satn[6], tmport++); |
| 1917 |
outb(satn[7], tmport++); |
1624 |
outb(satn[7], tmport++); |
|
Lines 1924-1940
Link Here
|
| 1924 |
outb(satn[8], tmport); |
1631 |
outb(satn[8], tmport); |
| 1925 |
tmport += 0x07; |
1632 |
tmport += 0x07; |
| 1926 |
|
1633 |
|
| 1927 |
while ((inb(tmport) & 0x80) == 0x00) |
1634 |
while ((inb(tmport) & 0x80) == 0x00); |
| 1928 |
cpu_relax(); |
|
|
| 1929 |
|
| 1930 |
tmport -= 0x08; |
1635 |
tmport -= 0x08; |
| 1931 |
if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) |
1636 |
if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { |
| 1932 |
continue; |
1637 |
continue; |
| 1933 |
|
1638 |
} |
| 1934 |
while (inb(tmport) != 0x8e) |
1639 |
while (inb(tmport) != 0x8e); |
| 1935 |
cpu_relax(); |
1640 |
dev->active_idu |= m; |
| 1936 |
|
|
|
| 1937 |
dev->active_id[0] |= m; |
| 1938 |
|
1641 |
|
| 1939 |
tmport = wkport + 0x50; |
1642 |
tmport = wkport + 0x50; |
| 1940 |
outb(0x30, tmport); |
1643 |
outb(0x30, tmport); |
|
Lines 1945-1954
Link Here
|
| 1945 |
tmport = wkport + 0x58; |
1648 |
tmport = wkport + 0x58; |
| 1946 |
outb(0x08, tmport); |
1649 |
outb(0x08, tmport); |
| 1947 |
tmport += 0x07; |
1650 |
tmport += 0x07; |
| 1948 |
|
1651 |
while ((inb(tmport) & 0x80) == 0x00); |
| 1949 |
while ((inb(tmport) & 0x80) == 0x00) |
|
|
| 1950 |
cpu_relax(); |
| 1951 |
|
| 1952 |
tmport -= 0x08; |
1652 |
tmport -= 0x08; |
| 1953 |
j = inb(tmport); |
1653 |
j = inb(tmport); |
| 1954 |
if (j != 0x16) { |
1654 |
if (j != 0x16) { |
|
Lines 1967-1990
Link Here
|
| 1967 |
tmport += 0x07; |
1667 |
tmport += 0x07; |
| 1968 |
outb(0, tmport); |
1668 |
outb(0, tmport); |
| 1969 |
tmport += 0x02; |
1669 |
tmport += 0x02; |
| 1970 |
outb(dev->id[0][i].devsp, tmport++); |
1670 |
outb(dev->id[i].devspu, tmport++); |
| 1971 |
outb(0, tmport++); |
1671 |
outb(0, tmport++); |
| 1972 |
outb(inqd[6], tmport++); |
1672 |
outb(inqd[6], tmport++); |
| 1973 |
outb(inqd[7], tmport++); |
1673 |
outb(inqd[7], tmport++); |
| 1974 |
tmport += 0x03; |
1674 |
tmport += 0x03; |
| 1975 |
outb(inqd[8], tmport); |
1675 |
outb(inqd[8], tmport); |
| 1976 |
tmport += 0x07; |
1676 |
tmport += 0x07; |
| 1977 |
|
1677 |
while ((inb(tmport) & 0x80) == 0x00); |
| 1978 |
while ((inb(tmport) & 0x80) == 0x00) |
|
|
| 1979 |
cpu_relax(); |
| 1980 |
|
| 1981 |
tmport -= 0x08; |
1678 |
tmport -= 0x08; |
| 1982 |
if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) |
1679 |
if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { |
| 1983 |
continue; |
1680 |
continue; |
| 1984 |
|
1681 |
} |
| 1985 |
while (inb(tmport) != 0x8e) |
1682 |
while (inb(tmport) != 0x8e); |
| 1986 |
cpu_relax(); |
|
|
| 1987 |
|
| 1988 |
tmport = wkport + 0x5b; |
1683 |
tmport = wkport + 0x5b; |
| 1989 |
outb(0x00, tmport); |
1684 |
outb(0x00, tmport); |
| 1990 |
tmport = wkport + 0x58; |
1685 |
tmport = wkport + 0x58; |
|
Lines 2016-2044
Link Here
|
| 2016 |
tmport += 0x03; |
1711 |
tmport += 0x03; |
| 2017 |
outb(0x08, tmport); |
1712 |
outb(0x08, tmport); |
| 2018 |
tmport += 0x07; |
1713 |
tmport += 0x07; |
| 2019 |
while ((inb(tmport) & 0x80) == 0x00) |
1714 |
while ((inb(tmport) & 0x80) == 0x00); |
| 2020 |
cpu_relax(); |
|
|
| 2021 |
|
| 2022 |
tmport -= 0x08; |
1715 |
tmport -= 0x08; |
| 2023 |
if (inb(tmport) != 0x16) |
1716 |
if (inb(tmport) != 0x16) { |
| 2024 |
goto sel_ok; |
1717 |
goto sel_ok; |
| 2025 |
|
1718 |
} |
| 2026 |
inq_ok: |
1719 |
inq_ok: |
| 2027 |
mbuf[36] = 0; |
1720 |
mbuf[36] = 0; |
| 2028 |
printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]); |
1721 |
printk(KERN_INFO " ID: %2d %s\n", i, &mbuf[8]); |
| 2029 |
dev->id[0][i].devtype = mbuf[0]; |
1722 |
dev->id[i].devtypeu = mbuf[0]; |
| 2030 |
rmb = mbuf[1]; |
1723 |
rmb = mbuf[1]; |
| 2031 |
n = mbuf[7]; |
1724 |
n = mbuf[7]; |
| 2032 |
if ((mbuf[7] & 0x60) == 0) { |
1725 |
if ((mbuf[7] & 0x60) == 0) { |
| 2033 |
goto not_wide; |
1726 |
goto not_wide; |
| 2034 |
} |
1727 |
} |
| 2035 |
if ((i < 8) && ((dev->global_map[0] & 0x20) == 0)) { |
1728 |
if ((i < 8) && ((dev->global_map & 0x20) == 0)) { |
| 2036 |
goto not_wide; |
1729 |
goto not_wide; |
| 2037 |
} |
1730 |
} |
| 2038 |
if (lvdmode == 0) { |
1731 |
if (lvdmode == 0) { |
| 2039 |
goto chg_wide; |
1732 |
goto chg_wide; |
| 2040 |
} |
1733 |
} |
| 2041 |
if (dev->sp[0][i] != 0x04) // force u2 |
1734 |
if (dev->sp[i] != 0x04) // force u2 |
| 2042 |
{ |
1735 |
{ |
| 2043 |
goto chg_wide; |
1736 |
goto chg_wide; |
| 2044 |
} |
1737 |
} |
|
Lines 2055-2061
Link Here
|
| 2055 |
tmport += 0x06; |
1748 |
tmport += 0x06; |
| 2056 |
outb(0, tmport); |
1749 |
outb(0, tmport); |
| 2057 |
tmport += 0x02; |
1750 |
tmport += 0x02; |
| 2058 |
outb(dev->id[0][i].devsp, tmport++); |
1751 |
outb(dev->id[i].devspu, tmport++); |
| 2059 |
outb(0, tmport++); |
1752 |
outb(0, tmport++); |
| 2060 |
outb(satn[6], tmport++); |
1753 |
outb(satn[6], tmport++); |
| 2061 |
outb(satn[7], tmport++); |
1754 |
outb(satn[7], tmport++); |
|
Lines 2063-2079
Link Here
|
| 2063 |
outb(satn[8], tmport); |
1756 |
outb(satn[8], tmport); |
| 2064 |
tmport += 0x07; |
1757 |
tmport += 0x07; |
| 2065 |
|
1758 |
|
| 2066 |
while ((inb(tmport) & 0x80) == 0x00) |
1759 |
while ((inb(tmport) & 0x80) == 0x00); |
| 2067 |
cpu_relax(); |
|
|
| 2068 |
|
| 2069 |
tmport -= 0x08; |
1760 |
tmport -= 0x08; |
| 2070 |
|
1761 |
if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { |
| 2071 |
if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) |
|
|
| 2072 |
continue; |
1762 |
continue; |
| 2073 |
|
1763 |
} |
| 2074 |
while (inb(tmport) != 0x8e) |
1764 |
while (inb(tmport) != 0x8e); |
| 2075 |
cpu_relax(); |
|
|
| 2076 |
|
| 2077 |
try_u3: |
1765 |
try_u3: |
| 2078 |
j = 0; |
1766 |
j = 0; |
| 2079 |
tmport = wkport + 0x54; |
1767 |
tmport = wkport + 0x54; |
|
Lines 2090-2099
Link Here
|
| 2090 |
} |
1778 |
} |
| 2091 |
} |
1779 |
} |
| 2092 |
tmport -= 0x08; |
1780 |
tmport -= 0x08; |
| 2093 |
|
1781 |
while ((inb(tmport) & 0x80) == 0x00); |
| 2094 |
while ((inb(tmport) & 0x80) == 0x00) |
|
|
| 2095 |
cpu_relax(); |
| 2096 |
|
| 2097 |
j = inb(tmport) & 0x0f; |
1782 |
j = inb(tmport) & 0x0f; |
| 2098 |
if (j == 0x0f) { |
1783 |
if (j == 0x0f) { |
| 2099 |
goto u3p_in; |
1784 |
goto u3p_in; |
|
Lines 2166-2175
Link Here
|
| 2166 |
tmport += 0x04; |
1851 |
tmport += 0x04; |
| 2167 |
outb(0x08, tmport); |
1852 |
outb(0x08, tmport); |
| 2168 |
tmport += 0x07; |
1853 |
tmport += 0x07; |
| 2169 |
|
1854 |
while ((inb(tmport) & 0x80) == 0x00); |
| 2170 |
while ((inb(tmport) & 0x80) == 0x00) |
|
|
| 2171 |
cpu_relax(); |
| 2172 |
|
| 2173 |
tmport -= 0x08; |
1855 |
tmport -= 0x08; |
| 2174 |
j = inb(tmport); |
1856 |
j = inb(tmport); |
| 2175 |
if (j != 0x16) { |
1857 |
if (j != 0x16) { |
|
Lines 2190-2197
Link Here
|
| 2190 |
if (mbuf[3] == 0x09) { |
1872 |
if (mbuf[3] == 0x09) { |
| 2191 |
m = 1; |
1873 |
m = 1; |
| 2192 |
m = m << i; |
1874 |
m = m << i; |
| 2193 |
dev->wide_id[0] |= m; |
1875 |
dev->wide_idu |= m; |
| 2194 |
dev->id[0][i].devsp = 0xce; |
1876 |
dev->id[i].devspu = 0xce; |
| 2195 |
continue; |
1877 |
continue; |
| 2196 |
} |
1878 |
} |
| 2197 |
chg_wide: |
1879 |
chg_wide: |
|
Lines 2207-2213
Link Here
|
| 2207 |
tmport += 0x06; |
1889 |
tmport += 0x06; |
| 2208 |
outb(0, tmport); |
1890 |
outb(0, tmport); |
| 2209 |
tmport += 0x02; |
1891 |
tmport += 0x02; |
| 2210 |
outb(dev->id[0][i].devsp, tmport++); |
1892 |
outb(dev->id[i].devspu, tmport++); |
| 2211 |
outb(0, tmport++); |
1893 |
outb(0, tmport++); |
| 2212 |
outb(satn[6], tmport++); |
1894 |
outb(satn[6], tmport++); |
| 2213 |
outb(satn[7], tmport++); |
1895 |
outb(satn[7], tmport++); |
|
Lines 2215-2230
Link Here
|
| 2215 |
outb(satn[8], tmport); |
1897 |
outb(satn[8], tmport); |
| 2216 |
tmport += 0x07; |
1898 |
tmport += 0x07; |
| 2217 |
|
1899 |
|
| 2218 |
while ((inb(tmport) & 0x80) == 0x00) |
1900 |
while ((inb(tmport) & 0x80) == 0x00); |
| 2219 |
cpu_relax(); |
|
|
| 2220 |
|
| 2221 |
tmport -= 0x08; |
1901 |
tmport -= 0x08; |
| 2222 |
if (inb(tmport) != 0x11 && inb(tmport) != 0x8e) |
1902 |
if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { |
| 2223 |
continue; |
1903 |
continue; |
| 2224 |
|
1904 |
} |
| 2225 |
while (inb(tmport) != 0x8e) |
1905 |
while (inb(tmport) != 0x8e); |
| 2226 |
cpu_relax(); |
|
|
| 2227 |
|
| 2228 |
try_wide: |
1906 |
try_wide: |
| 2229 |
j = 0; |
1907 |
j = 0; |
| 2230 |
tmport = wkport + 0x54; |
1908 |
tmport = wkport + 0x54; |
|
Lines 2241-2249
Link Here
|
| 2241 |
} |
1919 |
} |
| 2242 |
} |
1920 |
} |
| 2243 |
tmport -= 0x08; |
1921 |
tmport -= 0x08; |
| 2244 |
while ((inb(tmport) & 0x80) == 0x00) |
1922 |
while ((inb(tmport) & 0x80) == 0x00); |
| 2245 |
cpu_relax(); |
|
|
| 2246 |
|
| 2247 |
j = inb(tmport) & 0x0f; |
1923 |
j = inb(tmport) & 0x0f; |
| 2248 |
if (j == 0x0f) { |
1924 |
if (j == 0x0f) { |
| 2249 |
goto widep_in; |
1925 |
goto widep_in; |
|
Lines 2316-2325
Link Here
|
| 2316 |
tmport += 0x04; |
1992 |
tmport += 0x04; |
| 2317 |
outb(0x08, tmport); |
1993 |
outb(0x08, tmport); |
| 2318 |
tmport += 0x07; |
1994 |
tmport += 0x07; |
| 2319 |
|
1995 |
while ((inb(tmport) & 0x80) == 0x00); |
| 2320 |
while ((inb(tmport) & 0x80) == 0x00) |
|
|
| 2321 |
cpu_relax(); |
| 2322 |
|
| 2323 |
tmport -= 0x08; |
1996 |
tmport -= 0x08; |
| 2324 |
j = inb(tmport); |
1997 |
j = inb(tmport); |
| 2325 |
if (j != 0x16) { |
1998 |
if (j != 0x16) { |
|
Lines 2342-2370
Link Here
|
| 2342 |
} |
2015 |
} |
| 2343 |
m = 1; |
2016 |
m = 1; |
| 2344 |
m = m << i; |
2017 |
m = m << i; |
| 2345 |
dev->wide_id[0] |= m; |
2018 |
dev->wide_idu |= m; |
| 2346 |
not_wide: |
2019 |
not_wide: |
| 2347 |
if ((dev->id[0][i].devtype == 0x00) || (dev->id[0][i].devtype == 0x07) || ((dev->id[0][i].devtype == 0x05) && ((n & 0x10) != 0))) { |
2020 |
if ((dev->id[i].devtypeu == 0x00) || (dev->id[i].devtypeu == 0x07) || ((dev->id[i].devtypeu == 0x05) && ((n & 0x10) != 0))) { |
| 2348 |
m = 1; |
2021 |
m = 1; |
| 2349 |
m = m << i; |
2022 |
m = m << i; |
| 2350 |
if ((dev->async[0] & m) != 0) { |
2023 |
if ((dev->async & m) != 0) { |
| 2351 |
goto set_sync; |
2024 |
goto set_sync; |
| 2352 |
} |
2025 |
} |
| 2353 |
} |
2026 |
} |
| 2354 |
continue; |
2027 |
continue; |
| 2355 |
set_sync: |
2028 |
set_sync: |
| 2356 |
if (dev->sp[0][i] == 0x02) { |
2029 |
if (dev->sp[i] == 0x02) { |
| 2357 |
synu[4] = 0x0c; |
2030 |
synu[4] = 0x0c; |
| 2358 |
synuw[4] = 0x0c; |
2031 |
synuw[4] = 0x0c; |
| 2359 |
} else { |
2032 |
} else { |
| 2360 |
if (dev->sp[0][i] >= 0x03) { |
2033 |
if (dev->sp[i] >= 0x03) { |
| 2361 |
synu[4] = 0x0a; |
2034 |
synu[4] = 0x0a; |
| 2362 |
synuw[4] = 0x0a; |
2035 |
synuw[4] = 0x0a; |
| 2363 |
} |
2036 |
} |
| 2364 |
} |
2037 |
} |
| 2365 |
tmport = wkport + 0x5b; |
2038 |
tmport = wkport + 0x5b; |
| 2366 |
j = 0; |
2039 |
j = 0; |
| 2367 |
if ((m & dev->wide_id[0]) != 0) { |
2040 |
if ((m & dev->wide_idu) != 0) { |
| 2368 |
j |= 0x01; |
2041 |
j |= 0x01; |
| 2369 |
} |
2042 |
} |
| 2370 |
outb(j, tmport); |
2043 |
outb(j, tmport); |
|
Lines 2378-2384
Link Here
|
| 2378 |
tmport += 0x06; |
2051 |
tmport += 0x06; |
| 2379 |
outb(0, tmport); |
2052 |
outb(0, tmport); |
| 2380 |
tmport += 0x02; |
2053 |
tmport += 0x02; |
| 2381 |
outb(dev->id[0][i].devsp, tmport++); |
2054 |
outb(dev->id[i].devspu, tmport++); |
| 2382 |
outb(0, tmport++); |
2055 |
outb(0, tmport++); |
| 2383 |
outb(satn[6], tmport++); |
2056 |
outb(satn[6], tmport++); |
| 2384 |
outb(satn[7], tmport++); |
2057 |
outb(satn[7], tmport++); |
|
Lines 2386-2401
Link Here
|
| 2386 |
outb(satn[8], tmport); |
2059 |
outb(satn[8], tmport); |
| 2387 |
tmport += 0x07; |
2060 |
tmport += 0x07; |
| 2388 |
|
2061 |
|
| 2389 |
while ((inb(tmport) & 0x80) == 0x00) |
2062 |
while ((inb(tmport) & 0x80) == 0x00); |
| 2390 |
cpu_relax(); |
|
|
| 2391 |
|
| 2392 |
tmport -= 0x08; |
2063 |
tmport -= 0x08; |
| 2393 |
if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { |
2064 |
if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { |
| 2394 |
continue; |
2065 |
continue; |
| 2395 |
} |
2066 |
} |
| 2396 |
while (inb(tmport) != 0x8e) |
2067 |
while (inb(tmport) != 0x8e); |
| 2397 |
cpu_relax(); |
|
|
| 2398 |
|
| 2399 |
try_sync: |
2068 |
try_sync: |
| 2400 |
j = 0; |
2069 |
j = 0; |
| 2401 |
tmport = wkport + 0x54; |
2070 |
tmport = wkport + 0x54; |
|
Lines 2407-2420
Link Here
|
| 2407 |
while ((inb(tmport) & 0x80) == 0) { |
2076 |
while ((inb(tmport) & 0x80) == 0) { |
| 2408 |
if ((inb(tmport) & 0x01) != 0) { |
2077 |
if ((inb(tmport) & 0x01) != 0) { |
| 2409 |
tmport -= 0x06; |
2078 |
tmport -= 0x06; |
| 2410 |
if ((m & dev->wide_id[0]) != 0) { |
2079 |
if ((m & dev->wide_idu) != 0) { |
| 2411 |
if ((m & dev->ultra_map[0]) != 0) { |
2080 |
if ((m & dev->ultra_map) != 0) { |
| 2412 |
outb(synuw[j++], tmport); |
2081 |
outb(synuw[j++], tmport); |
| 2413 |
} else { |
2082 |
} else { |
| 2414 |
outb(synw[j++], tmport); |
2083 |
outb(synw[j++], tmport); |
| 2415 |
} |
2084 |
} |
| 2416 |
} else { |
2085 |
} else { |
| 2417 |
if ((m & dev->ultra_map[0]) != 0) { |
2086 |
if ((m & dev->ultra_map) != 0) { |
| 2418 |
outb(synu[j++], tmport); |
2087 |
outb(synu[j++], tmport); |
| 2419 |
} else { |
2088 |
} else { |
| 2420 |
outb(synn[j++], tmport); |
2089 |
outb(synn[j++], tmport); |
|
Lines 2424-2433
Link Here
|
| 2424 |
} |
2093 |
} |
| 2425 |
} |
2094 |
} |
| 2426 |
tmport -= 0x08; |
2095 |
tmport -= 0x08; |
| 2427 |
|
2096 |
while ((inb(tmport) & 0x80) == 0x00); |
| 2428 |
while ((inb(tmport) & 0x80) == 0x00) |
|
|
| 2429 |
cpu_relax(); |
| 2430 |
|
| 2431 |
j = inb(tmport) & 0x0f; |
2097 |
j = inb(tmport) & 0x0f; |
| 2432 |
if (j == 0x0f) { |
2098 |
if (j == 0x0f) { |
| 2433 |
goto phase_ins; |
2099 |
goto phase_ins; |
|
Lines 2485-2494
Link Here
|
| 2485 |
goto phase_ins1; |
2151 |
goto phase_ins1; |
| 2486 |
} |
2152 |
} |
| 2487 |
tmport -= 0x08; |
2153 |
tmport -= 0x08; |
| 2488 |
|
2154 |
while ((inb(tmport) & 0x80) == 0x00); |
| 2489 |
while ((inb(tmport) & 0x80) == 0x00) |
|
|
| 2490 |
cpu_relax(); |
| 2491 |
|
| 2492 |
j = inb(tmport); |
2155 |
j = inb(tmport); |
| 2493 |
if (j == 0x85) { |
2156 |
if (j == 0x85) { |
| 2494 |
goto tar_dcons; |
2157 |
goto tar_dcons; |
|
Lines 2513-2522
Link Here
|
| 2513 |
tmport += 0x04; |
2176 |
tmport += 0x04; |
| 2514 |
outb(0x08, tmport); |
2177 |
outb(0x08, tmport); |
| 2515 |
tmport += 0x07; |
2178 |
tmport += 0x07; |
| 2516 |
|
2179 |
while ((inb(tmport) & 0x80) == 0x00); |
| 2517 |
while ((inb(tmport) & 0x80) == 0x00) |
|
|
| 2518 |
cpu_relax(); |
| 2519 |
|
| 2520 |
tmport -= 0x08; |
2180 |
tmport -= 0x08; |
| 2521 |
j = inb(tmport); |
2181 |
j = inb(tmport); |
| 2522 |
if (j != 0x16) { |
2182 |
if (j != 0x16) { |
|
Lines 2537-2543
Link Here
|
| 2537 |
if (mbuf[4] > 0x0e) { |
2197 |
if (mbuf[4] > 0x0e) { |
| 2538 |
mbuf[4] = 0x0e; |
2198 |
mbuf[4] = 0x0e; |
| 2539 |
} |
2199 |
} |
| 2540 |
dev->id[0][i].devsp = mbuf[4]; |
2200 |
dev->id[i].devspu = mbuf[4]; |
| 2541 |
if (mbuf[3] < 0x0c) { |
2201 |
if (mbuf[3] < 0x0c) { |
| 2542 |
j = 0xb0; |
2202 |
j = 0xb0; |
| 2543 |
goto set_syn_ok; |
2203 |
goto set_syn_ok; |
|
Lines 2560-3096
Link Here
|
| 2560 |
} |
2220 |
} |
| 2561 |
j = 0x60; |
2221 |
j = 0x60; |
| 2562 |
set_syn_ok: |
2222 |
set_syn_ok: |
| 2563 |
dev->id[0][i].devsp = (dev->id[0][i].devsp & 0x0f) | j; |
2223 |
dev->id[i].devspu = (dev->id[i].devspu & 0x0f) | j; |
| 2564 |
} |
2224 |
} |
| 2565 |
} |
2225 |
} |
| 2566 |
|
2226 |
|
| 2567 |
static void atp870u_free_tables(struct Scsi_Host *host) |
2227 |
static void atp870u_free_tables(struct Scsi_Host *host) |
| 2568 |
{ |
2228 |
{ |
| 2569 |
struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata; |
2229 |
struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata; |
| 2570 |
int j, k; |
2230 |
int k; |
| 2571 |
for (j=0; j < 2; j++) { |
2231 |
|
| 2572 |
for (k = 0; k < 16; k++) { |
2232 |
for (k = 0; k < 16; k++) { |
| 2573 |
if (!atp_dev->id[j][k].prd_table) |
2233 |
if (!atp_dev->id[k].prd_tableu) |
| 2574 |
continue; |
2234 |
continue; |
| 2575 |
pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[j][k].prd_table, atp_dev->id[j][k].prdaddr); |
2235 |
pci_free_consistent(atp_dev->pdev, 1024, atp_dev->id[k].prd_tableu, |
| 2576 |
atp_dev->id[j][k].prd_table = NULL; |
2236 |
atp_dev->id[k].prd_phys); |
| 2577 |
} |
2237 |
atp_dev->id[k].prd_tableu = NULL; |
| 2578 |
} |
2238 |
} |
| 2579 |
} |
2239 |
} |
| 2580 |
|
2240 |
|
| 2581 |
static int atp870u_init_tables(struct Scsi_Host *host) |
2241 |
static int atp870u_init_tables(struct Scsi_Host *host) |
| 2582 |
{ |
2242 |
{ |
| 2583 |
struct atp_unit *atp_dev = (struct atp_unit *)&host->hostdata; |
2243 |
struct atp_unit *dev = (struct atp_unit *)&host->hostdata; |
| 2584 |
int c,k; |
2244 |
int k, i; |
| 2585 |
for(c=0;c < 2;c++) { |
2245 |
|
| 2586 |
for(k=0;k<16;k++) { |
2246 |
for (i = k = 0; k < 16; k++) { |
| 2587 |
atp_dev->id[c][k].prd_table = pci_alloc_consistent(atp_dev->pdev, 1024, &(atp_dev->id[c][k].prdaddr)); |
2247 |
dev->id[k].prd_tableu = pci_alloc_consistent(dev->pdev, 1024, &dev->id[k].prd_phys); |
| 2588 |
if (!atp_dev->id[c][k].prd_table) { |
2248 |
if (!dev->id[k].prd_tableu) { |
| 2589 |
printk("atp870u_init_tables fail\n"); |
2249 |
atp870u_free_tables(host); |
| 2590 |
atp870u_free_tables(host); |
2250 |
return -ENOMEM; |
| 2591 |
return -ENOMEM; |
2251 |
} |
| 2592 |
} |
2252 |
dev->id[k].devspu = 0x20; |
| 2593 |
atp_dev->id[c][k].devsp=0x20; |
2253 |
dev->id[k].devtypeu = 0; |
| 2594 |
atp_dev->id[c][k].devtype = 0x7f; |
2254 |
dev->id[k].curr_req = NULL; |
| 2595 |
atp_dev->id[c][k].curr_req = NULL; |
2255 |
} |
| 2596 |
} |
2256 |
dev->active_idu = 0; |
| 2597 |
|
2257 |
dev->wide_idu = 0; |
| 2598 |
atp_dev->active_id[c] = 0; |
2258 |
dev->host_idu = 0x07; |
| 2599 |
atp_dev->wide_id[c] = 0; |
2259 |
dev->quhdu = 0; |
| 2600 |
atp_dev->host_id[c] = 0x07; |
2260 |
dev->quendu = 0; |
| 2601 |
atp_dev->quhd[c] = 0; |
2261 |
dev->chip_veru = 0; |
| 2602 |
atp_dev->quend[c] = 0; |
2262 |
dev->last_cmd = 0xff; |
| 2603 |
atp_dev->last_cmd[c] = 0xff; |
2263 |
dev->in_snd = 0; |
| 2604 |
atp_dev->in_snd[c] = 0; |
2264 |
dev->in_int = 0; |
| 2605 |
atp_dev->in_int[c] = 0; |
2265 |
for (k = 0; k < qcnt; k++) { |
| 2606 |
|
2266 |
dev->querequ[k] = NULL; |
| 2607 |
for (k = 0; k < qcnt; k++) { |
2267 |
} |
| 2608 |
atp_dev->quereq[c][k] = NULL; |
2268 |
for (k = 0; k < 16; k++) { |
| 2609 |
} |
2269 |
dev->id[k].curr_req = NULL; |
| 2610 |
for (k = 0; k < 16; k++) { |
2270 |
dev->sp[k] = 0x04; |
| 2611 |
atp_dev->id[c][k].curr_req = NULL; |
|
|
| 2612 |
atp_dev->sp[c][k] = 0x04; |
| 2613 |
} |
| 2614 |
} |
2271 |
} |
| 2615 |
return 0; |
2272 |
return 0; |
| 2616 |
} |
2273 |
} |
| 2617 |
|
2274 |
|
| 2618 |
/* return non-zero on detection */ |
2275 |
/* return non-zero on detection */ |
| 2619 |
static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) |
2276 |
static int atp870u_probe(struct pci_dev *dev, const struct pci_device_id *ent) |
| 2620 |
{ |
2277 |
{ |
| 2621 |
unsigned char k, m, c; |
2278 |
unsigned char k, m; |
| 2622 |
unsigned long flags; |
2279 |
unsigned long flags; |
| 2623 |
unsigned int base_io, tmport, error,n; |
2280 |
unsigned int base_io, error, tmport; |
| 2624 |
unsigned char host_id; |
2281 |
unsigned char host_id; |
| 2625 |
struct Scsi_Host *shpnt = NULL; |
2282 |
unsigned short n; |
|
|
2283 |
struct Scsi_Host *shpnt; |
| 2626 |
struct atp_unit atp_dev, *p; |
2284 |
struct atp_unit atp_dev, *p; |
| 2627 |
unsigned char setupdata[2][16]; |
2285 |
static int count; |
| 2628 |
int count = 0; |
|
|
| 2629 |
|
| 2630 |
if (pci_enable_device(pdev)) |
| 2631 |
return -EIO; |
| 2632 |
|
2286 |
|
| 2633 |
if (!pci_set_dma_mask(pdev, 0xFFFFFFFFUL)) { |
2287 |
if (pci_enable_device(dev)) |
| 2634 |
printk(KERN_INFO "atp870u: use 32bit DMA mask.\n"); |
2288 |
return -EIO; |
| 2635 |
} else { |
|
|
| 2636 |
printk(KERN_ERR "atp870u: DMA mask required but not available.\n"); |
| 2637 |
return -EIO; |
| 2638 |
} |
| 2639 |
|
2289 |
|
|
|
2290 |
if (pci_set_dma_mask(dev, 0xFFFFFFFFUL)) { |
| 2291 |
printk(KERN_ERR "atp870u: 32bit DMA mask required but not available.\n"); |
| 2292 |
return -EIO; |
| 2293 |
} |
| 2294 |
|
| 2640 |
memset(&atp_dev, 0, sizeof atp_dev); |
2295 |
memset(&atp_dev, 0, sizeof atp_dev); |
|
|
2296 |
|
| 2641 |
/* |
2297 |
/* |
| 2642 |
* It's probably easier to weed out some revisions like |
2298 |
* It's probably easier to weed out some revisions like |
| 2643 |
* this than via the PCI device table |
2299 |
* this than via the PCI device table |
| 2644 |
*/ |
2300 |
*/ |
| 2645 |
if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) { |
2301 |
if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) { |
| 2646 |
error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver); |
2302 |
error = pci_read_config_byte(dev, PCI_CLASS_REVISION, &atp_dev.chip_veru); |
| 2647 |
if (atp_dev.chip_ver < 2) |
2303 |
if (atp_dev.chip_veru < 2) |
| 2648 |
return -EIO; |
2304 |
return -EIO; |
| 2649 |
} |
2305 |
} |
| 2650 |
|
2306 |
|
| 2651 |
switch (ent->device) { |
2307 |
switch (ent->device) { |
|
|
2308 |
case 0x8081: |
| 2652 |
case PCI_DEVICE_ID_ARTOP_AEC7612UW: |
2309 |
case PCI_DEVICE_ID_ARTOP_AEC7612UW: |
| 2653 |
case PCI_DEVICE_ID_ARTOP_AEC7612SUW: |
2310 |
case PCI_DEVICE_ID_ARTOP_AEC7612SUW: |
| 2654 |
case ATP880_DEVID1: |
2311 |
atp_dev.chip_veru = 0x04; |
| 2655 |
case ATP880_DEVID2: |
|
|
| 2656 |
case ATP885_DEVID: |
| 2657 |
atp_dev.chip_ver = 0x04; |
| 2658 |
default: |
2312 |
default: |
| 2659 |
break; |
2313 |
break; |
| 2660 |
} |
2314 |
} |
| 2661 |
base_io = pci_resource_start(pdev, 0); |
|
|
| 2662 |
base_io &= 0xfffffff8; |
| 2663 |
|
| 2664 |
if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { |
| 2665 |
error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver); |
| 2666 |
pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 |
| 2667 |
|
| 2668 |
host_id = inb(base_io + 0x39); |
| 2669 |
host_id >>= 0x04; |
| 2670 |
|
2315 |
|
| 2671 |
printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d" |
2316 |
base_io = pci_resource_start(dev, 0); |
| 2672 |
" IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); |
|
|
| 2673 |
atp_dev.ioport[0] = base_io + 0x40; |
| 2674 |
atp_dev.pciport[0] = base_io + 0x28; |
| 2675 |
atp_dev.dev_id = ent->device; |
| 2676 |
atp_dev.host_id[0] = host_id; |
| 2677 |
|
2317 |
|
|
|
2318 |
if (ent->device != 0x8081) { |
| 2319 |
error = pci_read_config_byte(dev, 0x49, &host_id); |
| 2320 |
base_io &= 0xfffffff8; |
| 2321 |
|
| 2322 |
printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-3 Host Adapter: %d " |
| 2323 |
"IO:%x, IRQ:%d.\n", count, base_io, dev->irq); |
| 2324 |
|
| 2325 |
atp_dev.unit = count; |
| 2326 |
atp_dev.ioport = base_io; |
| 2327 |
atp_dev.pciport = base_io + 0x20; |
| 2328 |
atp_dev.deviceid = ent->device; |
| 2329 |
host_id &= 0x07; |
| 2330 |
atp_dev.host_idu = host_id; |
| 2678 |
tmport = base_io + 0x22; |
2331 |
tmport = base_io + 0x22; |
| 2679 |
atp_dev.scam_on = inb(tmport); |
2332 |
atp_dev.scam_on = inb(tmport); |
| 2680 |
tmport += 0x13; |
2333 |
tmport += 0x0b; |
| 2681 |
atp_dev.global_map[0] = inb(tmport); |
2334 |
atp_dev.global_map = inb(tmport++); |
| 2682 |
tmport += 0x07; |
2335 |
atp_dev.ultra_map = inw(tmport); |
| 2683 |
atp_dev.ultra_map[0] = inw(tmport); |
|
|
| 2684 |
|
2336 |
|
| 2685 |
n = 0x3f09; |
2337 |
if (atp_dev.ultra_map == 0) { |
| 2686 |
next_fblk_880: |
2338 |
atp_dev.scam_on = 0x00; |
| 2687 |
if (n >= 0x4000) |
2339 |
atp_dev.global_map = 0x20; |
| 2688 |
goto flash_ok_880; |
2340 |
atp_dev.ultra_map = 0xffff; |
|
|
2341 |
} |
| 2689 |
|
2342 |
|
| 2690 |
m = 0; |
2343 |
shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); |
| 2691 |
outw(n, base_io + 0x34); |
2344 |
if (!shpnt) |
| 2692 |
n += 0x0002; |
2345 |
return -ENOMEM; |
| 2693 |
if (inb(base_io + 0x30) == 0xff) |
|
|
| 2694 |
goto flash_ok_880; |
| 2695 |
|
| 2696 |
atp_dev.sp[0][m++] = inb(base_io + 0x30); |
| 2697 |
atp_dev.sp[0][m++] = inb(base_io + 0x31); |
| 2698 |
atp_dev.sp[0][m++] = inb(base_io + 0x32); |
| 2699 |
atp_dev.sp[0][m++] = inb(base_io + 0x33); |
| 2700 |
outw(n, base_io + 0x34); |
| 2701 |
n += 0x0002; |
| 2702 |
atp_dev.sp[0][m++] = inb(base_io + 0x30); |
| 2703 |
atp_dev.sp[0][m++] = inb(base_io + 0x31); |
| 2704 |
atp_dev.sp[0][m++] = inb(base_io + 0x32); |
| 2705 |
atp_dev.sp[0][m++] = inb(base_io + 0x33); |
| 2706 |
outw(n, base_io + 0x34); |
| 2707 |
n += 0x0002; |
| 2708 |
atp_dev.sp[0][m++] = inb(base_io + 0x30); |
| 2709 |
atp_dev.sp[0][m++] = inb(base_io + 0x31); |
| 2710 |
atp_dev.sp[0][m++] = inb(base_io + 0x32); |
| 2711 |
atp_dev.sp[0][m++] = inb(base_io + 0x33); |
| 2712 |
outw(n, base_io + 0x34); |
| 2713 |
n += 0x0002; |
| 2714 |
atp_dev.sp[0][m++] = inb(base_io + 0x30); |
| 2715 |
atp_dev.sp[0][m++] = inb(base_io + 0x31); |
| 2716 |
atp_dev.sp[0][m++] = inb(base_io + 0x32); |
| 2717 |
atp_dev.sp[0][m++] = inb(base_io + 0x33); |
| 2718 |
n += 0x0018; |
| 2719 |
goto next_fblk_880; |
| 2720 |
flash_ok_880: |
| 2721 |
outw(0, base_io + 0x34); |
| 2722 |
atp_dev.ultra_map[0] = 0; |
| 2723 |
atp_dev.async[0] = 0; |
| 2724 |
for (k = 0; k < 16; k++) { |
| 2725 |
n = 1; |
| 2726 |
n = n << k; |
| 2727 |
if (atp_dev.sp[0][k] > 1) { |
| 2728 |
atp_dev.ultra_map[0] |= n; |
| 2729 |
} else { |
| 2730 |
if (atp_dev.sp[0][k] == 0) |
| 2731 |
atp_dev.async[0] |= n; |
| 2732 |
} |
| 2733 |
} |
| 2734 |
atp_dev.async[0] = ~(atp_dev.async[0]); |
| 2735 |
outb(atp_dev.global_map[0], base_io + 0x35); |
| 2736 |
|
| 2737 |
shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); |
| 2738 |
if (!shpnt) |
| 2739 |
return -ENOMEM; |
| 2740 |
|
2346 |
|
| 2741 |
p = (struct atp_unit *)&shpnt->hostdata; |
2347 |
p = (struct atp_unit *)&shpnt->hostdata; |
| 2742 |
|
2348 |
|
| 2743 |
atp_dev.host = shpnt; |
2349 |
atp_dev.host = shpnt; |
| 2744 |
atp_dev.pdev = pdev; |
2350 |
atp_dev.pdev = dev; |
| 2745 |
pci_set_drvdata(pdev, p); |
2351 |
pci_set_drvdata(dev, p); |
| 2746 |
memcpy(p, &atp_dev, sizeof atp_dev); |
2352 |
memcpy(p, &atp_dev, sizeof atp_dev); |
| 2747 |
if (atp870u_init_tables(shpnt) < 0) { |
2353 |
if (atp870u_init_tables(shpnt) < 0) |
| 2748 |
printk(KERN_ERR "Unable to allocate tables for Acard controller\n"); |
|
|
| 2749 |
goto unregister; |
2354 |
goto unregister; |
| 2750 |
} |
|
|
| 2751 |
|
2355 |
|
| 2752 |
if (request_irq(pdev->irq, atp870u_intr_handle, SA_SHIRQ, "atp880i", shpnt)) { |
2356 |
if (request_irq(dev->irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", shpnt)) { |
| 2753 |
printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq); |
2357 |
printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", dev->irq); |
| 2754 |
goto free_tables; |
2358 |
goto free_tables; |
| 2755 |
} |
2359 |
} |
| 2756 |
|
2360 |
|
| 2757 |
spin_lock_irqsave(shpnt->host_lock, flags); |
2361 |
spin_lock_irqsave(shpnt->host_lock, flags); |
| 2758 |
tmport = base_io + 0x38; |
2362 |
if (atp_dev.chip_veru > 0x07) { /* check if atp876 chip then enable terminator */ |
| 2759 |
k = inb(tmport) & 0x80; |
2363 |
tmport = base_io + 0x3e; |
|
|
2364 |
outb(0x00, tmport); |
| 2365 |
} |
| 2366 |
|
| 2367 |
tmport = base_io + 0x3a; |
| 2368 |
k = (inb(tmport) & 0xf3) | 0x10; |
| 2760 |
outb(k, tmport); |
2369 |
outb(k, tmport); |
| 2761 |
tmport += 0x03; |
2370 |
outb((k & 0xdf), tmport); |
| 2762 |
outb(0x20, tmport); |
|
|
| 2763 |
mdelay(32); |
2371 |
mdelay(32); |
| 2764 |
outb(0, tmport); |
2372 |
outb(k, tmport); |
| 2765 |
mdelay(32); |
2373 |
mdelay(32); |
| 2766 |
tmport = base_io + 0x5b; |
2374 |
tmport = base_io; |
| 2767 |
inb(tmport); |
|
|
| 2768 |
tmport -= 0x04; |
| 2769 |
inb(tmport); |
| 2770 |
tmport = base_io + 0x40; |
| 2771 |
outb((host_id | 0x08), tmport); |
2375 |
outb((host_id | 0x08), tmport); |
| 2772 |
tmport += 0x18; |
2376 |
tmport += 0x18; |
| 2773 |
outb(0, tmport); |
2377 |
outb(0, tmport); |
| 2774 |
tmport += 0x07; |
2378 |
tmport += 0x07; |
| 2775 |
while ((inb(tmport) & 0x80) == 0) |
2379 |
while ((inb(tmport) & 0x80) == 0) |
| 2776 |
mdelay(1); |
2380 |
mdelay(1); |
| 2777 |
tmport -= 0x08; |
|
|
| 2778 |
inb(tmport); |
| 2779 |
tmport = base_io + 0x41; |
| 2780 |
outb(8, tmport++); |
| 2781 |
outb(0x7f, tmport); |
| 2782 |
tmport = base_io + 0x51; |
| 2783 |
outb(0x20, tmport); |
| 2784 |
|
| 2785 |
tscam(shpnt); |
| 2786 |
is880(p, base_io); |
| 2787 |
tmport = base_io + 0x38; |
| 2788 |
outb(0xb0, tmport); |
| 2789 |
shpnt->max_id = 16; |
| 2790 |
shpnt->this_id = host_id; |
| 2791 |
shpnt->unique_id = base_io; |
| 2792 |
shpnt->io_port = base_io; |
| 2793 |
shpnt->n_io_port = 0x60; /* Number of bytes of I/O space used */ |
| 2794 |
shpnt->irq = pdev->irq; |
| 2795 |
} else if (ent->device == ATP885_DEVID) { |
| 2796 |
printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%x, IRQ:%d.\n" |
| 2797 |
, base_io, pdev->irq); |
| 2798 |
|
| 2799 |
atp_dev.pdev = pdev; |
| 2800 |
atp_dev.dev_id = ent->device; |
| 2801 |
atp_dev.baseport = base_io; |
| 2802 |
atp_dev.ioport[0] = base_io + 0x80; |
| 2803 |
atp_dev.ioport[1] = base_io + 0xc0; |
| 2804 |
atp_dev.pciport[0] = base_io + 0x40; |
| 2805 |
atp_dev.pciport[1] = base_io + 0x50; |
| 2806 |
|
| 2807 |
shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); |
| 2808 |
if (!shpnt) |
| 2809 |
return -ENOMEM; |
| 2810 |
|
| 2811 |
p = (struct atp_unit *)&shpnt->hostdata; |
| 2812 |
|
| 2813 |
atp_dev.host = shpnt; |
| 2814 |
atp_dev.pdev = pdev; |
| 2815 |
pci_set_drvdata(pdev, p); |
| 2816 |
memcpy(p, &atp_dev, sizeof(struct atp_unit)); |
| 2817 |
if (atp870u_init_tables(shpnt) < 0) |
| 2818 |
goto unregister; |
| 2819 |
|
| 2820 |
#ifdef ED_DBGP |
| 2821 |
printk("request_irq() shpnt %p hostdata %p\n", shpnt, p); |
| 2822 |
#endif |
| 2823 |
if (request_irq(pdev->irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", shpnt)) { |
| 2824 |
printk(KERN_ERR "Unable to allocate IRQ for Acard controller.\n"); |
| 2825 |
goto free_tables; |
| 2826 |
} |
| 2827 |
|
| 2828 |
spin_lock_irqsave(shpnt->host_lock, flags); |
| 2829 |
|
| 2830 |
c=inb(base_io + 0x29); |
| 2831 |
outb((c | 0x04),base_io + 0x29); |
| 2832 |
|
| 2833 |
n=0x1f80; |
| 2834 |
next_fblk_885: |
| 2835 |
if (n >= 0x2000) { |
| 2836 |
goto flash_ok_885; |
| 2837 |
} |
| 2838 |
outw(n,base_io + 0x3c); |
| 2839 |
if (inl(base_io + 0x38) == 0xffffffff) { |
| 2840 |
goto flash_ok_885; |
| 2841 |
} |
| 2842 |
for (m=0; m < 2; m++) { |
| 2843 |
p->global_map[m]= 0; |
| 2844 |
for (k=0; k < 4; k++) { |
| 2845 |
outw(n++,base_io + 0x3c); |
| 2846 |
((unsigned long *)&setupdata[m][0])[k]=inl(base_io + 0x38); |
| 2847 |
} |
| 2848 |
for (k=0; k < 4; k++) { |
| 2849 |
outw(n++,base_io + 0x3c); |
| 2850 |
((unsigned long *)&p->sp[m][0])[k]=inl(base_io + 0x38); |
| 2851 |
} |
| 2852 |
n += 8; |
| 2853 |
} |
| 2854 |
goto next_fblk_885; |
| 2855 |
flash_ok_885: |
| 2856 |
#ifdef ED_DBGP |
| 2857 |
printk( "Flash Read OK\n"); |
| 2858 |
#endif |
| 2859 |
c=inb(base_io + 0x29); |
| 2860 |
outb((c & 0xfb),base_io + 0x29); |
| 2861 |
for (c=0;c < 2;c++) { |
| 2862 |
p->ultra_map[c]=0; |
| 2863 |
p->async[c] = 0; |
| 2864 |
for (k=0; k < 16; k++) { |
| 2865 |
n=1; |
| 2866 |
n = n << k; |
| 2867 |
if (p->sp[c][k] > 1) { |
| 2868 |
p->ultra_map[c] |= n; |
| 2869 |
} else { |
| 2870 |
if (p->sp[c][k] == 0) { |
| 2871 |
p->async[c] |= n; |
| 2872 |
} |
| 2873 |
} |
| 2874 |
} |
| 2875 |
p->async[c] = ~(p->async[c]); |
| 2876 |
|
| 2877 |
if (p->global_map[c] == 0) { |
| 2878 |
k=setupdata[c][1]; |
| 2879 |
if ((k & 0x40) != 0) |
| 2880 |
p->global_map[c] |= 0x20; |
| 2881 |
k &= 0x07; |
| 2882 |
p->global_map[c] |= k; |
| 2883 |
if ((setupdata[c][2] & 0x04) != 0) |
| 2884 |
p->global_map[c] |= 0x08; |
| 2885 |
p->host_id[c] = setupdata[c][0] & 0x07; |
| 2886 |
} |
| 2887 |
} |
| 2888 |
|
| 2889 |
k = inb(base_io + 0x28) & 0x8f; |
| 2890 |
k |= 0x10; |
| 2891 |
outb(k, base_io + 0x28); |
| 2892 |
outb(0x80, base_io + 0x41); |
| 2893 |
outb(0x80, base_io + 0x51); |
| 2894 |
mdelay(100); |
| 2895 |
outb(0, base_io + 0x41); |
| 2896 |
outb(0, base_io + 0x51); |
| 2897 |
mdelay(1000); |
| 2898 |
inb(base_io + 0x9b); |
| 2899 |
inb(base_io + 0x97); |
| 2900 |
inb(base_io + 0xdb); |
| 2901 |
inb(base_io + 0xd7); |
| 2902 |
tmport = base_io + 0x80; |
| 2903 |
k=p->host_id[0]; |
| 2904 |
if (k > 7) |
| 2905 |
k = (k & 0x07) | 0x40; |
| 2906 |
k |= 0x08; |
| 2907 |
outb(k, tmport); |
| 2908 |
tmport += 0x18; |
| 2909 |
outb(0, tmport); |
| 2910 |
tmport += 0x07; |
| 2911 |
|
| 2912 |
while ((inb(tmport) & 0x80) == 0) |
| 2913 |
cpu_relax(); |
| 2914 |
|
| 2915 |
tmport -= 0x08; |
| 2916 |
inb(tmport); |
| 2917 |
tmport = base_io + 0x81; |
| 2918 |
outb(8, tmport++); |
| 2919 |
outb(0x7f, tmport); |
| 2920 |
tmport = base_io + 0x91; |
| 2921 |
outb(0x20, tmport); |
| 2922 |
|
| 2923 |
tmport = base_io + 0xc0; |
| 2924 |
k=p->host_id[1]; |
| 2925 |
if (k > 7) |
| 2926 |
k = (k & 0x07) | 0x40; |
| 2927 |
k |= 0x08; |
| 2928 |
outb(k, tmport); |
| 2929 |
tmport += 0x18; |
| 2930 |
outb(0, tmport); |
| 2931 |
tmport += 0x07; |
| 2932 |
|
| 2933 |
while ((inb(tmport) & 0x80) == 0) |
| 2934 |
cpu_relax(); |
| 2935 |
|
2381 |
|
| 2936 |
tmport -= 0x08; |
2382 |
tmport -= 0x08; |
| 2937 |
inb(tmport); |
2383 |
inb(tmport); |
| 2938 |
tmport = base_io + 0xc1; |
2384 |
tmport = base_io + 1; |
| 2939 |
outb(8, tmport++); |
2385 |
outb(8, tmport++); |
| 2940 |
outb(0x7f, tmport); |
2386 |
outb(0x7f, tmport); |
| 2941 |
tmport = base_io + 0xd1; |
2387 |
tmport = base_io + 0x11; |
| 2942 |
outb(0x20, tmport); |
2388 |
outb(0x20, tmport); |
| 2943 |
|
2389 |
|
| 2944 |
tscam_885(); |
2390 |
tscam(shpnt); |
| 2945 |
printk(KERN_INFO " Scanning Channel A SCSI Device ...\n"); |
2391 |
is870(shpnt, base_io); |
| 2946 |
is885(p, base_io + 0x80, 0); |
2392 |
tmport = base_io + 0x3a; |
| 2947 |
printk(KERN_INFO " Scanning Channel B SCSI Device ...\n"); |
2393 |
outb((inb(tmport) & 0xef), tmport); |
| 2948 |
is885(p, base_io + 0xc0, 1); |
2394 |
tmport++; |
| 2949 |
|
2395 |
outb((inb(tmport) | 0x20), tmport); |
| 2950 |
k = inb(base_io + 0x28) & 0xcf; |
|
|
| 2951 |
k |= 0xc0; |
| 2952 |
outb(k, base_io + 0x28); |
| 2953 |
k = inb(base_io + 0x1f) | 0x80; |
| 2954 |
outb(k, base_io + 0x1f); |
| 2955 |
k = inb(base_io + 0x29) | 0x01; |
| 2956 |
outb(k, base_io + 0x29); |
| 2957 |
#ifdef ED_DBGP |
| 2958 |
//printk("atp885: atp_host[0] 0x%p\n", atp_host[0]); |
| 2959 |
#endif |
| 2960 |
shpnt->max_id = 16; |
| 2961 |
shpnt->max_lun = (p->global_map[0] & 0x07) + 1; |
| 2962 |
shpnt->max_channel = 1; |
| 2963 |
shpnt->this_id = p->host_id[0]; |
| 2964 |
shpnt->unique_id = base_io; |
| 2965 |
shpnt->io_port = base_io; |
| 2966 |
shpnt->n_io_port = 0xff; /* Number of bytes of I/O space used */ |
| 2967 |
shpnt->irq = pdev->irq; |
| 2968 |
|
| 2969 |
} else { |
2396 |
} else { |
| 2970 |
error = pci_read_config_byte(pdev, 0x49, &host_id); |
2397 |
base_io &= 0xfffffff8; |
|
|
2398 |
host_id = inb(base_io + 0x39); |
| 2399 |
host_id >>= 0x04; |
| 2971 |
|
2400 |
|
| 2972 |
printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: %d " |
2401 |
printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d" |
| 2973 |
"IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); |
2402 |
" IO:%x, IRQ:%d.\n", count, base_io, dev->irq); |
|
|
2403 |
atp_dev.ioport = base_io + 0x40; |
| 2404 |
atp_dev.pciport = base_io + 0x28; |
| 2405 |
atp_dev.deviceid = ent->device; |
| 2406 |
atp_dev.host_idu = host_id; |
| 2974 |
|
2407 |
|
| 2975 |
atp_dev.ioport[0] = base_io; |
|
|
| 2976 |
atp_dev.pciport[0] = base_io + 0x20; |
| 2977 |
atp_dev.dev_id = ent->device; |
| 2978 |
host_id &= 0x07; |
| 2979 |
atp_dev.host_id[0] = host_id; |
| 2980 |
tmport = base_io + 0x22; |
2408 |
tmport = base_io + 0x22; |
| 2981 |
atp_dev.scam_on = inb(tmport); |
2409 |
atp_dev.scam_on = inb(tmport); |
| 2982 |
tmport += 0x0b; |
2410 |
tmport += 0x13; |
| 2983 |
atp_dev.global_map[0] = inb(tmport++); |
2411 |
atp_dev.global_map = inb(tmport); |
| 2984 |
atp_dev.ultra_map[0] = inw(tmport); |
2412 |
tmport += 0x07; |
|
|
2413 |
atp_dev.ultra_map = inw(tmport); |
| 2985 |
|
2414 |
|
| 2986 |
if (atp_dev.ultra_map[0] == 0) { |
2415 |
n = 0x3f09; |
| 2987 |
atp_dev.scam_on = 0x00; |
2416 |
next_fblk: |
| 2988 |
atp_dev.global_map[0] = 0x20; |
2417 |
if (n >= 0x4000) |
| 2989 |
atp_dev.ultra_map[0] = 0xffff; |
2418 |
goto flash_ok; |
| 2990 |
} |
2419 |
|
|
|
2420 |
m = 0; |
| 2421 |
outw(n, base_io + 0x34); |
| 2422 |
n += 0x0002; |
| 2423 |
if (inb(base_io + 0x30) == 0xff) |
| 2424 |
goto flash_ok; |
| 2991 |
|
2425 |
|
|
|
2426 |
atp_dev.sp[m++] = inb(base_io + 0x30); |
| 2427 |
atp_dev.sp[m++] = inb(base_io + 0x31); |
| 2428 |
atp_dev.sp[m++] = inb(base_io + 0x32); |
| 2429 |
atp_dev.sp[m++] = inb(base_io + 0x33); |
| 2430 |
outw(n, base_io + 0x34); |
| 2431 |
n += 0x0002; |
| 2432 |
atp_dev.sp[m++] = inb(base_io + 0x30); |
| 2433 |
atp_dev.sp[m++] = inb(base_io + 0x31); |
| 2434 |
atp_dev.sp[m++] = inb(base_io + 0x32); |
| 2435 |
atp_dev.sp[m++] = inb(base_io + 0x33); |
| 2436 |
outw(n, base_io + 0x34); |
| 2437 |
n += 0x0002; |
| 2438 |
atp_dev.sp[m++] = inb(base_io + 0x30); |
| 2439 |
atp_dev.sp[m++] = inb(base_io + 0x31); |
| 2440 |
atp_dev.sp[m++] = inb(base_io + 0x32); |
| 2441 |
atp_dev.sp[m++] = inb(base_io + 0x33); |
| 2442 |
outw(n, base_io + 0x34); |
| 2443 |
n += 0x0002; |
| 2444 |
atp_dev.sp[m++] = inb(base_io + 0x30); |
| 2445 |
atp_dev.sp[m++] = inb(base_io + 0x31); |
| 2446 |
atp_dev.sp[m++] = inb(base_io + 0x32); |
| 2447 |
atp_dev.sp[m++] = inb(base_io + 0x33); |
| 2448 |
n += 0x0018; |
| 2449 |
goto next_fblk; |
| 2450 |
flash_ok: |
| 2451 |
outw(0, base_io + 0x34); |
| 2452 |
atp_dev.ultra_map = 0; |
| 2453 |
atp_dev.async = 0; |
| 2454 |
for (k = 0; k < 16; k++) { |
| 2455 |
n = 1; |
| 2456 |
n = n << k; |
| 2457 |
if (atp_dev.sp[k] > 1) { |
| 2458 |
atp_dev.ultra_map |= n; |
| 2459 |
} else { |
| 2460 |
if (atp_dev.sp[k] == 0) |
| 2461 |
atp_dev.async |= n; |
| 2462 |
} |
| 2463 |
} |
| 2464 |
atp_dev.async = ~(atp_dev.async); |
| 2465 |
outb(atp_dev.global_map, base_io + 0x35); |
| 2466 |
|
| 2992 |
shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); |
2467 |
shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); |
| 2993 |
if (!shpnt) |
2468 |
if (!shpnt) |
| 2994 |
return -ENOMEM; |
2469 |
return -ENOMEM; |
| 2995 |
|
2470 |
|
| 2996 |
p = (struct atp_unit *)&shpnt->hostdata; |
2471 |
p = (struct atp_unit *)&shpnt->hostdata; |
| 2997 |
|
2472 |
|
| 2998 |
atp_dev.host = shpnt; |
2473 |
atp_dev.host = shpnt; |
| 2999 |
atp_dev.pdev = pdev; |
2474 |
atp_dev.pdev = dev; |
| 3000 |
pci_set_drvdata(pdev, p); |
2475 |
pci_set_drvdata(dev, p); |
| 3001 |
memcpy(p, &atp_dev, sizeof atp_dev); |
2476 |
memcpy(p, &atp_dev, sizeof atp_dev); |
| 3002 |
if (atp870u_init_tables(shpnt) < 0) |
2477 |
if (atp870u_init_tables(shpnt) < 0) { |
|
|
2478 |
printk(KERN_ERR "Unable to allocate tables for Acard controller\n"); |
| 3003 |
goto unregister; |
2479 |
goto unregister; |
|
|
2480 |
} |
| 3004 |
|
2481 |
|
| 3005 |
if (request_irq(pdev->irq, atp870u_intr_handle, SA_SHIRQ, "atp870i", shpnt)) { |
2482 |
if (request_irq(dev->irq, atp870u_intr_handle, SA_SHIRQ, "atp870u", shpnt)) { |
| 3006 |
printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", pdev->irq); |
2483 |
printk(KERN_ERR "Unable to allocate IRQ%d for Acard controller.\n", dev->irq); |
| 3007 |
goto free_tables; |
2484 |
goto free_tables; |
| 3008 |
} |
2485 |
} |
| 3009 |
|
2486 |
|
| 3010 |
spin_lock_irqsave(shpnt->host_lock, flags); |
2487 |
spin_lock_irqsave(shpnt->host_lock, flags); |
| 3011 |
if (atp_dev.chip_ver > 0x07) { /* check if atp876 chip then enable terminator */ |
2488 |
tmport = base_io + 0x38; |
| 3012 |
tmport = base_io + 0x3e; |
2489 |
k = inb(tmport) & 0x80; |
| 3013 |
outb(0x00, tmport); |
|
|
| 3014 |
} |
| 3015 |
|
| 3016 |
tmport = base_io + 0x3a; |
| 3017 |
k = (inb(tmport) & 0xf3) | 0x10; |
| 3018 |
outb(k, tmport); |
2490 |
outb(k, tmport); |
| 3019 |
outb((k & 0xdf), tmport); |
2491 |
tmport += 0x03; |
|
|
2492 |
outb(0x20, tmport); |
| 3020 |
mdelay(32); |
2493 |
mdelay(32); |
| 3021 |
outb(k, tmport); |
2494 |
outb(0, tmport); |
| 3022 |
mdelay(32); |
2495 |
mdelay(32); |
| 3023 |
tmport = base_io; |
2496 |
tmport = base_io + 0x5b; |
|
|
2497 |
inb(tmport); |
| 2498 |
tmport -= 0x04; |
| 2499 |
inb(tmport); |
| 2500 |
tmport = base_io + 0x40; |
| 3024 |
outb((host_id | 0x08), tmport); |
2501 |
outb((host_id | 0x08), tmport); |
| 3025 |
tmport += 0x18; |
2502 |
tmport += 0x18; |
| 3026 |
outb(0, tmport); |
2503 |
outb(0, tmport); |
| 3027 |
tmport += 0x07; |
2504 |
tmport += 0x07; |
| 3028 |
while ((inb(tmport) & 0x80) == 0) |
2505 |
while ((inb(tmport) & 0x80) == 0) |
| 3029 |
mdelay(1); |
2506 |
mdelay(1); |
| 3030 |
|
|
|
| 3031 |
tmport -= 0x08; |
2507 |
tmport -= 0x08; |
| 3032 |
inb(tmport); |
2508 |
inb(tmport); |
| 3033 |
tmport = base_io + 1; |
2509 |
tmport = base_io + 0x41; |
| 3034 |
outb(8, tmport++); |
2510 |
outb(8, tmport++); |
| 3035 |
outb(0x7f, tmport); |
2511 |
outb(0x7f, tmport); |
| 3036 |
tmport = base_io + 0x11; |
2512 |
tmport = base_io + 0x51; |
| 3037 |
outb(0x20, tmport); |
2513 |
outb(0x20, tmport); |
| 3038 |
|
2514 |
|
| 3039 |
tscam(shpnt); |
2515 |
tscam(shpnt); |
| 3040 |
is870(p, base_io); |
2516 |
is880(shpnt, base_io); |
| 3041 |
tmport = base_io + 0x3a; |
2517 |
tmport = base_io + 0x38; |
| 3042 |
outb((inb(tmport) & 0xef), tmport); |
2518 |
outb(0xb0, tmport); |
| 3043 |
tmport++; |
2519 |
} |
| 3044 |
outb((inb(tmport) | 0x20), tmport); |
2520 |
|
| 3045 |
if (atp_dev.chip_ver == 4) |
2521 |
if (p->chip_veru == 4) |
| 3046 |
shpnt->max_id = 16; |
2522 |
shpnt->max_id = 16; |
| 3047 |
else |
2523 |
|
| 3048 |
shpnt->max_id = 7; |
2524 |
shpnt->this_id = host_id; |
| 3049 |
shpnt->this_id = host_id; |
2525 |
shpnt->unique_id = base_io; |
| 3050 |
shpnt->unique_id = base_io; |
2526 |
shpnt->io_port = base_io; |
| 3051 |
shpnt->io_port = base_io; |
2527 |
if (ent->device == 0x8081) { |
|
|
2528 |
shpnt->n_io_port = 0x60; /* Number of bytes of I/O space used */ |
| 2529 |
} else { |
| 3052 |
shpnt->n_io_port = 0x40; /* Number of bytes of I/O space used */ |
2530 |
shpnt->n_io_port = 0x40; /* Number of bytes of I/O space used */ |
| 3053 |
shpnt->irq = pdev->irq; |
2531 |
} |
| 3054 |
} |
2532 |
shpnt->irq = dev->irq; |
| 3055 |
spin_unlock_irqrestore(shpnt->host_lock, flags); |
2533 |
spin_unlock_irqrestore(shpnt->host_lock, flags); |
| 3056 |
if(ent->device==ATP885_DEVID) { |
2534 |
if (ent->device == 0x8081) { |
| 3057 |
if(!request_region(base_io, 0xff, "atp870u")) /* Register the IO ports that we use */ |
2535 |
if (!request_region(base_io, 0x60, "atp870u")) |
| 3058 |
goto request_io_fail; |
2536 |
goto request_io_fail; |
| 3059 |
} else if((ent->device==ATP880_DEVID1)||(ent->device==ATP880_DEVID2)) { |
2537 |
} else { |
| 3060 |
if(!request_region(base_io, 0x60, "atp870u")) /* Register the IO ports that we use */ |
2538 |
if (!request_region(base_io, 0x40, "atp870u")) |
| 3061 |
goto request_io_fail; |
2539 |
goto request_io_fail; |
| 3062 |
} else { |
2540 |
} |
| 3063 |
if(!request_region(base_io, 0x40, "atp870u")) /* Register the IO ports that we use */ |
|
|
| 3064 |
goto request_io_fail; |
| 3065 |
} |
| 3066 |
count++; |
| 3067 |
if (scsi_add_host(shpnt, &pdev->dev)) |
| 3068 |
goto scsi_add_fail; |
| 3069 |
scsi_scan_host(shpnt); |
| 3070 |
#ifdef ED_DBGP |
| 3071 |
printk("atp870u_prob : exit\n"); |
| 3072 |
#endif |
| 3073 |
return 0; |
| 3074 |
|
2541 |
|
|
|
2542 |
count++; |
| 2543 |
if (scsi_add_host(shpnt, &dev->dev)) |
| 2544 |
goto scsi_add_fail; |
| 2545 |
scsi_scan_host(shpnt); |
| 2546 |
return 0; |
| 2547 |
|
| 3075 |
scsi_add_fail: |
2548 |
scsi_add_fail: |
| 3076 |
printk("atp870u_prob:scsi_add_fail\n"); |
2549 |
if (ent->device == 0x8081) |
| 3077 |
if(ent->device==ATP885_DEVID) { |
|
|
| 3078 |
release_region(base_io, 0xff); |
| 3079 |
} else if((ent->device==ATP880_DEVID1)||(ent->device==ATP880_DEVID2)) { |
| 3080 |
release_region(base_io, 0x60); |
2550 |
release_region(base_io, 0x60); |
| 3081 |
} else { |
2551 |
else |
| 3082 |
release_region(base_io, 0x40); |
2552 |
release_region(base_io, 0x40); |
| 3083 |
} |
|
|
| 3084 |
request_io_fail: |
2553 |
request_io_fail: |
| 3085 |
printk("atp870u_prob:request_io_fail\n"); |
2554 |
free_irq(dev->irq, shpnt); |
| 3086 |
free_irq(pdev->irq, shpnt); |
|
|
| 3087 |
free_tables: |
2555 |
free_tables: |
| 3088 |
printk("atp870u_prob:free_table\n"); |
|
|
| 3089 |
atp870u_free_tables(shpnt); |
2556 |
atp870u_free_tables(shpnt); |
| 3090 |
unregister: |
2557 |
unregister: |
| 3091 |
printk("atp870u_prob:unregister\n"); |
|
|
| 3092 |
scsi_host_put(shpnt); |
2558 |
scsi_host_put(shpnt); |
| 3093 |
return -1; |
2559 |
return -1; |
| 3094 |
} |
2560 |
} |
| 3095 |
|
2561 |
|
| 3096 |
/* The abort command does not leave the device in a clean state where |
2562 |
/* The abort command does not leave the device in a clean state where |
|
Lines 3099-3138
Link Here
|
| 3099 |
|
2565 |
|
| 3100 |
static int atp870u_abort(struct scsi_cmnd * SCpnt) |
2566 |
static int atp870u_abort(struct scsi_cmnd * SCpnt) |
| 3101 |
{ |
2567 |
{ |
| 3102 |
unsigned char j, k, c; |
2568 |
unsigned char j, k; |
| 3103 |
struct scsi_cmnd *workrequ; |
2569 |
struct scsi_cmnd *workrequ; |
| 3104 |
unsigned int tmport; |
2570 |
unsigned int tmport; |
| 3105 |
struct atp_unit *dev; |
2571 |
struct atp_unit *dev = (struct atp_unit *)&SCpnt->device->host->hostdata; |
| 3106 |
struct Scsi_Host *host; |
|
|
| 3107 |
host = SCpnt->device->host; |
| 3108 |
|
2572 |
|
| 3109 |
dev = (struct atp_unit *)&host->hostdata; |
2573 |
printk(KERN_DEBUG "working=%x last_cmd=%x ", dev->working, dev->last_cmd); |
| 3110 |
c=SCpnt->device->channel; |
2574 |
printk(" quhdu=%x quendu=%x ", dev->quhdu, dev->quendu); |
| 3111 |
printk(" atp870u: abort Channel = %x \n", c); |
2575 |
tmport = dev->ioport; |
| 3112 |
printk("working=%x last_cmd=%x ", dev->working[c], dev->last_cmd[c]); |
2576 |
for (j = 0; j < 0x17; j++) { |
| 3113 |
printk(" quhdu=%x quendu=%x ", dev->quhd[c], dev->quend[c]); |
|
|
| 3114 |
tmport = dev->ioport[c]; |
| 3115 |
for (j = 0; j < 0x18; j++) { |
| 3116 |
printk(" r%2x=%2x", j, inb(tmport++)); |
2577 |
printk(" r%2x=%2x", j, inb(tmport++)); |
| 3117 |
} |
2578 |
} |
| 3118 |
tmport += 0x04; |
2579 |
tmport += 0x05; |
| 3119 |
printk(" r1c=%2x", inb(tmport)); |
2580 |
printk(" r1c=%2x", inb(tmport)); |
| 3120 |
tmport += 0x03; |
2581 |
tmport += 0x03; |
| 3121 |
printk(" r1f=%2x in_snd=%2x ", inb(tmport), dev->in_snd[c]); |
2582 |
printk(" r1f=%2x in_snd=%2x ", inb(tmport), dev->in_snd); |
| 3122 |
tmport= dev->pciport[c]; |
2583 |
tmport = dev->pciport; |
| 3123 |
printk(" d00=%2x", inb(tmport)); |
2584 |
printk(" r20=%2x", inb(tmport)); |
| 3124 |
tmport += 0x02; |
2585 |
tmport += 0x02; |
| 3125 |
printk(" d02=%2x", inb(tmport)); |
2586 |
printk(" r22=%2x", inb(tmport)); |
| 3126 |
for(j=0;j<16;j++) { |
2587 |
tmport = dev->ioport + 0x3a; |
| 3127 |
if (dev->id[c][j].curr_req != NULL) { |
2588 |
printk(" r3a=%2x \n", inb(tmport)); |
| 3128 |
workrequ = dev->id[c][j].curr_req; |
2589 |
tmport = dev->ioport + 0x3b; |
| 3129 |
printk("\n que cdb= "); |
2590 |
printk(" r3b=%2x \n", inb(tmport)); |
| 3130 |
for (k=0; k < workrequ->cmd_len; k++) { |
2591 |
for (j = 0; j < 16; j++) { |
| 3131 |
printk(" %2x ",workrequ->cmnd[k]); |
2592 |
if (dev->id[j].curr_req != NULL) { |
|
|
2593 |
workrequ = dev->id[j].curr_req; |
| 2594 |
printk("\n que cdb= "); |
| 2595 |
for (k = 0; k < workrequ->cmd_len; k++) { |
| 2596 |
printk(" %2x ", workrequ->cmnd[k]); |
| 2597 |
} |
| 2598 |
printk(" last_lenu= %lx ", dev->id[j].last_lenu); |
| 3132 |
} |
2599 |
} |
| 3133 |
printk(" last_lenu= %x ",(unsigned int)dev->id[c][j].last_len); |
|
|
| 3134 |
} |
| 3135 |
} |
2600 |
} |
|
|
2601 |
/* Sort of - the thing handles itself */ |
| 3136 |
return SUCCESS; |
2602 |
return SUCCESS; |
| 3137 |
} |
2603 |
} |
| 3138 |
|
2604 |
|
|
Lines 3170-3176
Link Here
|
| 3170 |
size += sprintf(BLS, " IRQ: %d\n", HBAptr->irq); |
2636 |
size += sprintf(BLS, " IRQ: %d\n", HBAptr->irq); |
| 3171 |
len += size; |
2637 |
len += size; |
| 3172 |
pos = begin + len; |
2638 |
pos = begin + len; |
| 3173 |
|
2639 |
|
| 3174 |
*start = buffer + (offset - begin); /* Start of wanted data */ |
2640 |
*start = buffer + (offset - begin); /* Start of wanted data */ |
| 3175 |
len -= (offset - begin); /* Start slop */ |
2641 |
len -= (offset - begin); /* Start slop */ |
| 3176 |
if (len > length) { |
2642 |
if (len > length) { |
|
Lines 3179-3193
Link Here
|
| 3179 |
return (len); |
2645 |
return (len); |
| 3180 |
} |
2646 |
} |
| 3181 |
|
2647 |
|
| 3182 |
|
2648 |
static int atp870u_biosparam(struct scsi_device *sdev, |
| 3183 |
static int atp870u_biosparam(struct scsi_device *disk, struct block_device *dev, |
2649 |
struct block_device *dev, sector_t capacity, int *ip) |
| 3184 |
sector_t capacity, int *ip) |
|
|
| 3185 |
{ |
2650 |
{ |
| 3186 |
int heads, sectors, cylinders; |
2651 |
int heads, sectors, cylinders; |
| 3187 |
|
2652 |
|
| 3188 |
heads = 64; |
2653 |
heads = 64; |
| 3189 |
sectors = 32; |
2654 |
sectors = 32; |
| 3190 |
cylinders = (unsigned long)capacity / (heads * sectors); |
2655 |
cylinders = (unsigned long)capacity / (heads * sectors); |
|
|
2656 |
|
| 3191 |
if (cylinders > 1024) { |
2657 |
if (cylinders > 1024) { |
| 3192 |
heads = 255; |
2658 |
heads = 255; |
| 3193 |
sectors = 63; |
2659 |
sectors = 63; |
|
Lines 3200-3245
Link Here
|
| 3200 |
return 0; |
2666 |
return 0; |
| 3201 |
} |
2667 |
} |
| 3202 |
|
2668 |
|
| 3203 |
static void atp870u_remove (struct pci_dev *pdev) |
2669 |
static void atp870u_remove(struct pci_dev *pdev) |
| 3204 |
{ |
2670 |
{ |
| 3205 |
struct atp_unit *devext = pci_get_drvdata(pdev); |
2671 |
struct atp_unit *atp_dev = pci_get_drvdata(pdev); |
| 3206 |
struct Scsi_Host *pshost = devext->host; |
2672 |
struct Scsi_Host *pshost = atp_dev->host; |
| 3207 |
|
2673 |
|
| 3208 |
|
|
|
| 3209 |
scsi_remove_host(pshost); |
2674 |
scsi_remove_host(pshost); |
| 3210 |
printk(KERN_INFO "free_irq : %d\n",pshost->irq); |
|
|
| 3211 |
free_irq(pshost->irq, pshost); |
2675 |
free_irq(pshost->irq, pshost); |
| 3212 |
release_region(pshost->io_port, pshost->n_io_port); |
2676 |
release_region(pshost->io_port, pshost->n_io_port); |
| 3213 |
printk(KERN_INFO "atp870u_free_tables : %p\n",pshost); |
|
|
| 3214 |
atp870u_free_tables(pshost); |
2677 |
atp870u_free_tables(pshost); |
| 3215 |
printk(KERN_INFO "scsi_host_put : %p\n",pshost); |
|
|
| 3216 |
scsi_host_put(pshost); |
2678 |
scsi_host_put(pshost); |
| 3217 |
printk(KERN_INFO "pci_set_drvdata : %p\n",pdev); |
2679 |
pci_set_drvdata(pdev, NULL); |
| 3218 |
pci_set_drvdata(pdev, NULL); |
|
|
| 3219 |
} |
2680 |
} |
|
|
2681 |
|
| 3220 |
MODULE_LICENSE("GPL"); |
2682 |
MODULE_LICENSE("GPL"); |
| 3221 |
|
2683 |
|
| 3222 |
static struct scsi_host_template atp870u_template = { |
2684 |
static struct scsi_host_template atp870u_template = { |
| 3223 |
.module = THIS_MODULE, |
2685 |
.module = THIS_MODULE, |
| 3224 |
.name = "atp870u" /* name */, |
2686 |
.name = "atp870u", |
| 3225 |
.proc_name = "atp870u", |
2687 |
.proc_name = "atp870u", |
| 3226 |
.proc_info = atp870u_proc_info, |
2688 |
.proc_info = atp870u_proc_info, |
| 3227 |
.info = atp870u_info /* info */, |
2689 |
.info = atp870u_info, |
| 3228 |
.queuecommand = atp870u_queuecommand /* queuecommand */, |
2690 |
.queuecommand = atp870u_queuecommand, |
| 3229 |
.eh_abort_handler = atp870u_abort /* abort */, |
2691 |
.eh_abort_handler = atp870u_abort, |
| 3230 |
.bios_param = atp870u_biosparam /* biosparm */, |
2692 |
.bios_param = atp870u_biosparam, |
| 3231 |
.can_queue = qcnt /* can_queue */, |
2693 |
.can_queue = qcnt, |
| 3232 |
.this_id = 7 /* SCSI ID */, |
2694 |
.this_id = 7, |
| 3233 |
.sg_tablesize = ATP870U_SCATTER /*SG_ALL*/ /*SG_NONE*/, |
2695 |
.sg_tablesize = ATP870U_SCATTER, |
| 3234 |
.cmd_per_lun = ATP870U_CMDLUN /* commands per lun */, |
2696 |
.cmd_per_lun = ATP870U_CMDLUN, |
| 3235 |
.use_clustering = ENABLE_CLUSTERING, |
2697 |
.use_clustering = ENABLE_CLUSTERING, |
| 3236 |
.max_sectors = ATP870U_MAX_SECTORS, |
|
|
| 3237 |
}; |
2698 |
}; |
| 3238 |
|
2699 |
|
| 3239 |
static struct pci_device_id atp870u_id_table[] = { |
2700 |
static struct pci_device_id atp870u_id_table[] = { |
| 3240 |
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP885_DEVID) }, |
2701 |
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, 0x8081) }, |
| 3241 |
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP880_DEVID1) }, |
|
|
| 3242 |
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, ATP880_DEVID2) }, |
| 3243 |
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7610) }, |
2702 |
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7610) }, |
| 3244 |
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612UW) }, |
2703 |
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612UW) }, |
| 3245 |
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612U) }, |
2704 |
{ PCI_DEVICE(PCI_VENDOR_ID_ARTOP, PCI_DEVICE_ID_ARTOP_AEC7612U) }, |
|
Lines 3252-3258
Link Here
|
| 3252 |
|
2711 |
|
| 3253 |
MODULE_DEVICE_TABLE(pci, atp870u_id_table); |
2712 |
MODULE_DEVICE_TABLE(pci, atp870u_id_table); |
| 3254 |
|
2713 |
|
| 3255 |
static struct pci_driver atp870u_driver = { |
2714 |
static struct pci_driver atp870u_driver = { |
| 3256 |
.id_table = atp870u_id_table, |
2715 |
.id_table = atp870u_id_table, |
| 3257 |
.name = "atp870u", |
2716 |
.name = "atp870u", |
| 3258 |
.probe = atp870u_probe, |
2717 |
.probe = atp870u_probe, |
|
Lines 3261-3970
Link Here
|
| 3261 |
|
2720 |
|
| 3262 |
static int __init atp870u_init(void) |
2721 |
static int __init atp870u_init(void) |
| 3263 |
{ |
2722 |
{ |
| 3264 |
#ifdef ED_DBGP |
2723 |
return pci_module_init(&atp870u_driver); |
| 3265 |
printk("atp870u_init: Entry\n"); |
|
|
| 3266 |
#endif |
| 3267 |
return pci_register_driver(&atp870u_driver); |
| 3268 |
} |
2724 |
} |
| 3269 |
|
2725 |
|
| 3270 |
static void __exit atp870u_exit(void) |
2726 |
static void __exit atp870u_exit(void) |
| 3271 |
{ |
2727 |
{ |
| 3272 |
#ifdef ED_DBGP |
|
|
| 3273 |
printk("atp870u_exit: Entry\n"); |
| 3274 |
#endif |
| 3275 |
pci_unregister_driver(&atp870u_driver); |
2728 |
pci_unregister_driver(&atp870u_driver); |
| 3276 |
} |
2729 |
} |
| 3277 |
|
2730 |
|
| 3278 |
static void tscam_885(void) |
|
|
| 3279 |
{ |
| 3280 |
unsigned char i; |
| 3281 |
|
| 3282 |
for (i = 0; i < 0x2; i++) { |
| 3283 |
mdelay(300); |
| 3284 |
} |
| 3285 |
return; |
| 3286 |
} |
| 3287 |
|
| 3288 |
|
| 3289 |
|
| 3290 |
static void is885(struct atp_unit *dev, unsigned int wkport,unsigned char c) |
| 3291 |
{ |
| 3292 |
unsigned int tmport; |
| 3293 |
unsigned char i, j, k, rmb, n, lvdmode; |
| 3294 |
unsigned short int m; |
| 3295 |
static unsigned char mbuf[512]; |
| 3296 |
static unsigned char satn[9] = {0, 0, 0, 0, 0, 0, 0, 6, 6}; |
| 3297 |
static unsigned char inqd[9] = {0x12, 0, 0, 0, 0x24, 0, 0, 0x24, 6}; |
| 3298 |
static unsigned char synn[6] = {0x80, 1, 3, 1, 0x19, 0x0e}; |
| 3299 |
unsigned char synu[6] = {0x80, 1, 3, 1, 0x0a, 0x0e}; |
| 3300 |
static unsigned char synw[6] = {0x80, 1, 3, 1, 0x19, 0x0e}; |
| 3301 |
unsigned char synuw[6] = {0x80, 1, 3, 1, 0x0a, 0x0e}; |
| 3302 |
static unsigned char wide[6] = {0x80, 1, 2, 3, 1, 0}; |
| 3303 |
static unsigned char u3[9] = { 0x80,1,6,4,0x09,00,0x0e,0x01,0x02 }; |
| 3304 |
|
| 3305 |
lvdmode=inb(wkport + 0x1b) >> 7; |
| 3306 |
|
| 3307 |
for (i = 0; i < 16; i++) { |
| 3308 |
m = 1; |
| 3309 |
m = m << i; |
| 3310 |
if ((m & dev->active_id[c]) != 0) { |
| 3311 |
continue; |
| 3312 |
} |
| 3313 |
if (i == dev->host_id[c]) { |
| 3314 |
printk(KERN_INFO " ID: %2d Host Adapter\n", dev->host_id[c]); |
| 3315 |
continue; |
| 3316 |
} |
| 3317 |
tmport = wkport + 0x1b; |
| 3318 |
outb(0x01, tmport); |
| 3319 |
tmport = wkport + 0x01; |
| 3320 |
outb(0x08, tmport++); |
| 3321 |
outb(0x7f, tmport++); |
| 3322 |
outb(satn[0], tmport++); |
| 3323 |
outb(satn[1], tmport++); |
| 3324 |
outb(satn[2], tmport++); |
| 3325 |
outb(satn[3], tmport++); |
| 3326 |
outb(satn[4], tmport++); |
| 3327 |
outb(satn[5], tmport++); |
| 3328 |
tmport += 0x06; |
| 3329 |
outb(0, tmport); |
| 3330 |
tmport += 0x02; |
| 3331 |
outb(dev->id[c][i].devsp, tmport++); |
| 3332 |
|
| 3333 |
outb(0, tmport++); |
| 3334 |
outb(satn[6], tmport++); |
| 3335 |
outb(satn[7], tmport++); |
| 3336 |
j = i; |
| 3337 |
if ((j & 0x08) != 0) { |
| 3338 |
j = (j & 0x07) | 0x40; |
| 3339 |
} |
| 3340 |
outb(j, tmport); |
| 3341 |
tmport += 0x03; |
| 3342 |
outb(satn[8], tmport); |
| 3343 |
tmport += 0x07; |
| 3344 |
|
| 3345 |
while ((inb(tmport) & 0x80) == 0x00) |
| 3346 |
cpu_relax(); |
| 3347 |
tmport -= 0x08; |
| 3348 |
if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { |
| 3349 |
continue; |
| 3350 |
} |
| 3351 |
while (inb(tmport) != 0x8e) |
| 3352 |
cpu_relax(); |
| 3353 |
dev->active_id[c] |= m; |
| 3354 |
|
| 3355 |
tmport = wkport + 0x10; |
| 3356 |
outb(0x30, tmport); |
| 3357 |
tmport = wkport + 0x14; |
| 3358 |
outb(0x00, tmport); |
| 3359 |
|
| 3360 |
phase_cmd: |
| 3361 |
tmport = wkport + 0x18; |
| 3362 |
outb(0x08, tmport); |
| 3363 |
tmport += 0x07; |
| 3364 |
while ((inb(tmport) & 0x80) == 0x00) |
| 3365 |
cpu_relax(); |
| 3366 |
tmport -= 0x08; |
| 3367 |
j = inb(tmport); |
| 3368 |
if (j != 0x16) { |
| 3369 |
tmport = wkport + 0x10; |
| 3370 |
outb(0x41, tmport); |
| 3371 |
goto phase_cmd; |
| 3372 |
} |
| 3373 |
sel_ok: |
| 3374 |
tmport = wkport + 0x03; |
| 3375 |
outb(inqd[0], tmport++); |
| 3376 |
outb(inqd[1], tmport++); |
| 3377 |
outb(inqd[2], tmport++); |
| 3378 |
outb(inqd[3], tmport++); |
| 3379 |
outb(inqd[4], tmport++); |
| 3380 |
outb(inqd[5], tmport); |
| 3381 |
tmport += 0x07; |
| 3382 |
outb(0, tmport); |
| 3383 |
tmport += 0x02; |
| 3384 |
outb(dev->id[c][i].devsp, tmport++); |
| 3385 |
outb(0, tmport++); |
| 3386 |
outb(inqd[6], tmport++); |
| 3387 |
outb(inqd[7], tmport++); |
| 3388 |
tmport += 0x03; |
| 3389 |
outb(inqd[8], tmport); |
| 3390 |
tmport += 0x07; |
| 3391 |
while ((inb(tmport) & 0x80) == 0x00) |
| 3392 |
cpu_relax(); |
| 3393 |
tmport -= 0x08; |
| 3394 |
if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { |
| 3395 |
continue; |
| 3396 |
} |
| 3397 |
while (inb(tmport) != 0x8e) |
| 3398 |
cpu_relax(); |
| 3399 |
tmport = wkport + 0x1b; |
| 3400 |
outb(0x00, tmport); |
| 3401 |
tmport = wkport + 0x18; |
| 3402 |
outb(0x08, tmport); |
| 3403 |
tmport += 0x07; |
| 3404 |
j = 0; |
| 3405 |
rd_inq_data: |
| 3406 |
k = inb(tmport); |
| 3407 |
if ((k & 0x01) != 0) { |
| 3408 |
tmport -= 0x06; |
| 3409 |
mbuf[j++] = inb(tmport); |
| 3410 |
tmport += 0x06; |
| 3411 |
goto rd_inq_data; |
| 3412 |
} |
| 3413 |
if ((k & 0x80) == 0) { |
| 3414 |
goto rd_inq_data; |
| 3415 |
} |
| 3416 |
tmport -= 0x08; |
| 3417 |
j = inb(tmport); |
| 3418 |
if (j == 0x16) { |
| 3419 |
goto inq_ok; |
| 3420 |
} |
| 3421 |
tmport = wkport + 0x10; |
| 3422 |
outb(0x46, tmport); |
| 3423 |
tmport += 0x02; |
| 3424 |
outb(0, tmport++); |
| 3425 |
outb(0, tmport++); |
| 3426 |
outb(0, tmport++); |
| 3427 |
tmport += 0x03; |
| 3428 |
outb(0x08, tmport); |
| 3429 |
tmport += 0x07; |
| 3430 |
while ((inb(tmport) & 0x80) == 0x00) |
| 3431 |
cpu_relax(); |
| 3432 |
tmport -= 0x08; |
| 3433 |
if (inb(tmport) != 0x16) { |
| 3434 |
goto sel_ok; |
| 3435 |
} |
| 3436 |
inq_ok: |
| 3437 |
mbuf[36] = 0; |
| 3438 |
printk( KERN_INFO" ID: %2d %s\n", i, &mbuf[8]); |
| 3439 |
dev->id[c][i].devtype = mbuf[0]; |
| 3440 |
rmb = mbuf[1]; |
| 3441 |
n = mbuf[7]; |
| 3442 |
if ((mbuf[7] & 0x60) == 0) { |
| 3443 |
goto not_wide; |
| 3444 |
} |
| 3445 |
if ((i < 8) && ((dev->global_map[c] & 0x20) == 0)) { |
| 3446 |
goto not_wide; |
| 3447 |
} |
| 3448 |
if (lvdmode == 0) { |
| 3449 |
goto chg_wide; |
| 3450 |
} |
| 3451 |
if (dev->sp[c][i] != 0x04) { // force u2 |
| 3452 |
goto chg_wide; |
| 3453 |
} |
| 3454 |
|
| 3455 |
tmport = wkport + 0x1b; |
| 3456 |
outb(0x01, tmport); |
| 3457 |
tmport = wkport + 0x03; |
| 3458 |
outb(satn[0], tmport++); |
| 3459 |
outb(satn[1], tmport++); |
| 3460 |
outb(satn[2], tmport++); |
| 3461 |
outb(satn[3], tmport++); |
| 3462 |
outb(satn[4], tmport++); |
| 3463 |
outb(satn[5], tmport++); |
| 3464 |
tmport += 0x06; |
| 3465 |
outb(0, tmport); |
| 3466 |
tmport += 0x02; |
| 3467 |
outb(dev->id[c][i].devsp, tmport++); |
| 3468 |
outb(0, tmport++); |
| 3469 |
outb(satn[6], tmport++); |
| 3470 |
outb(satn[7], tmport++); |
| 3471 |
tmport += 0x03; |
| 3472 |
outb(satn[8], tmport); |
| 3473 |
tmport += 0x07; |
| 3474 |
|
| 3475 |
while ((inb(tmport) & 0x80) == 0x00) |
| 3476 |
cpu_relax(); |
| 3477 |
tmport -= 0x08; |
| 3478 |
if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { |
| 3479 |
continue; |
| 3480 |
} |
| 3481 |
while (inb(tmport) != 0x8e) |
| 3482 |
cpu_relax(); |
| 3483 |
try_u3: |
| 3484 |
j = 0; |
| 3485 |
tmport = wkport + 0x14; |
| 3486 |
outb(0x09, tmport); |
| 3487 |
tmport += 0x04; |
| 3488 |
outb(0x20, tmport); |
| 3489 |
tmport += 0x07; |
| 3490 |
|
| 3491 |
while ((inb(tmport) & 0x80) == 0) { |
| 3492 |
if ((inb(tmport) & 0x01) != 0) { |
| 3493 |
tmport -= 0x06; |
| 3494 |
outb(u3[j++], tmport); |
| 3495 |
tmport += 0x06; |
| 3496 |
} |
| 3497 |
cpu_relax(); |
| 3498 |
} |
| 3499 |
tmport -= 0x08; |
| 3500 |
while ((inb(tmport) & 0x80) == 0x00) |
| 3501 |
cpu_relax(); |
| 3502 |
j = inb(tmport) & 0x0f; |
| 3503 |
if (j == 0x0f) { |
| 3504 |
goto u3p_in; |
| 3505 |
} |
| 3506 |
if (j == 0x0a) { |
| 3507 |
goto u3p_cmd; |
| 3508 |
} |
| 3509 |
if (j == 0x0e) { |
| 3510 |
goto try_u3; |
| 3511 |
} |
| 3512 |
continue; |
| 3513 |
u3p_out: |
| 3514 |
tmport = wkport + 0x18; |
| 3515 |
outb(0x20, tmport); |
| 3516 |
tmport += 0x07; |
| 3517 |
while ((inb(tmport) & 0x80) == 0) { |
| 3518 |
if ((inb(tmport) & 0x01) != 0) { |
| 3519 |
tmport -= 0x06; |
| 3520 |
outb(0, tmport); |
| 3521 |
tmport += 0x06; |
| 3522 |
} |
| 3523 |
cpu_relax(); |
| 3524 |
} |
| 3525 |
tmport -= 0x08; |
| 3526 |
j = inb(tmport) & 0x0f; |
| 3527 |
if (j == 0x0f) { |
| 3528 |
goto u3p_in; |
| 3529 |
} |
| 3530 |
if (j == 0x0a) { |
| 3531 |
goto u3p_cmd; |
| 3532 |
} |
| 3533 |
if (j == 0x0e) { |
| 3534 |
goto u3p_out; |
| 3535 |
} |
| 3536 |
continue; |
| 3537 |
u3p_in: |
| 3538 |
tmport = wkport + 0x14; |
| 3539 |
outb(0x09, tmport); |
| 3540 |
tmport += 0x04; |
| 3541 |
outb(0x20, tmport); |
| 3542 |
tmport += 0x07; |
| 3543 |
k = 0; |
| 3544 |
u3p_in1: |
| 3545 |
j = inb(tmport); |
| 3546 |
if ((j & 0x01) != 0) { |
| 3547 |
tmport -= 0x06; |
| 3548 |
mbuf[k++] = inb(tmport); |
| 3549 |
tmport += 0x06; |
| 3550 |
goto u3p_in1; |
| 3551 |
} |
| 3552 |
if ((j & 0x80) == 0x00) { |
| 3553 |
goto u3p_in1; |
| 3554 |
} |
| 3555 |
tmport -= 0x08; |
| 3556 |
j = inb(tmport) & 0x0f; |
| 3557 |
if (j == 0x0f) { |
| 3558 |
goto u3p_in; |
| 3559 |
} |
| 3560 |
if (j == 0x0a) { |
| 3561 |
goto u3p_cmd; |
| 3562 |
} |
| 3563 |
if (j == 0x0e) { |
| 3564 |
goto u3p_out; |
| 3565 |
} |
| 3566 |
continue; |
| 3567 |
u3p_cmd: |
| 3568 |
tmport = wkport + 0x10; |
| 3569 |
outb(0x30, tmport); |
| 3570 |
tmport = wkport + 0x14; |
| 3571 |
outb(0x00, tmport); |
| 3572 |
tmport += 0x04; |
| 3573 |
outb(0x08, tmport); |
| 3574 |
tmport += 0x07; |
| 3575 |
while ((inb(tmport) & 0x80) == 0x00); |
| 3576 |
tmport -= 0x08; |
| 3577 |
j = inb(tmport); |
| 3578 |
if (j != 0x16) { |
| 3579 |
if (j == 0x4e) { |
| 3580 |
goto u3p_out; |
| 3581 |
} |
| 3582 |
continue; |
| 3583 |
} |
| 3584 |
if (mbuf[0] != 0x01) { |
| 3585 |
goto chg_wide; |
| 3586 |
} |
| 3587 |
if (mbuf[1] != 0x06) { |
| 3588 |
goto chg_wide; |
| 3589 |
} |
| 3590 |
if (mbuf[2] != 0x04) { |
| 3591 |
goto chg_wide; |
| 3592 |
} |
| 3593 |
if (mbuf[3] == 0x09) { |
| 3594 |
m = 1; |
| 3595 |
m = m << i; |
| 3596 |
dev->wide_id[c] |= m; |
| 3597 |
dev->id[c][i].devsp = 0xce; |
| 3598 |
#ifdef ED_DBGP |
| 3599 |
printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp); |
| 3600 |
#endif |
| 3601 |
continue; |
| 3602 |
} |
| 3603 |
chg_wide: |
| 3604 |
tmport = wkport + 0x1b; |
| 3605 |
outb(0x01, tmport); |
| 3606 |
tmport = wkport + 0x03; |
| 3607 |
outb(satn[0], tmport++); |
| 3608 |
outb(satn[1], tmport++); |
| 3609 |
outb(satn[2], tmport++); |
| 3610 |
outb(satn[3], tmport++); |
| 3611 |
outb(satn[4], tmport++); |
| 3612 |
outb(satn[5], tmport++); |
| 3613 |
tmport += 0x06; |
| 3614 |
outb(0, tmport); |
| 3615 |
tmport += 0x02; |
| 3616 |
outb(dev->id[c][i].devsp, tmport++); |
| 3617 |
outb(0, tmport++); |
| 3618 |
outb(satn[6], tmport++); |
| 3619 |
outb(satn[7], tmport++); |
| 3620 |
tmport += 0x03; |
| 3621 |
outb(satn[8], tmport); |
| 3622 |
tmport += 0x07; |
| 3623 |
|
| 3624 |
while ((inb(tmport) & 0x80) == 0x00) |
| 3625 |
cpu_relax(); |
| 3626 |
tmport -= 0x08; |
| 3627 |
if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { |
| 3628 |
continue; |
| 3629 |
} |
| 3630 |
while (inb(tmport) != 0x8e) |
| 3631 |
cpu_relax(); |
| 3632 |
try_wide: |
| 3633 |
j = 0; |
| 3634 |
tmport = wkport + 0x14; |
| 3635 |
outb(0x05, tmport); |
| 3636 |
tmport += 0x04; |
| 3637 |
outb(0x20, tmport); |
| 3638 |
tmport += 0x07; |
| 3639 |
|
| 3640 |
while ((inb(tmport) & 0x80) == 0) { |
| 3641 |
if ((inb(tmport) & 0x01) != 0) { |
| 3642 |
tmport -= 0x06; |
| 3643 |
outb(wide[j++], tmport); |
| 3644 |
tmport += 0x06; |
| 3645 |
} |
| 3646 |
cpu_relax(); |
| 3647 |
} |
| 3648 |
tmport -= 0x08; |
| 3649 |
while ((inb(tmport) & 0x80) == 0x00) |
| 3650 |
cpu_relax(); |
| 3651 |
j = inb(tmport) & 0x0f; |
| 3652 |
if (j == 0x0f) { |
| 3653 |
goto widep_in; |
| 3654 |
} |
| 3655 |
if (j == 0x0a) { |
| 3656 |
goto widep_cmd; |
| 3657 |
} |
| 3658 |
if (j == 0x0e) { |
| 3659 |
goto try_wide; |
| 3660 |
} |
| 3661 |
continue; |
| 3662 |
widep_out: |
| 3663 |
tmport = wkport + 0x18; |
| 3664 |
outb(0x20, tmport); |
| 3665 |
tmport += 0x07; |
| 3666 |
while ((inb(tmport) & 0x80) == 0) { |
| 3667 |
if ((inb(tmport) & 0x01) != 0) { |
| 3668 |
tmport -= 0x06; |
| 3669 |
outb(0, tmport); |
| 3670 |
tmport += 0x06; |
| 3671 |
} |
| 3672 |
cpu_relax(); |
| 3673 |
} |
| 3674 |
tmport -= 0x08; |
| 3675 |
j = inb(tmport) & 0x0f; |
| 3676 |
if (j == 0x0f) { |
| 3677 |
goto widep_in; |
| 3678 |
} |
| 3679 |
if (j == 0x0a) { |
| 3680 |
goto widep_cmd; |
| 3681 |
} |
| 3682 |
if (j == 0x0e) { |
| 3683 |
goto widep_out; |
| 3684 |
} |
| 3685 |
continue; |
| 3686 |
widep_in: |
| 3687 |
tmport = wkport + 0x14; |
| 3688 |
outb(0xff, tmport); |
| 3689 |
tmport += 0x04; |
| 3690 |
outb(0x20, tmport); |
| 3691 |
tmport += 0x07; |
| 3692 |
k = 0; |
| 3693 |
widep_in1: |
| 3694 |
j = inb(tmport); |
| 3695 |
if ((j & 0x01) != 0) { |
| 3696 |
tmport -= 0x06; |
| 3697 |
mbuf[k++] = inb(tmport); |
| 3698 |
tmport += 0x06; |
| 3699 |
goto widep_in1; |
| 3700 |
} |
| 3701 |
if ((j & 0x80) == 0x00) { |
| 3702 |
goto widep_in1; |
| 3703 |
} |
| 3704 |
tmport -= 0x08; |
| 3705 |
j = inb(tmport) & 0x0f; |
| 3706 |
if (j == 0x0f) { |
| 3707 |
goto widep_in; |
| 3708 |
} |
| 3709 |
if (j == 0x0a) { |
| 3710 |
goto widep_cmd; |
| 3711 |
} |
| 3712 |
if (j == 0x0e) { |
| 3713 |
goto widep_out; |
| 3714 |
} |
| 3715 |
continue; |
| 3716 |
widep_cmd: |
| 3717 |
tmport = wkport + 0x10; |
| 3718 |
outb(0x30, tmport); |
| 3719 |
tmport = wkport + 0x14; |
| 3720 |
outb(0x00, tmport); |
| 3721 |
tmport += 0x04; |
| 3722 |
outb(0x08, tmport); |
| 3723 |
tmport += 0x07; |
| 3724 |
while ((inb(tmport) & 0x80) == 0x00) |
| 3725 |
cpu_relax(); |
| 3726 |
tmport -= 0x08; |
| 3727 |
j = inb(tmport); |
| 3728 |
if (j != 0x16) { |
| 3729 |
if (j == 0x4e) { |
| 3730 |
goto widep_out; |
| 3731 |
} |
| 3732 |
continue; |
| 3733 |
} |
| 3734 |
if (mbuf[0] != 0x01) { |
| 3735 |
goto not_wide; |
| 3736 |
} |
| 3737 |
if (mbuf[1] != 0x02) { |
| 3738 |
goto not_wide; |
| 3739 |
} |
| 3740 |
if (mbuf[2] != 0x03) { |
| 3741 |
goto not_wide; |
| 3742 |
} |
| 3743 |
if (mbuf[3] != 0x01) { |
| 3744 |
goto not_wide; |
| 3745 |
} |
| 3746 |
m = 1; |
| 3747 |
m = m << i; |
| 3748 |
dev->wide_id[c] |= m; |
| 3749 |
not_wide: |
| 3750 |
if ((dev->id[c][i].devtype == 0x00) || (dev->id[c][i].devtype == 0x07) || |
| 3751 |
((dev->id[c][i].devtype == 0x05) && ((n & 0x10) != 0))) { |
| 3752 |
m = 1; |
| 3753 |
m = m << i; |
| 3754 |
if ((dev->async[c] & m) != 0) { |
| 3755 |
goto set_sync; |
| 3756 |
} |
| 3757 |
} |
| 3758 |
continue; |
| 3759 |
set_sync: |
| 3760 |
if (dev->sp[c][i] == 0x02) { |
| 3761 |
synu[4]=0x0c; |
| 3762 |
synuw[4]=0x0c; |
| 3763 |
} else { |
| 3764 |
if (dev->sp[c][i] >= 0x03) { |
| 3765 |
synu[4]=0x0a; |
| 3766 |
synuw[4]=0x0a; |
| 3767 |
} |
| 3768 |
} |
| 3769 |
tmport = wkport + 0x1b; |
| 3770 |
j = 0; |
| 3771 |
if ((m & dev->wide_id[c]) != 0) { |
| 3772 |
j |= 0x01; |
| 3773 |
} |
| 3774 |
outb(j, tmport); |
| 3775 |
tmport = wkport + 0x03; |
| 3776 |
outb(satn[0], tmport++); |
| 3777 |
outb(satn[1], tmport++); |
| 3778 |
outb(satn[2], tmport++); |
| 3779 |
outb(satn[3], tmport++); |
| 3780 |
outb(satn[4], tmport++); |
| 3781 |
outb(satn[5], tmport++); |
| 3782 |
tmport += 0x06; |
| 3783 |
outb(0, tmport); |
| 3784 |
tmport += 0x02; |
| 3785 |
outb(dev->id[c][i].devsp, tmport++); |
| 3786 |
outb(0, tmport++); |
| 3787 |
outb(satn[6], tmport++); |
| 3788 |
outb(satn[7], tmport++); |
| 3789 |
tmport += 0x03; |
| 3790 |
outb(satn[8], tmport); |
| 3791 |
tmport += 0x07; |
| 3792 |
|
| 3793 |
while ((inb(tmport) & 0x80) == 0x00) |
| 3794 |
cpu_relax(); |
| 3795 |
tmport -= 0x08; |
| 3796 |
if ((inb(tmport) != 0x11) && (inb(tmport) != 0x8e)) { |
| 3797 |
continue; |
| 3798 |
} |
| 3799 |
while (inb(tmport) != 0x8e) |
| 3800 |
cpu_relax(); |
| 3801 |
try_sync: |
| 3802 |
j = 0; |
| 3803 |
tmport = wkport + 0x14; |
| 3804 |
outb(0x06, tmport); |
| 3805 |
tmport += 0x04; |
| 3806 |
outb(0x20, tmport); |
| 3807 |
tmport += 0x07; |
| 3808 |
|
| 3809 |
while ((inb(tmport) & 0x80) == 0) { |
| 3810 |
if ((inb(tmport) & 0x01) != 0) { |
| 3811 |
tmport -= 0x06; |
| 3812 |
if ((m & dev->wide_id[c]) != 0) { |
| 3813 |
if ((m & dev->ultra_map[c]) != 0) { |
| 3814 |
outb(synuw[j++], tmport); |
| 3815 |
} else { |
| 3816 |
outb(synw[j++], tmport); |
| 3817 |
} |
| 3818 |
} else { |
| 3819 |
if ((m & dev->ultra_map[c]) != 0) { |
| 3820 |
outb(synu[j++], tmport); |
| 3821 |
} else { |
| 3822 |
outb(synn[j++], tmport); |
| 3823 |
} |
| 3824 |
} |
| 3825 |
tmport += 0x06; |
| 3826 |
} |
| 3827 |
} |
| 3828 |
tmport -= 0x08; |
| 3829 |
while ((inb(tmport) & 0x80) == 0x00) |
| 3830 |
cpu_relax(); |
| 3831 |
j = inb(tmport) & 0x0f; |
| 3832 |
if (j == 0x0f) { |
| 3833 |
goto phase_ins; |
| 3834 |
} |
| 3835 |
if (j == 0x0a) { |
| 3836 |
goto phase_cmds; |
| 3837 |
} |
| 3838 |
if (j == 0x0e) { |
| 3839 |
goto try_sync; |
| 3840 |
} |
| 3841 |
continue; |
| 3842 |
phase_outs: |
| 3843 |
tmport = wkport + 0x18; |
| 3844 |
outb(0x20, tmport); |
| 3845 |
tmport += 0x07; |
| 3846 |
while ((inb(tmport) & 0x80) == 0x00) { |
| 3847 |
if ((inb(tmport) & 0x01) != 0x00) { |
| 3848 |
tmport -= 0x06; |
| 3849 |
outb(0x00, tmport); |
| 3850 |
tmport += 0x06; |
| 3851 |
} |
| 3852 |
cpu_relax(); |
| 3853 |
} |
| 3854 |
tmport -= 0x08; |
| 3855 |
j = inb(tmport); |
| 3856 |
if (j == 0x85) { |
| 3857 |
goto tar_dcons; |
| 3858 |
} |
| 3859 |
j &= 0x0f; |
| 3860 |
if (j == 0x0f) { |
| 3861 |
goto phase_ins; |
| 3862 |
} |
| 3863 |
if (j == 0x0a) { |
| 3864 |
goto phase_cmds; |
| 3865 |
} |
| 3866 |
if (j == 0x0e) { |
| 3867 |
goto phase_outs; |
| 3868 |
} |
| 3869 |
continue; |
| 3870 |
phase_ins: |
| 3871 |
tmport = wkport + 0x14; |
| 3872 |
outb(0x06, tmport); |
| 3873 |
tmport += 0x04; |
| 3874 |
outb(0x20, tmport); |
| 3875 |
tmport += 0x07; |
| 3876 |
k = 0; |
| 3877 |
phase_ins1: |
| 3878 |
j = inb(tmport); |
| 3879 |
if ((j & 0x01) != 0x00) { |
| 3880 |
tmport -= 0x06; |
| 3881 |
mbuf[k++] = inb(tmport); |
| 3882 |
tmport += 0x06; |
| 3883 |
goto phase_ins1; |
| 3884 |
} |
| 3885 |
if ((j & 0x80) == 0x00) { |
| 3886 |
goto phase_ins1; |
| 3887 |
} |
| 3888 |
tmport -= 0x08; |
| 3889 |
while ((inb(tmport) & 0x80) == 0x00); |
| 3890 |
j = inb(tmport); |
| 3891 |
if (j == 0x85) { |
| 3892 |
goto tar_dcons; |
| 3893 |
} |
| 3894 |
j &= 0x0f; |
| 3895 |
if (j == 0x0f) { |
| 3896 |
goto phase_ins; |
| 3897 |
} |
| 3898 |
if (j == 0x0a) { |
| 3899 |
goto phase_cmds; |
| 3900 |
} |
| 3901 |
if (j == 0x0e) { |
| 3902 |
goto phase_outs; |
| 3903 |
} |
| 3904 |
continue; |
| 3905 |
phase_cmds: |
| 3906 |
tmport = wkport + 0x10; |
| 3907 |
outb(0x30, tmport); |
| 3908 |
tar_dcons: |
| 3909 |
tmport = wkport + 0x14; |
| 3910 |
outb(0x00, tmport); |
| 3911 |
tmport += 0x04; |
| 3912 |
outb(0x08, tmport); |
| 3913 |
tmport += 0x07; |
| 3914 |
while ((inb(tmport) & 0x80) == 0x00) |
| 3915 |
cpu_relax(); |
| 3916 |
tmport -= 0x08; |
| 3917 |
j = inb(tmport); |
| 3918 |
if (j != 0x16) { |
| 3919 |
continue; |
| 3920 |
} |
| 3921 |
if (mbuf[0] != 0x01) { |
| 3922 |
continue; |
| 3923 |
} |
| 3924 |
if (mbuf[1] != 0x03) { |
| 3925 |
continue; |
| 3926 |
} |
| 3927 |
if (mbuf[4] == 0x00) { |
| 3928 |
continue; |
| 3929 |
} |
| 3930 |
if (mbuf[3] > 0x64) { |
| 3931 |
continue; |
| 3932 |
} |
| 3933 |
if (mbuf[4] > 0x0e) { |
| 3934 |
mbuf[4] = 0x0e; |
| 3935 |
} |
| 3936 |
dev->id[c][i].devsp = mbuf[4]; |
| 3937 |
if (mbuf[3] < 0x0c){ |
| 3938 |
j = 0xb0; |
| 3939 |
goto set_syn_ok; |
| 3940 |
} |
| 3941 |
if ((mbuf[3] < 0x0d) && (rmb == 0)) { |
| 3942 |
j = 0xa0; |
| 3943 |
goto set_syn_ok; |
| 3944 |
} |
| 3945 |
if (mbuf[3] < 0x1a) { |
| 3946 |
j = 0x20; |
| 3947 |
goto set_syn_ok; |
| 3948 |
} |
| 3949 |
if (mbuf[3] < 0x33) { |
| 3950 |
j = 0x40; |
| 3951 |
goto set_syn_ok; |
| 3952 |
} |
| 3953 |
if (mbuf[3] < 0x4c) { |
| 3954 |
j = 0x50; |
| 3955 |
goto set_syn_ok; |
| 3956 |
} |
| 3957 |
j = 0x60; |
| 3958 |
set_syn_ok: |
| 3959 |
dev->id[c][i].devsp = (dev->id[c][i].devsp & 0x0f) | j; |
| 3960 |
#ifdef ED_DBGP |
| 3961 |
printk("dev->id[%2d][%2d].devsp = %2x\n",c,i,dev->id[c][i].devsp); |
| 3962 |
#endif |
| 3963 |
} |
| 3964 |
tmport = wkport + 0x16; |
| 3965 |
outb(0x80, tmport); |
| 3966 |
} |
| 3967 |
|
| 3968 |
module_init(atp870u_init); |
2731 |
module_init(atp870u_init); |
| 3969 |
module_exit(atp870u_exit); |
2732 |
module_exit(atp870u_exit); |
| 3970 |
|
2733 |
|