]>
Commit | Line | Data |
---|---|---|
9f5cda77 KT |
1 | diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/3w-xxxx.c linux.21p1/drivers/scsi/3w-xxxx.c |
2 | --- linux.vanilla/drivers/scsi/3w-xxxx.c Sat Dec 29 16:57:22 2001 | |
3 | +++ linux.21p1/drivers/scsi/3w-xxxx.c Sat Dec 29 03:11:00 2001 | |
4 | @@ -4,6 +4,7 @@ | |
5 | Written By: Adam Radford <linux@3ware.com> | |
6 | Modifications By: Joel Jacobson <linux@3ware.com> | |
7 | Arnaldo Carvalho de Melo <acme@conectiva.com.br> | |
8 | + Brad Strand <linux@3ware.com> | |
9 | ||
10 | Copyright (C) 1999-2001 3ware Inc. | |
11 | ||
12 | @@ -98,6 +99,11 @@ | |
13 | Fix possible null pointer dereference in tw_aen_drain_queue() | |
14 | during initialization. | |
15 | Clear pci parity errors during initialization and during io. | |
16 | + 1.02.00.009 - Remove redundant increment in tw_state_request_start(). | |
17 | + Add ioctl support for direct ATA command passthru. | |
18 | + Add entire aen code string list. | |
19 | + 1.02.00.010 - Cleanup queueing code, fix jbod throughput. | |
20 | + Fix get_param for specific units. | |
21 | */ | |
22 | ||
23 | #include <linux/module.h> | |
24 | @@ -149,7 +155,7 @@ | |
25 | }; | |
26 | ||
27 | /* Globals */ | |
28 | -char *tw_driver_version="1.02.00.008"; | |
29 | +char *tw_driver_version="1.02.00.010"; | |
30 | TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT]; | |
31 | int tw_device_extension_count = 0; | |
32 | ||
33 | @@ -170,21 +176,17 @@ | |
34 | dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen); | |
35 | ||
36 | /* Print some useful info when certain aen codes come out */ | |
37 | - switch (aen & 0x0ff) { | |
38 | - case TW_AEN_APORT_TIMEOUT: | |
39 | - printk(KERN_WARNING "3w-xxxx: scsi%d: Received drive timeout AEN on port %d, check drive and drive cables.\n", tw_dev->host->host_no, aen >> 8); | |
40 | - break; | |
41 | - case TW_AEN_DRIVE_ERROR: | |
42 | - printk(KERN_WARNING "3w-xxxx: scsi%d: Received drive error AEN on port %d, check/replace cabling, or possible bad drive.\n", tw_dev->host->host_no, aen >> 8); | |
43 | - break; | |
44 | - case TW_AEN_SMART_FAIL: | |
45 | - printk(KERN_WARNING "3w-xxxx: scsi%d: Received S.M.A.R.T. threshold AEN on port %d, check drive/cooling, or possible bad drive.\n", tw_dev->host->host_no, aen >> 8); | |
46 | - break; | |
47 | - case TW_AEN_SBUF_FAIL: | |
48 | - printk(KERN_WARNING "3w-xxxx: scsi%d: Received SBUF integrity check failure AEN, reseat card or bad card.\n", tw_dev->host->host_no); | |
49 | - break; | |
50 | - default: | |
51 | - printk(KERN_WARNING "3w-xxxx: Received AEN 0x%x\n", aen); | |
52 | + if (aen == 0x0ff) { | |
53 | + printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: AEN queue overflow.\n", tw_dev->host->host_no); | |
54 | + } else { | |
55 | + if ((aen & 0x0ff) < TW_AEN_STRING_MAX) { | |
56 | + if ((tw_aen_string[aen & 0xff][strlen(tw_aen_string[aen & 0xff])-1]) == '#') { | |
57 | + printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s%d.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff], aen >> 8); | |
58 | + } else { | |
59 | + printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff]); | |
60 | + } | |
61 | + } else | |
62 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Received AEN %d.\n", tw_dev->host->host_no, aen); | |
63 | } | |
64 | ||
65 | tw_dev->aen_count++; | |
66 | @@ -236,7 +238,7 @@ | |
67 | response_que_addr = tw_dev->registers.response_que_addr; | |
68 | ||
69 | if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT, 15)) { | |
70 | - printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d\n", tw_device_extension_count); | |
71 | + dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d\n", tw_device_extension_count); | |
72 | return 1; | |
73 | } | |
74 | ||
75 | @@ -292,7 +294,7 @@ | |
76 | mdelay(5); | |
77 | status_reg_value = inl(status_reg_addr); | |
78 | if (tw_check_bits(status_reg_value)) { | |
79 | - printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected bits.\n"); | |
80 | + dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected bits.\n"); | |
81 | tw_decode_bits(tw_dev, status_reg_value); | |
82 | return 1; | |
83 | } | |
84 | @@ -309,7 +311,8 @@ | |
85 | if (command_packet->status != 0) { | |
86 | if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) { | |
87 | /* Bad response */ | |
88 | - printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags); | |
89 | + dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags); | |
90 | + tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit); | |
91 | return 1; | |
92 | } else { | |
93 | /* We know this is a 3w-1x00, and doesn't support aen's */ | |
94 | @@ -429,7 +432,7 @@ | |
95 | ||
96 | status_reg_value = inl(status_reg_addr); | |
97 | if (tw_check_bits(status_reg_value)) { | |
98 | - printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n"); | |
99 | + dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n"); | |
100 | tw_decode_bits(tw_dev, status_reg_value); | |
101 | return 1; | |
102 | } | |
103 | @@ -527,11 +530,11 @@ | |
104 | int tw_check_bits(u32 status_reg_value) | |
105 | { | |
106 | if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) { | |
107 | - printk(KERN_WARNING "3w-xxxx: tw_check_bits(): No expected bits (0x%x).\n", status_reg_value); | |
108 | + dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): No expected bits (0x%x).\n", status_reg_value); | |
109 | return 1; | |
110 | } | |
111 | if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0) { | |
112 | - printk(KERN_WARNING "3w-xxxx: tw_check_bits(): Found unexpected bits (0x%x).\n", status_reg_value); | |
113 | + dprintk(KERN_WARNING "3w-xxxx: tw_check_bits(): Found unexpected bits (0x%x).\n", status_reg_value); | |
114 | return 1; | |
115 | } | |
116 | ||
117 | @@ -635,9 +638,13 @@ | |
118 | case 0x51: | |
119 | printk(KERN_WARNING "3w-xxxx: scsi%d: Unrecoverable drive error on unit %d, check/replace cabling, or possible bad drive.\n", tw_dev->host->host_no, unit); | |
120 | break; | |
121 | - } | |
122 | + default: | |
123 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Controller error: status = 0x%x, flags = 0x%x, unit #%d.\n", tw_dev->host->host_no, status, flags, unit); | |
124 | + } | |
125 | break; | |
126 | - } | |
127 | + default: | |
128 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Controller error: status = 0x%x, flags = 0x%x, unit #%d.\n", tw_dev->host->host_no, status, flags, unit); | |
129 | + } | |
130 | } /* End tw_decode_error() */ | |
131 | ||
132 | /* This function will disable interrupts on the controller */ | |
133 | @@ -662,7 +669,7 @@ | |
134 | status_reg_value = inl(status_reg_addr); | |
135 | ||
136 | if (tw_check_bits(status_reg_value)) { | |
137 | - printk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 1.\n"); | |
138 | + dprintk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 1.\n"); | |
139 | tw_decode_bits(tw_dev, status_reg_value); | |
140 | return 1; | |
141 | } | |
142 | @@ -671,7 +678,7 @@ | |
143 | response_que_value = inl(response_que_addr); | |
144 | status_reg_value = inl(status_reg_addr); | |
145 | if (tw_check_bits(status_reg_value)) { | |
146 | - printk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 2.\n"); | |
147 | + dprintk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 2.\n"); | |
148 | tw_decode_bits(tw_dev, status_reg_value); | |
149 | return 1; | |
150 | } | |
151 | @@ -817,9 +824,20 @@ | |
152 | continue; | |
153 | } | |
154 | ||
155 | - /* Calculate max cmds per lun */ | |
156 | - if (tw_dev->num_units > 0) | |
157 | - tw_host->cmd_per_lun = (TW_Q_LENGTH-2)/tw_dev->num_units; | |
158 | + /* Calculate max cmds per lun, and setup queues */ | |
159 | + if (tw_dev->num_units > 0) { | |
160 | + if ((tw_dev->num_raid_five > 0) && (tw_dev->tw_pci_dev->device == TW_DEVICE_ID)) { | |
161 | + tw_host->cmd_per_lun = (TW_MAX_BOUNCEBUF-1)/tw_dev->num_units; | |
162 | + tw_dev->free_head = TW_Q_START; | |
163 | + tw_dev->free_tail = TW_MAX_BOUNCEBUF - 1; | |
164 | + tw_dev->free_wrap = TW_MAX_BOUNCEBUF - 1; | |
165 | + } else { | |
166 | + tw_host->cmd_per_lun = (TW_Q_LENGTH-1)/tw_dev->num_units; | |
167 | + tw_dev->free_head = TW_Q_START; | |
168 | + tw_dev->free_tail = TW_Q_LENGTH - 1; | |
169 | + tw_dev->free_wrap = TW_Q_LENGTH - 1; | |
170 | + } | |
171 | + } | |
172 | ||
173 | /* Register the card with the kernel SCSI layer */ | |
174 | host = scsi_register(tw_host, sizeof(TW_Device_Extension)); | |
175 | @@ -890,18 +908,19 @@ | |
176 | /* This function will free up device extension resources */ | |
177 | void tw_free_device_extension(TW_Device_Extension *tw_dev) | |
178 | { | |
179 | - int i, imax; | |
180 | - imax = TW_Q_LENGTH; | |
181 | + int i; | |
182 | ||
183 | dprintk(KERN_NOTICE "3w-xxxx: tw_free_device_extension()\n"); | |
184 | /* Free command packet and generic buffer memory */ | |
185 | - for (i=0;i<imax;i++) { | |
186 | + for (i=0;i<TW_Q_LENGTH;i++) { | |
187 | if (tw_dev->command_packet_virtual_address[i]) | |
188 | kfree(tw_dev->command_packet_virtual_address[i]); | |
189 | ||
190 | if (tw_dev->alignment_virtual_address[i]) | |
191 | kfree(tw_dev->alignment_virtual_address[i]); | |
192 | ||
193 | + } | |
194 | + for (i=0;i<TW_MAX_BOUNCEBUF;i++) { | |
195 | if (tw_dev->bounce_buffer[i]) | |
196 | kfree(tw_dev->bounce_buffer[i]); | |
197 | } | |
198 | @@ -913,7 +932,7 @@ | |
199 | int i; | |
200 | ||
201 | for (i=0;i<tw_device_extension_count;i++) { | |
202 | - printk(KERN_NOTICE "3w-xxxx: Notifying card #%d\n", i); | |
203 | + printk(KERN_NOTICE "3w-xxxx: Shutting down card %d.\n", i); | |
204 | tw_shutdown_device(tw_device_extension_list[i]); | |
205 | } | |
206 | unregister_reboot_notifier(&tw_notifier); | |
207 | @@ -972,7 +991,7 @@ | |
208 | mdelay(5); | |
209 | status_reg_value = inl(status_reg_addr); | |
210 | if (tw_check_bits(status_reg_value)) { | |
211 | - printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected bits.\n"); | |
212 | + dprintk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected bits.\n"); | |
213 | tw_decode_bits(tw_dev, status_reg_value); | |
214 | return 1; | |
215 | } | |
216 | @@ -986,7 +1005,8 @@ | |
217 | } | |
218 | if (command_packet->status != 0) { | |
219 | /* bad response */ | |
220 | - printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags); | |
221 | + dprintk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags); | |
222 | + tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit); | |
223 | return 1; | |
224 | } | |
225 | break; /* Response was okay, so we exit */ | |
226 | @@ -1034,8 +1054,6 @@ | |
227 | tw_dev->num_units = 0; | |
228 | tw_dev->num_aborts = 0; | |
229 | tw_dev->num_resets = 0; | |
230 | - tw_dev->free_head = TW_Q_START; | |
231 | - tw_dev->free_tail = TW_Q_LENGTH - 1; | |
232 | tw_dev->posted_request_count = 0; | |
233 | tw_dev->max_posted_request_count = 0; | |
234 | tw_dev->max_sgl_entries = 0; | |
235 | @@ -1125,7 +1143,7 @@ | |
236 | mdelay(5); | |
237 | status_reg_value = inl(status_reg_addr); | |
238 | if (tw_check_bits(status_reg_value)) { | |
239 | - printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n"); | |
240 | + dprintk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n"); | |
241 | tw_decode_bits(tw_dev, status_reg_value); | |
242 | return 1; | |
243 | } | |
244 | @@ -1139,7 +1157,8 @@ | |
245 | } | |
246 | if (command_packet->status != 0) { | |
247 | /* bad response */ | |
248 | - printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags); | |
249 | + dprintk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags); | |
250 | + tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit); | |
251 | return 1; | |
252 | } | |
253 | found = 1; | |
254 | @@ -1228,7 +1247,7 @@ | |
255 | mdelay(5); | |
256 | status_reg_value = inl(status_reg_addr); | |
257 | if (tw_check_bits(status_reg_value)) { | |
258 | - printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n"); | |
259 | + dprintk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n"); | |
260 | tw_decode_bits(tw_dev, status_reg_value); | |
261 | return 1; | |
262 | } | |
263 | @@ -1242,7 +1261,8 @@ | |
264 | } | |
265 | if (command_packet->status != 0) { | |
266 | /* bad response */ | |
267 | - printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags); | |
268 | + dprintk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags); | |
269 | + tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit); | |
270 | return 1; | |
271 | } | |
272 | found = 1; | |
273 | @@ -1267,13 +1287,13 @@ | |
274 | ||
275 | /* Now allocate raid5 bounce buffers */ | |
276 | if ((num_raid_five != 0) && (tw_dev->tw_pci_dev->device == TW_DEVICE_ID)) { | |
277 | - for (i=0;i<TW_Q_LENGTH;i++) { | |
278 | - tw_allocate_memory(tw_dev, i, sizeof(TW_Sector)*128, 2); | |
279 | + for (i=0;i<TW_MAX_BOUNCEBUF;i++) { | |
280 | + tw_allocate_memory(tw_dev, i, sizeof(TW_Sector)*TW_MAX_SECTORS, 2); | |
281 | if (tw_dev->bounce_buffer[i] == NULL) { | |
282 | printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bounce buffer allocation failed.\n"); | |
283 | return 1; | |
284 | } | |
285 | - memset(tw_dev->bounce_buffer[i], 0, sizeof(TW_Sector)*128); | |
286 | + memset(tw_dev->bounce_buffer[i], 0, sizeof(TW_Sector)*TW_MAX_SECTORS); | |
287 | } | |
288 | } | |
289 | ||
290 | @@ -1330,7 +1350,7 @@ | |
291 | tw_state_request_start(tw_dev, &request_id); | |
292 | error = tw_aen_read_queue(tw_dev, request_id); | |
293 | if (error) { | |
294 | - printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Error reading aen queue.\n"); | |
295 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Error reading aen queue.\n", tw_dev->host->host_no); | |
296 | tw_dev->state[request_id] = TW_S_COMPLETED; | |
297 | tw_state_request_finish(tw_dev, request_id); | |
298 | } | |
299 | @@ -1342,7 +1362,7 @@ | |
300 | while (tw_dev->pending_request_count > 0) { | |
301 | request_id = tw_dev->pending_queue[tw_dev->pending_head]; | |
302 | if (tw_dev->state[request_id] != TW_S_PENDING) { | |
303 | - printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found request id that wasn't pending.\n"); | |
304 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Found request id that wasn't pending.\n", tw_dev->host->host_no); | |
305 | break; | |
306 | } | |
307 | if (tw_post_command_packet(tw_dev, request_id)==0) { | |
308 | @@ -1370,12 +1390,12 @@ | |
309 | command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id]; | |
310 | error = 0; | |
311 | if (command_packet->status != 0) { | |
312 | - printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, status = 0x%x, flags = 0x%x, unit = 0x%x.\n", command_packet->status, command_packet->flags, command_packet->byte3.unit); | |
313 | + dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Bad response, status = 0x%x, flags = 0x%x, unit = 0x%x.\n", command_packet->status, command_packet->flags, command_packet->byte3.unit); | |
314 | tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit); | |
315 | error = 1; | |
316 | } | |
317 | if (tw_dev->state[request_id] != TW_S_POSTED) { | |
318 | - printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Received a request id (%d) (opcode = 0x%x) that wasn't posted.\n", request_id, command_packet->byte0.opcode); | |
319 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Received a request id (%d) (opcode = 0x%x) that wasn't posted.\n", tw_dev->host->host_no, request_id, command_packet->byte0.opcode); | |
320 | error = 1; | |
321 | } | |
322 | if (TW_STATUS_ERRORS(status_reg_value)) { | |
323 | @@ -1388,24 +1408,22 @@ | |
324 | dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n"); | |
325 | error = tw_aen_complete(tw_dev, request_id); | |
326 | if (error) { | |
327 | - printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Error completing aen.\n"); | |
328 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Error completing aen.\n", tw_dev->host->host_no); | |
329 | } | |
330 | status_reg_value = inl(status_reg_addr); | |
331 | if (tw_check_bits(status_reg_value)) { | |
332 | - printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n"); | |
333 | + dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n"); | |
334 | tw_decode_bits(tw_dev, status_reg_value); | |
335 | } | |
336 | } else { | |
337 | switch (tw_dev->srb[request_id]->cmnd[0]) { | |
338 | case READ_10: | |
339 | - dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10\n"); | |
340 | case READ_6: | |
341 | - dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_6\n"); | |
342 | + dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10/READ_6\n"); | |
343 | break; | |
344 | case WRITE_10: | |
345 | - dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10\n"); | |
346 | case WRITE_6: | |
347 | - dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_6\n"); | |
348 | + dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10/WRITE_6\n"); | |
349 | break; | |
350 | case INQUIRY: | |
351 | dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught INQUIRY\n"); | |
352 | @@ -1420,7 +1438,7 @@ | |
353 | error = tw_ioctl_complete(tw_dev, request_id); | |
354 | break; | |
355 | default: | |
356 | - printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unknown scsi opcode: 0x%x.\n", tw_dev->srb[request_id]->cmnd[0]); | |
357 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x.\n", tw_dev->host->host_no, tw_dev->srb[request_id]->cmnd[0]); | |
358 | tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16); | |
359 | tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); | |
360 | } | |
361 | @@ -1438,7 +1456,7 @@ | |
362 | tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); | |
363 | status_reg_value = inl(status_reg_addr); | |
364 | if (tw_check_bits(status_reg_value)) { | |
365 | - printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n"); | |
366 | + dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n"); | |
367 | tw_decode_bits(tw_dev, status_reg_value); | |
368 | } | |
369 | } | |
370 | @@ -1458,6 +1476,7 @@ | |
371 | TW_Command *command_packet; | |
372 | u32 param_value; | |
373 | TW_Ioctl *ioctl = NULL; | |
374 | + TW_Passthru *passthru = NULL; | |
375 | int tw_aen_code; | |
376 | ||
377 | ioctl = (TW_Ioctl *)tw_dev->srb[request_id]->request_buffer; | |
378 | @@ -1506,6 +1525,7 @@ | |
379 | case TW_OP_GET_PARAM: | |
380 | dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_GET_PARAM.\n"); | |
381 | command_packet->byte0.opcode = TW_OP_GET_PARAM; | |
382 | + command_packet->byte3.unit = ioctl->unit_index; | |
383 | param->table_id = ioctl->table_id; | |
384 | param->parameter_id = ioctl->parameter_id; | |
385 | param->parameter_size_bytes = ioctl->parameter_size_bytes; | |
386 | @@ -1549,6 +1569,25 @@ | |
387 | tw_dev->srb[request_id]->result = (DID_OK << 16); | |
388 | tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]); | |
389 | return 0; | |
390 | + case TW_ATA_PASSTHRU: | |
391 | + if (ioctl->data != NULL) { | |
392 | + memcpy(command_packet, ioctl->data, sizeof(TW_Command)); | |
393 | + command_packet->request_id = request_id; | |
394 | + } else { | |
395 | + printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n"); | |
396 | + return 1; | |
397 | + } | |
398 | + | |
399 | + passthru = (TW_Passthru *)tw_dev->command_packet_virtual_address[request_id]; | |
400 | + passthru->sg_list[0].length = passthru->sector_count*512; | |
401 | + if (passthru->sg_list[0].length > TW_MAX_PASSTHRU_BYTES) { | |
402 | + printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Passthru size (%ld) too big.\n", passthru->sg_list[0].length); | |
403 | + return 1; | |
404 | + } | |
405 | + passthru->sg_list[0].address = virt_to_bus(tw_dev->alignment_virtual_address[request_id]); | |
406 | + tw_post_command_packet(tw_dev, request_id); | |
407 | + return 0; | |
408 | + | |
409 | case TW_CMD_PACKET: | |
410 | if (ioctl->data != NULL) { | |
411 | memcpy(command_packet, ioctl->data, sizeof(TW_Command)); | |
412 | @@ -1583,7 +1622,6 @@ | |
413 | command_packet->byte0.sgl_offset = 2; | |
414 | command_packet->size = 4; | |
415 | command_packet->request_id = request_id; | |
416 | - command_packet->byte3.unit = 0; | |
417 | command_packet->byte3.host_id = 0; | |
418 | command_packet->status = 0; | |
419 | command_packet->flags = 0; | |
420 | @@ -1601,7 +1639,10 @@ | |
421 | unsigned char *param_data; | |
422 | unsigned char *buff; | |
423 | TW_Param *param; | |
424 | + TW_Ioctl *ioctl = NULL; | |
425 | + TW_Passthru *passthru = NULL; | |
426 | ||
427 | + ioctl = (TW_Ioctl *)tw_dev->srb[request_id]->request_buffer; | |
428 | dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete()\n"); | |
429 | buff = tw_dev->srb[request_id]->request_buffer; | |
430 | if (buff == NULL) { | |
431 | @@ -1609,16 +1650,23 @@ | |
432 | return 1; | |
433 | } | |
434 | dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete(): Request_bufflen = %d\n", tw_dev->srb[request_id]->request_bufflen); | |
435 | - memset(buff, 0, tw_dev->srb[request_id]->request_bufflen); | |
436 | - param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; | |
437 | - if (param == NULL) { | |
438 | - printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n"); | |
439 | - return 1; | |
440 | - } | |
441 | - param_data = &(param->data[0]); | |
442 | - | |
443 | - memcpy(buff, param_data, tw_dev->ioctl_size[request_id]); | |
444 | ||
445 | + ioctl = (TW_Ioctl *)buff; | |
446 | + switch (ioctl->opcode) { | |
447 | + case TW_ATA_PASSTHRU: | |
448 | + passthru = (TW_Passthru *)ioctl->data; | |
449 | + memcpy(buff, tw_dev->alignment_virtual_address[request_id], passthru->sector_count * 512); | |
450 | + break; | |
451 | + default: | |
452 | + memset(buff, 0, tw_dev->srb[request_id]->request_bufflen); | |
453 | + param = (TW_Param *)tw_dev->alignment_virtual_address[request_id]; | |
454 | + if (param == NULL) { | |
455 | + printk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): Bad alignment virtual address.\n"); | |
456 | + return 1; | |
457 | + } | |
458 | + param_data = &(param->data[0]); | |
459 | + memcpy(buff, param_data, tw_dev->ioctl_size[request_id]); | |
460 | + } | |
461 | return 0; | |
462 | } /* End tw_ioctl_complete() */ | |
463 | ||
464 | @@ -1646,7 +1694,7 @@ | |
465 | status_reg_value = inl(status_reg_addr); | |
466 | do_gettimeofday(&timeout); | |
467 | if (before.tv_sec + seconds < timeout.tv_sec) { | |
468 | - printk(KERN_WARNING "3w-xxxx: tw_poll_status(): Flag 0x%x not found.\n", flag); | |
469 | + dprintk(KERN_WARNING "3w-xxxx: tw_poll_status(): Flag 0x%x not found.\n", flag); | |
470 | return 1; | |
471 | } | |
472 | mdelay(1); | |
473 | @@ -1667,7 +1715,7 @@ | |
474 | status_reg_value = inl(status_reg_addr); | |
475 | ||
476 | if (tw_check_bits(status_reg_value)) { | |
477 | - printk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n"); | |
478 | + dprintk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n"); | |
479 | tw_decode_bits(tw_dev, status_reg_value); | |
480 | } | |
481 | ||
482 | @@ -1711,7 +1759,7 @@ | |
483 | imax = TW_Q_LENGTH; | |
484 | ||
485 | if (tw_reset_sequence(tw_dev)) { | |
486 | - printk(KERN_WARNING "3w-xxxx: tw_reset_device_extension(): Reset sequence failed for card %d.\n", tw_dev->host->host_no); | |
487 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Reset sequence failed.\n", tw_dev->host->host_no); | |
488 | return 1; | |
489 | } | |
490 | ||
491 | @@ -1758,14 +1806,14 @@ | |
492 | ||
493 | error = tw_aen_drain_queue(tw_dev); | |
494 | if (error) { | |
495 | - printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): No attention interrupt for card %d.\n", tw_dev->host->host_no); | |
496 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Card not responding, retrying.\n", tw_dev->host->host_no); | |
497 | tries++; | |
498 | continue; | |
499 | } | |
500 | ||
501 | /* Check for controller errors */ | |
502 | if (tw_check_errors(tw_dev)) { | |
503 | - printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Controller errors found, soft resetting card %d.\n", tw_dev->host->host_no); | |
504 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors found, retrying.\n", tw_dev->host->host_no); | |
505 | tries++; | |
506 | continue; | |
507 | } | |
508 | @@ -1773,7 +1821,7 @@ | |
509 | /* Empty the response queue again */ | |
510 | error = tw_empty_response_que(tw_dev); | |
511 | if (error) { | |
512 | - printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Couldn't empty response queue for card %d.\n", tw_dev->host->host_no); | |
513 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Couldn't empty response queue, retrying.\n", tw_dev->host->host_no); | |
514 | tries++; | |
515 | continue; | |
516 | } | |
517 | @@ -1783,13 +1831,13 @@ | |
518 | } | |
519 | ||
520 | if (tries >= TW_MAX_RESET_TRIES) { | |
521 | - printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Controller error or no attention interrupt: giving up for card %d.\n", tw_dev->host->host_no); | |
522 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Controller errors, card not responding, check all cabling.\n", tw_dev->host->host_no); | |
523 | return 1; | |
524 | } | |
525 | ||
526 | error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS); | |
527 | if (error) { | |
528 | - printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Couldn't initconnection for card %d.\n", tw_dev->host->host_no); | |
529 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Connection initialization failed.\n", tw_dev->host->host_no); | |
530 | return 1; | |
531 | } | |
532 | ||
533 | @@ -1879,14 +1927,14 @@ | |
534 | for (i=0;i<TW_Q_LENGTH;i++) { | |
535 | if (tw_dev->srb[i] == SCpnt) { | |
536 | if (tw_dev->state[i] == TW_S_STARTED) { | |
537 | - printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Abort succeeded for started Scsi_Cmnd 0x%x\n", (u32)tw_dev->srb[i]); | |
538 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Command (0x%x) timed out.\n", tw_dev->host->host_no, (u32)SCpnt); | |
539 | tw_dev->state[i] = TW_S_COMPLETED; | |
540 | tw_state_request_finish(tw_dev, i); | |
541 | spin_unlock(&tw_dev->tw_lock); | |
542 | return (SUCCESS); | |
543 | } | |
544 | if (tw_dev->state[i] == TW_S_PENDING) { | |
545 | - printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Abort succeeded for pending Scsi_Cmnd 0x%x\n", (u32)tw_dev->srb[i]); | |
546 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Command (0x%x) timed out.\n", tw_dev->host->host_no, (u32)SCpnt); | |
547 | if (tw_dev->pending_head == TW_Q_LENGTH-1) { | |
548 | tw_dev->pending_head = TW_Q_START; | |
549 | } else { | |
550 | @@ -1902,10 +1950,9 @@ | |
551 | } | |
552 | ||
553 | /* If the command has already been posted, we have to reset the card */ | |
554 | - printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Abort failed for unknown Scsi_Cmnd 0x%x, resetting card %d.\n", (u32)SCpnt, tw_dev->host->host_no); | |
555 | - | |
556 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Command (0x%x) timed out, resetting card.\n", tw_dev->host->host_no, (u32)SCpnt); | |
557 | if (tw_reset_device_extension(tw_dev)) { | |
558 | - printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Reset failed for card %d.\n", tw_dev->host->host_no); | |
559 | + dprintk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Reset failed for card %d.\n", tw_dev->host->host_no); | |
560 | spin_unlock(&tw_dev->tw_lock); | |
561 | return (FAILED); | |
562 | } | |
563 | @@ -1943,11 +1990,11 @@ | |
564 | ||
565 | /* Now reset the card and some of the device extension data */ | |
566 | if (tw_reset_device_extension(tw_dev)) { | |
567 | - printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Reset failed for card %d.\n", tw_dev->host->host_no); | |
568 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Reset failed.\n", tw_dev->host->host_no); | |
569 | spin_unlock_irqrestore(&tw_dev->tw_lock, flags); | |
570 | return (FAILED); | |
571 | } | |
572 | - printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Reset succeeded for card %d.\n", tw_dev->host->host_no); | |
573 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Reset succeeded.\n", tw_dev->host->host_no); | |
574 | spin_unlock_irqrestore(&tw_dev->tw_lock, flags); | |
575 | ||
576 | return (SUCCESS); | |
577 | @@ -2060,13 +2107,10 @@ | |
578 | ||
579 | switch (*command) { | |
580 | case READ_10: | |
581 | - dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_10.\n"); | |
582 | case READ_6: | |
583 | - dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_6.\n"); | |
584 | case WRITE_10: | |
585 | - dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught WRITE_10.\n"); | |
586 | case WRITE_6: | |
587 | - dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught WRITE_6.\n"); | |
588 | + dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ/WRITE.\n"); | |
589 | error = tw_scsiop_read_write(tw_dev, request_id); | |
590 | break; | |
591 | case TEST_UNIT_READY: | |
592 | @@ -2090,7 +2134,7 @@ | |
593 | error = tw_ioctl(tw_dev, request_id); | |
594 | break; | |
595 | default: | |
596 | - printk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): Unknown scsi opcode: 0x%x\n", *command); | |
597 | + printk(KERN_NOTICE "3w-xxxx: scsi%d: Unknown scsi opcode: 0x%x\n", tw_dev->host->host_no, *command); | |
598 | tw_dev->state[request_id] = TW_S_COMPLETED; | |
599 | tw_state_request_finish(tw_dev, request_id); | |
600 | SCpnt->result = (DID_BAD_TARGET << 16); | |
601 | @@ -2558,7 +2602,7 @@ | |
602 | mdelay(5); | |
603 | status_reg_value = inl(status_reg_addr); | |
604 | if (tw_check_bits(status_reg_value)) { | |
605 | - printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected bits.\n"); | |
606 | + dprintk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected bits.\n"); | |
607 | tw_decode_bits(tw_dev, status_reg_value); | |
608 | return 1; | |
609 | } | |
610 | @@ -2572,7 +2616,8 @@ | |
611 | } | |
612 | if (command_packet->status != 0) { | |
613 | /* bad response */ | |
614 | - printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags); | |
615 | + dprintk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags); | |
616 | + tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit); | |
617 | return 1; | |
618 | } | |
619 | break; /* Response was okay, so we exit */ | |
620 | @@ -2592,7 +2637,7 @@ | |
621 | error = request_irq(tw_dev->tw_pci_dev->irq, tw_interrupt, SA_SHIRQ, device, tw_dev); | |
622 | ||
623 | if (error < 0) { | |
624 | - printk(KERN_WARNING "3w-xxxx: tw_setup_irq(): Error requesting IRQ: %d for card %d.\n", tw_dev->tw_pci_dev->irq, tw_dev->host->host_no); | |
625 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Error requesting IRQ: %d.\n", tw_dev->host->host_no, tw_dev->tw_pci_dev->irq); | |
626 | return 1; | |
627 | } | |
628 | return 0; | |
629 | @@ -2610,9 +2655,9 @@ | |
630 | /* poke the board */ | |
631 | error = tw_initconnection(tw_dev, 1); | |
632 | if (error) { | |
633 | - printk(KERN_WARNING "3w-xxxx: tw_shutdown_device(): Couldn't initconnection for card %d.\n", tw_dev->host->host_no); | |
634 | + printk(KERN_WARNING "3w-xxxx: scsi%d: Connection shutdown failed.\n", tw_dev->host->host_no); | |
635 | } else { | |
636 | - printk(KERN_NOTICE "3w-xxxx shutdown succeeded\n"); | |
637 | + printk(KERN_NOTICE "3w-xxxx: Shutdown complete.\n"); | |
638 | } | |
639 | ||
640 | /* Re-enable interrupts */ | |
641 | @@ -2643,7 +2688,7 @@ | |
642 | dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish()\n"); | |
643 | ||
644 | do { | |
645 | - if (tw_dev->free_tail == TW_Q_LENGTH-1) { | |
646 | + if (tw_dev->free_tail == tw_dev->free_wrap) { | |
647 | tw_dev->free_tail = TW_Q_START; | |
648 | } else { | |
649 | tw_dev->free_tail = tw_dev->free_tail + 1; | |
650 | @@ -2667,23 +2712,14 @@ | |
651 | ||
652 | /* Obtain next free request_id */ | |
653 | do { | |
654 | - if (tw_dev->free_head == TW_Q_LENGTH - 1) { | |
655 | + if (tw_dev->free_head == tw_dev->free_wrap) { | |
656 | tw_dev->free_head = TW_Q_START; | |
657 | } else { | |
658 | tw_dev->free_head = tw_dev->free_head + 1; | |
659 | } | |
660 | - } while ((tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_STARTED) || | |
661 | - (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_POSTED) || | |
662 | - (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_PENDING) || | |
663 | - (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_COMPLETED)); | |
664 | + } while (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] & TW_START_MASK); | |
665 | ||
666 | id = tw_dev->free_queue[tw_dev->free_head]; | |
667 | - | |
668 | - if (tw_dev->free_head == TW_Q_LENGTH - 1) { | |
669 | - tw_dev->free_head = TW_Q_START; | |
670 | - } else { | |
671 | - tw_dev->free_head = tw_dev->free_head + 1; | |
672 | - } | |
673 | ||
674 | dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start(): id = %d.\n", id); | |
675 | *request_id = id; | |
676 | diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/3w-xxxx.h linux.21p1/drivers/scsi/3w-xxxx.h | |
677 | --- linux.vanilla/drivers/scsi/3w-xxxx.h Sat Dec 29 16:57:22 2001 | |
678 | +++ linux.21p1/drivers/scsi/3w-xxxx.h Sat Dec 29 03:50:08 2001 | |
679 | @@ -4,6 +4,7 @@ | |
680 | Written By: Adam Radford <linux@3ware.com> | |
681 | Modifications By: Joel Jacobson <linux@3ware.com> | |
682 | Arnaldo Carvalho de Melo <acme@conectiva.com.br> | |
683 | + Brad Strand <linux@3ware.com> | |
684 | ||
685 | Copyright (C) 1999-2001 3ware Inc. | |
686 | ||
687 | @@ -57,6 +58,43 @@ | |
688 | #include <linux/types.h> | |
689 | #include <linux/kdev_t.h> | |
690 | ||
691 | +/* AEN strings */ | |
692 | +static char *tw_aen_string[] = { | |
693 | + "AEN queue empty", // 0x000 | |
694 | + "Soft reset occurred", // 0x001 | |
695 | + "Mirorr degraded: Unit #", // 0x002 | |
696 | + "Controller error", // 0x003 | |
697 | + "Rebuild failed: Unit #", // 0x004 | |
698 | + "Rebuild complete: Unit #", // 0x005 | |
699 | + "Incomplete unit detected: Unit #", // 0x006 | |
700 | + "Initialization complete: Unit #", // 0x007 | |
701 | + "Unclean shutdown detected: Unit #", // 0x008 | |
702 | + "ATA port timeout: Port #", // 0x009 | |
703 | + "Drive error: Port #", // 0x00A | |
704 | + "Rebuild started: Unit #", // 0x00B | |
705 | + "Initialization started: Unit #", // 0x00C | |
706 | + "Logical unit deleted: Unit #", // 0x00D | |
707 | + NULL, // 0x00E unused | |
708 | + "SMART threshold exceeded: Port #", // 0x00F | |
709 | + NULL, NULL, NULL, NULL, NULL, | |
710 | + NULL, NULL, NULL, NULL, NULL, | |
711 | + NULL, NULL, NULL, NULL, NULL, | |
712 | + NULL, NULL, // 0x010-0x020 unused | |
713 | + "ATA UDMA downgrade: Port #", // 0x021 | |
714 | + "ATA UDMA upgrade: Port #", // 0x022 | |
715 | + "Sector repair occurred: Port #", // 0x023 | |
716 | + "SBUF integrity check failure", // 0x024 | |
717 | + "Lost cached write: Port #", // 0x025 | |
718 | + "Drive ECC error detected: Port #", // 0x026 | |
719 | + "DCB checksum error: Port #", // 0x027 | |
720 | + "DCB unsupported version: Port #", // 0x028 | |
721 | + "Verify started: Unit #", // 0x029 | |
722 | + "Verify failed: Port #", // 0x02A | |
723 | + "Verify complete: Unit #" // 0x02B | |
724 | +}; | |
725 | + | |
726 | +#define TW_AEN_STRING_MAX 0x02C | |
727 | + | |
728 | /* Control register bit definitions */ | |
729 | #define TW_CONTROL_CLEAR_HOST_INTERRUPT 0x00080000 | |
730 | #define TW_CONTROL_CLEAR_ATTENTION_INTERRUPT 0x00040000 | |
731 | @@ -114,6 +152,7 @@ | |
732 | #define TW_OP_SECTOR_INFO 0x1a | |
733 | #define TW_OP_AEN_LISTEN 0x1c | |
734 | #define TW_CMD_PACKET 0x1d | |
735 | +#define TW_ATA_PASSTHRU 0x1e | |
736 | ||
737 | /* Asynchronous Event Notification (AEN) Codes */ | |
738 | #define TW_AEN_QUEUE_EMPTY 0x0000 | |
739 | @@ -137,7 +176,10 @@ | |
740 | #define TW_INIT_COMMAND_PACKET_SIZE 0x3 | |
741 | #define TW_POLL_MAX_RETRIES 20000 | |
742 | #define TW_MAX_SGL_LENGTH 62 | |
743 | -#define TW_Q_LENGTH 16 | |
744 | +#define TW_ATA_PASS_SGL_MAX 60 | |
745 | +#define TW_MAX_PASSTHRU_BYTES 4096 | |
746 | +#define TW_Q_LENGTH 256 | |
747 | +#define TW_MAX_BOUNCEBUF 16 | |
748 | #define TW_Q_START 0 | |
749 | #define TW_MAX_SLOT 32 | |
750 | #define TW_MAX_PCI_BUSES 255 | |
751 | @@ -149,6 +191,7 @@ | |
752 | #define TW_MAX_AEN_TRIES 100 | |
753 | #define TW_UNIT_ONLINE 1 | |
754 | #define TW_IN_INTR 1 | |
755 | +#define TW_MAX_SECTORS 128 | |
756 | #define TW_AEN_WAIT_TIME 1000 | |
757 | ||
758 | /* Macros */ | |
759 | @@ -222,6 +265,7 @@ | |
760 | unsigned short table_id; | |
761 | unsigned char parameter_id; | |
762 | unsigned char parameter_size_bytes; | |
763 | + unsigned char unit_index; | |
764 | unsigned char data[1]; | |
765 | } TW_Ioctl; | |
766 | ||
767 | @@ -258,14 +302,42 @@ | |
768 | int position; | |
769 | } TW_Info; | |
770 | ||
771 | -typedef enum TAG_TW_Cmd_State { | |
772 | - TW_S_INITIAL, /* Initial state */ | |
773 | - TW_S_STARTED, /* Id in use */ | |
774 | - TW_S_POSTED, /* Posted to the controller */ | |
775 | - TW_S_PENDING, /* Waiting to be posted in isr */ | |
776 | - TW_S_COMPLETED, /* Completed by isr */ | |
777 | - TW_S_FINISHED, /* I/O completely done */ | |
778 | -} TW_Cmd_State; | |
779 | +typedef int TW_Cmd_State; | |
780 | + | |
781 | +#define TW_S_INITIAL 0x1 /* Initial state */ | |
782 | +#define TW_S_STARTED 0x2 /* Id in use */ | |
783 | +#define TW_S_POSTED 0x4 /* Posted to the controller */ | |
784 | +#define TW_S_PENDING 0x8 /* Waiting to be posted in isr */ | |
785 | +#define TW_S_COMPLETED 0x10 /* Completed by isr */ | |
786 | +#define TW_S_FINISHED 0x20 /* I/O completely done */ | |
787 | +#define TW_START_MASK (TW_S_STARTED | TW_S_POSTED | TW_S_PENDING | TW_S_COMPLETED) | |
788 | + | |
789 | +/* Command header for ATA pass-thru */ | |
790 | +typedef struct TAG_TW_Passthru | |
791 | +{ | |
792 | + struct { | |
793 | + unsigned char opcode:5; | |
794 | + unsigned char sgloff:3; | |
795 | + } byte0; | |
796 | + unsigned char size; | |
797 | + unsigned char request_id; | |
798 | + struct { | |
799 | + unsigned char aport:4; | |
800 | + unsigned char host_id:4; | |
801 | + } byte3; | |
802 | + unsigned char status; | |
803 | + unsigned char flags; | |
804 | + unsigned short param; | |
805 | + unsigned short features; | |
806 | + unsigned short sector_count; | |
807 | + unsigned short sector_num; | |
808 | + unsigned short cylinder_lo; | |
809 | + unsigned short cylinder_hi; | |
810 | + unsigned char drive_head; | |
811 | + unsigned char command; | |
812 | + TW_SG_Entry sg_list[TW_ATA_PASS_SGL_MAX]; | |
813 | + unsigned char padding[12]; | |
814 | +} TW_Passthru; | |
815 | ||
816 | typedef struct TAG_TW_Device_Extension { | |
817 | TW_Registers registers; | |
818 | @@ -283,6 +355,7 @@ | |
819 | unsigned char free_queue[TW_Q_LENGTH]; | |
820 | unsigned char free_head; | |
821 | unsigned char free_tail; | |
822 | + unsigned char free_wrap; | |
823 | unsigned char pending_queue[TW_Q_LENGTH]; | |
824 | unsigned char pending_head; | |
825 | unsigned char pending_tail; | |
826 | diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/53c7,8xx.c linux.21p1/drivers/scsi/53c7,8xx.c | |
827 | --- linux.vanilla/drivers/scsi/53c7,8xx.c Sun Mar 25 17:31:30 2001 | |
828 | +++ linux.21p1/drivers/scsi/53c7,8xx.c Sat Dec 29 03:07:50 2001 | |
829 | @@ -239,6 +239,7 @@ | |
830 | #include <asm/dma.h> | |
831 | #include <asm/io.h> | |
832 | #include <asm/system.h> | |
833 | +#include <asm/processor.h> | |
834 | #include <linux/delay.h> | |
835 | #include <linux/signal.h> | |
836 | #include <linux/sched.h> | |
837 | @@ -1463,7 +1464,7 @@ | |
838 | command |= PCI_COMMAND_MASTER|PCI_COMMAND_IO; | |
839 | pci_write_config_word(pdev, PCI_COMMAND, command); | |
840 | ||
841 | - if (io_port >= 0x10000000 && is_prep ) { | |
842 | + if (io_port >= 0x10000000 && (_machine == _MACH_prep)) { | |
843 | /* Mapping on PowerPC can't handle this! */ | |
844 | unsigned long new_io_port; | |
845 | new_io_port = (io_port & 0x00FFFFFF) | 0x01000000; | |
846 | diff -u --new-file --recursive --exclude-from /usr/src/exclude linux.vanilla/drivers/scsi/sym53c8xx.c linux.21p1/drivers/scsi/sym53c8xx.c | |
847 | --- linux.vanilla/drivers/scsi/sym53c8xx.c Sat Dec 29 16:57:23 2001 | |
848 | +++ linux.21p1/drivers/scsi/sym53c8xx.c Sat Dec 29 03:17:07 2001 | |
849 | @@ -10125,14 +10125,13 @@ | |
850 | if (i >= MAX_START*2) | |
851 | i = 0; | |
852 | } | |
853 | - assert(k != -1); | |
854 | - if (k != 1) { | |
855 | + if (k != -1) { | |
856 | np->squeue[k] = np->squeue[i]; /* Idle task */ | |
857 | np->squeueput = k; /* Start queue pointer */ | |
858 | - cp->host_status = HS_ABORTED; | |
859 | - cp->scsi_status = S_ILLEGAL; | |
860 | - ncr_complete(np, cp); | |
861 | } | |
862 | + cp->host_status = HS_ABORTED; | |
863 | + cp->scsi_status = S_ILLEGAL; | |
864 | + ncr_complete(np, cp); | |
865 | } | |
866 | break; | |
867 | /* |