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
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>
10 Copyright (C) 1999-2001 3ware Inc.
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.
23 #include <linux/module.h>
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;
34 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen);
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);
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);
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);
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);
51 - printk(KERN_WARNING "3w-xxxx: Received AEN 0x%x\n", aen);
53 + printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: AEN queue overflow.\n", tw_dev->host->host_no);
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);
59 + printk(KERN_WARNING "3w-xxxx: scsi%d: AEN: %s.\n", tw_dev->host->host_no, tw_aen_string[aen & 0xff]);
62 + printk(KERN_WARNING "3w-xxxx: scsi%d: Received AEN %d.\n", tw_dev->host->host_no, aen);
67 response_que_addr = tw_dev->registers.response_que_addr;
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);
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);
85 if (command_packet->status != 0) {
86 if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
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);
93 /* We know this is a 3w-1x00, and doesn't support aen's */
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);
103 @@ -527,11 +530,11 @@
104 int tw_check_bits(u32 status_reg_value)
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);
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);
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);
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);
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);
130 } /* End tw_decode_error() */
132 /* This function will disable interrupts on the controller */
134 status_reg_value = inl(status_reg_addr);
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);
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);
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;
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;
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)
180 - imax = TW_Q_LENGTH;
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]);
190 if (tw_dev->alignment_virtual_address[i])
191 kfree(tw_dev->alignment_virtual_address[i]);
194 + for (i=0;i<TW_MAX_BOUNCEBUF;i++) {
195 if (tw_dev->bounce_buffer[i])
196 kfree(tw_dev->bounce_buffer[i]);
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]);
206 unregister_reboot_notifier(&tw_notifier);
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);
218 if (command_packet->status != 0) {
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);
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 @@
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);
244 @@ -1139,7 +1157,8 @@
246 if (command_packet->status != 0) {
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);
254 @@ -1228,7 +1247,7 @@
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);
263 @@ -1242,7 +1261,8 @@
265 if (command_packet->status != 0) {
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);
273 @@ -1267,13 +1287,13 @@
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");
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);
290 @@ -1330,7 +1350,7 @@
291 tw_state_request_start(tw_dev, &request_id);
292 error = tw_aen_read_queue(tw_dev, request_id);
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);
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);
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];
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);
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);
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);
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);
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);
337 switch (tw_dev->srb[request_id]->cmnd[0]) {
339 - dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10\n");
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");
345 - dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10\n");
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");
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);
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]);
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);
370 @@ -1458,6 +1476,7 @@
371 TW_Command *command_packet;
373 TW_Ioctl *ioctl = NULL;
374 + TW_Passthru *passthru = NULL;
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]);
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;
395 + printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
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);
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);
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;
424 + TW_Ioctl *ioctl = NULL;
425 + TW_Passthru *passthru = NULL;
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;
431 @@ -1609,16 +1650,23 @@
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");
441 - param_data = &(param->data[0]);
443 - memcpy(buff, param_data, tw_dev->ioctl_size[request_id]);
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);
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");
458 + param_data = &(param->data[0]);
459 + memcpy(buff, param_data, tw_dev->ioctl_size[request_id]);
462 } /* End tw_ioctl_complete() */
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);
473 @@ -1667,7 +1715,7 @@
474 status_reg_value = inl(status_reg_addr);
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);
482 @@ -1711,7 +1759,7 @@
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);
491 @@ -1758,14 +1806,14 @@
493 error = tw_aen_drain_queue(tw_dev);
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);
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);
508 @@ -1773,7 +1821,7 @@
509 /* Empty the response queue again */
510 error = tw_empty_response_que(tw_dev);
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);
517 @@ -1783,13 +1831,13 @@
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);
526 error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
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);
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);
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;
550 @@ -1902,10 +1950,9 @@
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);
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);
563 @@ -1943,11 +1990,11 @@
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);
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);
577 @@ -2060,13 +2107,10 @@
581 - dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_10.\n");
583 - dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_6.\n");
585 - dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught WRITE_10.\n");
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);
591 case TEST_UNIT_READY:
592 @@ -2090,7 +2134,7 @@
593 error = tw_ioctl(tw_dev, request_id);
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 @@
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);
610 @@ -2572,7 +2616,8 @@
612 if (command_packet->status != 0) {
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);
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);
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);
629 @@ -2610,9 +2655,9 @@
631 error = tw_initconnection(tw_dev, 1);
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);
636 - printk(KERN_NOTICE "3w-xxxx shutdown succeeded\n");
637 + printk(KERN_NOTICE "3w-xxxx: Shutdown complete.\n");
640 /* Re-enable interrupts */
641 @@ -2643,7 +2688,7 @@
642 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish()\n");
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;
649 tw_dev->free_tail = tw_dev->free_tail + 1;
650 @@ -2667,23 +2712,14 @@
652 /* Obtain next free request_id */
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;
658 tw_dev->free_head = tw_dev->free_head + 1;
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);
666 id = tw_dev->free_queue[tw_dev->free_head];
668 - if (tw_dev->free_head == TW_Q_LENGTH - 1) {
669 - tw_dev->free_head = TW_Q_START;
671 - tw_dev->free_head = tw_dev->free_head + 1;
674 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start(): id = %d.\n", 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
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>
685 Copyright (C) 1999-2001 3ware Inc.
688 #include <linux/types.h>
689 #include <linux/kdev_t.h>
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
726 +#define TW_AEN_STRING_MAX 0x02C
728 /* Control register bit definitions */
729 #define TW_CONTROL_CLEAR_HOST_INTERRUPT 0x00080000
730 #define TW_CONTROL_CLEAR_ATTENTION_INTERRUPT 0x00040000
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
737 /* Asynchronous Event Notification (AEN) Codes */
738 #define TW_AEN_QUEUE_EMPTY 0x0000
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
749 #define TW_MAX_SLOT 32
750 #define TW_MAX_PCI_BUSES 255
752 #define TW_MAX_AEN_TRIES 100
753 #define TW_UNIT_ONLINE 1
755 +#define TW_MAX_SECTORS 128
756 #define TW_AEN_WAIT_TIME 1000
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];
767 @@ -258,14 +302,42 @@
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 */
779 +typedef int TW_Cmd_State;
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)
789 +/* Command header for ATA pass-thru */
790 +typedef struct TAG_TW_Passthru
793 + unsigned char opcode:5;
794 + unsigned char sgloff:3;
796 + unsigned char size;
797 + unsigned char request_id;
799 + unsigned char aport:4;
800 + unsigned char host_id:4;
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];
816 typedef struct TAG_TW_Device_Extension {
817 TW_Registers registers;
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
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);
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)
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);
862 + cp->host_status = HS_ABORTED;
863 + cp->scsi_status = S_ILLEGAL;
864 + ncr_complete(np, cp);