]> git.pld-linux.org Git - packages/kernel.git/blame - 2.2.21-pre2_sym53x8xx.patch
- CAN-2003-0985 fix from Linux 2.4.24 (apply before grsec)
[packages/kernel.git] / 2.2.21-pre2_sym53x8xx.patch
CommitLineData
9f5cda77
KT
1diff -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;
676diff -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;
826diff -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;
846diff -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 /*
This page took 3.078427 seconds and 4 git commands to generate.