File: /usr/src/linux/drivers/scsi/3w-xxxx.c
1 /*
2 3w-xxxx.c -- 3ware Storage Controller device driver for Linux.
3
4 Written By: Adam Radford <linux@3ware.com>
5 Modifications By: Joel Jacobson <linux@3ware.com>
6 Arnaldo Carvalho de Melo <acme@conectiva.com.br>
7
8 Copyright (C) 1999-2001 3ware Inc.
9
10 Kernel compatablity By: Andre Hedrick <andre@suse.com>
11 Non-Copyright (C) 2000 Andre Hedrick <andre@suse.com>
12
13 Further tiny build fixes and trivial hoovering Alan Cox
14
15 This program is free software; you can redistribute it and/or modify
16 it under the terms of the GNU General Public License as published by
17 the Free Software Foundation; version 2 of the License.
18
19 This program is distributed in the hope that it will be useful,
20 but WITHOUT ANY WARRANTY; without even the implied warranty of
21 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 GNU General Public License for more details.
23
24 NO WARRANTY
25 THE PROGRAM IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OR
26 CONDITIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED INCLUDING, WITHOUT
27 LIMITATION, ANY WARRANTIES OR CONDITIONS OF TITLE, NON-INFRINGEMENT,
28 MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Each Recipient is
29 solely responsible for determining the appropriateness of using and
30 distributing the Program and assumes all risks associated with its
31 exercise of rights under this Agreement, including but not limited to
32 the risks and costs of program errors, damage to or loss of data,
33 programs or equipment, and unavailability or interruption of operations.
34
35 DISCLAIMER OF LIABILITY
36 NEITHER RECIPIENT NOR ANY CONTRIBUTORS SHALL HAVE ANY LIABILITY FOR ANY
37 DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
38 DAMAGES (INCLUDING WITHOUT LIMITATION LOST PROFITS), HOWEVER CAUSED AND
39 ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
40 TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
41 USE OR DISTRIBUTION OF THE PROGRAM OR THE EXERCISE OF ANY RIGHTS GRANTED
42 HEREUNDER, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGES
43
44 You should have received a copy of the GNU General Public License
45 along with this program; if not, write to the Free Software
46 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
47
48 Bugs/Comments/Suggestions should be mailed to:
49 linux@3ware.com
50
51 For more information, goto:
52 http://www.3ware.com
53
54 History
55 -------
56 0.1.000 - Initial release.
57 0.4.000 - Added support for Asynchronous Event Notification through
58 ioctls for 3DM.
59 1.0.000 - Added DPO & FUA bit support for WRITE_10 & WRITE_6 cdb
60 to disable drive write-cache before writes.
61 1.1.000 - Fixed performance bug with DPO & FUA not existing for WRITE_6.
62 1.2.000 - Added support for clean shutdown notification/feature table.
63 1.02.00.001 - Added support for full command packet posts through ioctls
64 for 3DM.
65 Bug fix so hot spare drives don't show up.
66 1.02.00.002 - Fix bug with tw_setfeature() call that caused oops on some
67 systems.
68 08/21/00 - release previously allocated resources on failure at
69 tw_allocate_memory (acme)
70 1.02.00.003 - Fix tw_interrupt() to report error to scsi layer when
71 controller status is non-zero.
72 Added handling of request_sense opcode.
73 Fix possible null pointer dereference in
74 tw_reset_device_extension()
75 1.02.00.004 - Add support for device id of 3ware 7000 series controllers.
76 Make tw_setfeature() call with interrupts disabled.
77 Register interrupt handler before enabling interrupts.
78 Clear attention interrupt before draining aen queue.
79 1.02.00.005 - Allocate bounce buffers and custom queue depth for raid5 for
80 6000 and 5000 series controllers.
81 Reduce polling mdelays causing problems on some systems.
82 Fix use_sg = 1 calculation bug.
83 Check for scsi_register returning NULL.
84 Add aen count to /proc/scsi/3w-xxxx.
85 Remove aen code unit masking in tw_aen_complete().
86 1.02.00.006 - Remove unit from printk in tw_scsi_eh_abort(), causing
87 possible oops.
88 Fix possible null pointer dereference in tw_scsi_queue()
89 if done function pointer was invalid.
90 1.02.00.007 - Fix possible null pointer dereferences in tw_ioctl().
91 Remove check for invalid done function pointer from
92 tw_scsi_queue().
93 1.02.00.008 - Set max sectors per io to TW_MAX_SECTORS in tw_findcards().
94 Add tw_decode_error() for printing readable error messages.
95 Print some useful information on certain aen codes.
96 Add tw_decode_bits() for interpreting status register output.
97 Make scsi_set_pci_device() for kernels >= 2.4.4
98 Fix bug where aen's could be lost before a reset.
99 Re-add spinlocks in tw_scsi_detect().
100 Fix possible null pointer dereference in tw_aen_drain_queue()
101 during initialization.
102 Clear pci parity errors during initialization and during io.
103 */
104
105 #include <linux/module.h>
106
107 MODULE_AUTHOR ("3ware Inc.");
108 MODULE_DESCRIPTION ("3ware Storage Controller Linux Driver");
109
110 #include <linux/kernel.h>
111 #include <linux/pci.h>
112 #include <linux/time.h>
113 #include <linux/proc_fs.h>
114 #include <linux/sched.h>
115 #include <linux/ioport.h>
116 #include <linux/blk.h>
117 #include <linux/hdreg.h>
118 #include <linux/string.h>
119 #include <linux/delay.h>
120 #include <linux/smp.h>
121 #include <linux/reboot.h>
122 #include <linux/spinlock.h>
123
124 #include <asm/errno.h>
125 #include <asm/io.h>
126 #include <asm/irq.h>
127 #include <asm/uaccess.h>
128
129 #define __3W_C /* let 3w-xxxx.h know it is use */
130
131 #include "sd.h"
132 #include "scsi.h"
133 #include "hosts.h"
134
135 #include "3w-xxxx.h"
136
137 static int tw_copy_info(TW_Info *info, char *fmt, ...);
138 static void tw_copy_mem_info(TW_Info *info, char *data, int len);
139 static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
140 static int tw_halt(struct notifier_block *nb, ulong event, void *buf);
141
142 /* Notifier block to get a notify on system shutdown/halt/reboot */
143 static struct notifier_block tw_notifier = {
144 tw_halt, NULL, 0
145 };
146
147 /* Globals */
148 char *tw_driver_version="1.02.00.008";
149 TW_Device_Extension *tw_device_extension_list[TW_MAX_SLOT];
150 int tw_device_extension_count = 0;
151
152 /* Functions */
153
154 /* This function will complete an aen request from the isr */
155 int tw_aen_complete(TW_Device_Extension *tw_dev, int request_id)
156 {
157 TW_Param *param;
158 unsigned short aen;
159
160 dprintk(KERN_WARNING "3w-xxxx: tw_aen_complete()\n");
161 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
162 printk(KERN_WARNING "3w-xxxx: tw_aen_complete(): Bad alignment virtual address.\n");
163 return 1;
164 }
165 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
166 aen = *(unsigned short *)(param->data);
167 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_complete(): Queue'd code 0x%x\n", aen);
168
169 /* Print some useful info when certain aen codes come out */
170 switch (aen & 0x0ff) {
171 case TW_AEN_APORT_TIMEOUT:
172 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);
173 break;
174 case TW_AEN_DRIVE_ERROR:
175 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);
176 break;
177 case TW_AEN_SMART_FAIL:
178 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);
179 break;
180 case TW_AEN_SBUF_FAIL:
181 printk(KERN_WARNING "3w-xxxx: scsi%d: Received SBUF integrity check failure AEN, reseat card or bad card.\n", tw_dev->host->host_no);
182 break;
183 default:
184 printk(KERN_WARNING "3w-xxxx: Received AEN 0x%x\n", aen);
185 }
186
187 tw_dev->aen_count++;
188
189 /* Now queue the code */
190 tw_dev->aen_queue[tw_dev->aen_tail] = aen;
191 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
192 tw_dev->aen_tail = TW_Q_START;
193 } else {
194 tw_dev->aen_tail = tw_dev->aen_tail + 1;
195 }
196 if (tw_dev->aen_head == tw_dev->aen_tail) {
197 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
198 tw_dev->aen_head = TW_Q_START;
199 } else {
200 tw_dev->aen_head = tw_dev->aen_head + 1;
201 }
202 }
203 tw_dev->state[request_id] = TW_S_COMPLETED;
204 tw_state_request_finish(tw_dev, request_id);
205
206 return 0;
207 } /* End tw_aen_complete() */
208
209 /* This function will drain the aen queue after a soft reset */
210 int tw_aen_drain_queue(TW_Device_Extension *tw_dev)
211 {
212 TW_Command *command_packet;
213 TW_Param *param;
214 int tries = 0;
215 int request_id = 0;
216 u32 command_que_value = 0, command_que_addr;
217 u32 status_reg_value = 0, status_reg_addr;
218 u32 param_value;
219 TW_Response_Queue response_queue;
220 u32 response_que_addr;
221 unsigned short aen;
222 unsigned short aen_code;
223 int finished = 0;
224 int first_reset = 0;
225 int queue = 0;
226 int imax, i;
227 int found = 0;
228
229 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue()\n");
230
231 command_que_addr = tw_dev->registers.command_que_addr;
232 status_reg_addr = tw_dev->registers.status_reg_addr;
233 response_que_addr = tw_dev->registers.response_que_addr;
234
235 if (tw_poll_status(tw_dev, TW_STATUS_ATTENTION_INTERRUPT, 15)) {
236 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): No attention interrupt for card %d.\n", tw_device_extension_count);
237 return 1;
238 }
239
240 /* Initialize command packet */
241 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
242 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet virtual address.\n");
243 return 1;
244 }
245 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
246 memset(command_packet, 0, sizeof(TW_Sector));
247 command_packet->byte0.opcode = TW_OP_GET_PARAM;
248 command_packet->byte0.sgl_offset = 2;
249 command_packet->size = 4;
250 command_packet->request_id = request_id;
251 command_packet->byte3.unit = 0;
252 command_packet->byte3.host_id = 0;
253 command_packet->status = 0;
254 command_packet->flags = 0;
255 command_packet->byte6.parameter_count = 1;
256 command_que_value = tw_dev->command_packet_physical_address[request_id];
257 if (command_que_value == 0) {
258 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad command packet physical address.\n");
259 return 1;
260 }
261
262 /* Now setup the param */
263 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
264 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment virtual address.\n");
265 return 1;
266 }
267 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
268 memset(param, 0, sizeof(TW_Sector));
269 param->table_id = 0x401; /* AEN table */
270 param->parameter_id = 2; /* Unit code */
271 param->parameter_size_bytes = 2;
272 param_value = tw_dev->alignment_physical_address[request_id];
273 if (param_value == 0) {
274 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad alignment physical address.\n");
275 return 1;
276 }
277 command_packet->byte8.param.sgl[0].address = param_value;
278 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
279
280 imax = TW_POLL_MAX_RETRIES;
281
282 /* Now drain the controller's aen queue */
283 do {
284 /* Post command packet */
285 outl(command_que_value, command_que_addr);
286
287 /* Now poll for completion */
288 for (i=0;i<imax;i++) {
289 mdelay(5);
290 status_reg_value = inl(status_reg_addr);
291 if (tw_check_bits(status_reg_value)) {
292 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected bits.\n");
293 tw_decode_bits(tw_dev, status_reg_value);
294 return 1;
295 }
296 if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
297 response_queue.value = inl(response_que_addr);
298 request_id = (unsigned char)response_queue.u.response_id;
299
300 if (request_id != 0) {
301 /* Unexpected request id */
302 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unexpected request id.\n");
303 return 1;
304 }
305
306 if (command_packet->status != 0) {
307 if (command_packet->flags != TW_AEN_TABLE_UNDEFINED) {
308 /* Bad response */
309 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
310 return 1;
311 } else {
312 /* We know this is a 3w-1x00, and doesn't support aen's */
313 return 0;
314 }
315 }
316
317 /* Now check the aen */
318 aen = *(unsigned short *)(param->data);
319 aen_code = (aen & 0x0ff);
320 queue = 0;
321 switch (aen_code) {
322 case TW_AEN_QUEUE_EMPTY:
323 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_QUEUE_EMPTY.\n");
324 if (first_reset != 1) {
325 continue;
326 } else {
327 finished = 1;
328 }
329 break;
330 case TW_AEN_SOFT_RESET:
331 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_SOFT_RESET.\n");
332 if (first_reset == 0) {
333 first_reset = 1;
334 } else {
335 queue = 1;
336 }
337 break;
338 case TW_AEN_DEGRADED_MIRROR:
339 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_DEGRADED_MIRROR.\n");
340 queue = 1;
341 break;
342 case TW_AEN_CONTROLLER_ERROR:
343 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_CONTROLLER_ERROR.\n");
344 queue = 1;
345 break;
346 case TW_AEN_REBUILD_FAIL:
347 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_REBUILD_FAIL.\n");
348 queue = 1;
349 break;
350 case TW_AEN_REBUILD_DONE:
351 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_REBUILD_DONE.\n");
352 queue = 1;
353 break;
354 case TW_AEN_QUEUE_FULL:
355 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_drain_queue(): Found TW_AEN_QUEUE_FULL.\n");
356 queue = 1;
357 break;
358 case TW_AEN_APORT_TIMEOUT:
359 printk(KERN_WARNING "3w-xxxx: Received drive timeout AEN on port %d, check drive and drive cables.\n", aen >> 8);
360 queue = 1;
361 break;
362 case TW_AEN_DRIVE_ERROR:
363 printk(KERN_WARNING "3w-xxxx: Received drive error AEN on port %d, check/replace cabling, or possible bad drive.\n", aen >> 8);
364 queue = 1;
365 break;
366 case TW_AEN_SMART_FAIL:
367 printk(KERN_WARNING "3w-xxxx: Received S.M.A.R.T. threshold AEN on port %d, check drive/cooling, or possible bad drive.\n", aen >> 8);
368 queue = 1;
369 break;
370 case TW_AEN_SBUF_FAIL:
371 printk(KERN_WARNING "3w-xxxx: Received SBUF integrity check failure AEN, reseat card or bad card.\n");
372 queue = 1;
373 break;
374 default:
375 dprintk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Unknown AEN code 0x%x.\n", aen_code);
376 queue = 1;
377 }
378
379 /* Now put the aen on the aen_queue */
380 if (queue == 1) {
381 tw_dev->aen_queue[tw_dev->aen_tail] = aen_code;
382 if (tw_dev->aen_tail == TW_Q_LENGTH - 1) {
383 tw_dev->aen_tail = TW_Q_START;
384 } else {
385 tw_dev->aen_tail = tw_dev->aen_tail + 1;
386 }
387 if (tw_dev->aen_head == tw_dev->aen_tail) {
388 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
389 tw_dev->aen_head = TW_Q_START;
390 } else {
391 tw_dev->aen_head = tw_dev->aen_head + 1;
392 }
393 }
394 }
395 found = 1;
396 break;
397 }
398 }
399 if (found == 0) {
400 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Response never received.\n");
401 return 1;
402 }
403 tries++;
404 } while ((tries < TW_MAX_AEN_TRIES) && (finished == 0));
405
406 if (tries >=TW_MAX_AEN_TRIES) {
407 printk(KERN_WARNING "3w-xxxx: tw_aen_drain_queue(): Aen queue error.\n");
408 return 1;
409 }
410
411 return 0;
412 } /* End tw_aen_drain_queue() */
413
414 /* This function will read the aen queue from the isr */
415 int tw_aen_read_queue(TW_Device_Extension *tw_dev, int request_id)
416 {
417 TW_Command *command_packet;
418 TW_Param *param;
419 u32 command_que_value = 0, command_que_addr;
420 u32 status_reg_value = 0, status_reg_addr;
421 u32 param_value = 0;
422
423 dprintk(KERN_NOTICE "3w-xxxx: tw_aen_read_queue()\n");
424 command_que_addr = tw_dev->registers.command_que_addr;
425 status_reg_addr = tw_dev->registers.status_reg_addr;
426
427 status_reg_value = inl(status_reg_addr);
428 if (tw_check_bits(status_reg_value)) {
429 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Unexpected bits.\n");
430 tw_decode_bits(tw_dev, status_reg_value);
431 return 1;
432 }
433 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
434 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet virtual address.\n");
435 return 1;
436 }
437 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
438 memset(command_packet, 0, sizeof(TW_Sector));
439 command_packet->byte0.opcode = TW_OP_GET_PARAM;
440 command_packet->byte0.sgl_offset = 2;
441 command_packet->size = 4;
442 command_packet->request_id = request_id;
443 command_packet->byte3.unit = 0;
444 command_packet->byte3.host_id = 0;
445 command_packet->status = 0;
446 command_packet->flags = 0;
447 command_packet->byte6.parameter_count = 1;
448 command_que_value = tw_dev->command_packet_physical_address[request_id];
449 if (command_que_value == 0) {
450 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad command packet physical address.\n");
451 return 1;
452 }
453 /* Now setup the param */
454 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
455 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment virtual address.\n");
456 return 1;
457 }
458 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
459 memset(param, 0, sizeof(TW_Sector));
460 param->table_id = 0x401; /* AEN table */
461 param->parameter_id = 2; /* Unit code */
462 param->parameter_size_bytes = 2;
463 param_value = tw_dev->alignment_physical_address[request_id];
464 if (param_value == 0) {
465 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Bad alignment physical address.\n");
466 return 1;
467 }
468 command_packet->byte8.param.sgl[0].address = param_value;
469 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
470
471 /* Now post the command packet */
472 if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
473 dprintk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post succeeded.\n");
474 tw_dev->srb[request_id] = 0; /* Flag internal command */
475 tw_dev->state[request_id] = TW_S_POSTED;
476 outl(command_que_value, command_que_addr);
477 } else {
478 printk(KERN_WARNING "3w-xxxx: tw_aen_read_queue(): Post failed, will retry.\n");
479 return 1;
480 }
481
482 return 0;
483 } /* End tw_aen_read_queue() */
484
485 /* This function will allocate memory and check if it is 16 d-word aligned */
486 int tw_allocate_memory(TW_Device_Extension *tw_dev, int request_id, int size, int which)
487 {
488 u32 *virt_addr = kmalloc(size, GFP_ATOMIC);
489
490 dprintk(KERN_NOTICE "3w-xxxx: tw_allocate_memory()\n");
491
492 if (!virt_addr) {
493 printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): kmalloc() failed.\n");
494 return 1;
495 }
496
497 if ((u32)virt_addr % TW_ALIGNMENT) {
498 kfree(virt_addr);
499 printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): Found unaligned address.\n");
500 return 1;
501 }
502
503 switch(which) {
504 case 0:
505 tw_dev->command_packet_virtual_address[request_id] = virt_addr;
506 tw_dev->command_packet_physical_address[request_id] = virt_to_bus(virt_addr);
507 break;
508 case 1:
509 tw_dev->alignment_virtual_address[request_id] = virt_addr;
510 tw_dev->alignment_physical_address[request_id] = virt_to_bus(virt_addr);
511 break;
512 case 2:
513 tw_dev->bounce_buffer[request_id] = virt_addr;
514 break;
515 default:
516 printk(KERN_WARNING "3w-xxxx: tw_allocate_memory(): case slip in tw_allocate_memory()\n");
517 return 1;
518 }
519 return 0;
520 } /* End tw_allocate_memory() */
521
522 /* This function will check the status register for unexpected bits */
523 int tw_check_bits(u32 status_reg_value)
524 {
525 if ((status_reg_value & TW_STATUS_EXPECTED_BITS) != TW_STATUS_EXPECTED_BITS) {
526 printk(KERN_WARNING "3w-xxxx: tw_check_bits(): No expected bits (0x%x).\n", status_reg_value);
527 return 1;
528 }
529 if ((status_reg_value & TW_STATUS_UNEXPECTED_BITS) != 0) {
530 printk(KERN_WARNING "3w-xxxx: tw_check_bits(): Found unexpected bits (0x%x).\n", status_reg_value);
531 return 1;
532 }
533
534 return 0;
535 } /* End tw_check_bits() */
536
537 /* This function will report controller error status */
538 int tw_check_errors(TW_Device_Extension *tw_dev)
539 {
540 u32 status_reg_addr, status_reg_value;
541
542 status_reg_addr = tw_dev->registers.status_reg_addr;
543 status_reg_value = inl(status_reg_addr);
544
545 if (TW_STATUS_ERRORS(status_reg_value) || tw_check_bits(status_reg_value))
546 return 1;
547
548 return 0;
549 } /* End tw_check_errors() */
550
551 /* This function will clear the attention interrupt */
552 void tw_clear_attention_interrupt(TW_Device_Extension *tw_dev)
553 {
554 u32 control_reg_addr, control_reg_value;
555
556 control_reg_addr = tw_dev->registers.control_reg_addr;
557 control_reg_value = TW_CONTROL_CLEAR_ATTENTION_INTERRUPT;
558 outl(control_reg_value, control_reg_addr);
559 } /* End tw_clear_attention_interrupt() */
560
561 /* This function will clear the host interrupt */
562 void tw_clear_host_interrupt(TW_Device_Extension *tw_dev)
563 {
564 u32 control_reg_addr, control_reg_value;
565
566 control_reg_addr = tw_dev->registers.control_reg_addr;
567 control_reg_value = TW_CONTROL_CLEAR_HOST_INTERRUPT;
568 outl(control_reg_value, control_reg_addr);
569 } /* End tw_clear_host_interrupt() */
570
571 /* This function is called by tw_scsi_proc_info */
572 static int tw_copy_info(TW_Info *info, char *fmt, ...)
573 {
574 va_list args;
575 char buf[81];
576 int len;
577
578 va_start(args, fmt);
579 len = vsprintf(buf, fmt, args);
580 va_end(args);
581 tw_copy_mem_info(info, buf, len);
582 return len;
583 } /* End tw_copy_info() */
584
585 /* This function is called by tw_scsi_proc_info */
586 static void tw_copy_mem_info(TW_Info *info, char *data, int len)
587 {
588 if (info->position + len > info->length)
589 len = info->length - info->position;
590
591 if (info->position + len < info->offset) {
592 info->position += len;
593 return;
594 }
595 if (info->position < info->offset) {
596 data += (info->offset - info->position);
597 len -= (info->offset - info->position);
598 }
599 if (len > 0) {
600 memcpy(info->buffer + info->position, data, len);
601 info->position += len;
602 }
603 } /* End tw_copy_mem_info() */
604
605 /* This function will print readable messages from statsu register errors */
606 void tw_decode_bits(TW_Device_Extension *tw_dev, u32 status_reg_value)
607 {
608 dprintk(KERN_WARNING "3w-xxxx: tw_decode_bits()\n");
609 switch (status_reg_value & TW_STATUS_UNEXPECTED_BITS) {
610 case TW_STATUS_PCI_PARITY_ERROR:
611 printk(KERN_WARNING "3w-xxxx: PCI Parity Error: Reseat card, move card, or buggy device on the bus.\n");
612 outl(TW_CONTROL_CLEAR_PARITY_ERROR, tw_dev->registers.control_reg_addr);
613 pci_write_config_word(tw_dev->tw_pci_dev, PCI_STATUS, TW_PCI_CLEAR_PARITY_ERRORS);
614 break;
615 case TW_STATUS_MICROCONTROLLER_ERROR:
616 printk(KERN_WARNING "3w-xxxx: Microcontroller Error.\n");
617 break;
618 }
619 } /* End tw_decode_bits() */
620
621 /* This function will print readable messages from flags and status values */
622 void tw_decode_error(TW_Device_Extension *tw_dev, unsigned char status, unsigned char flags, unsigned char unit)
623 {
624 dprintk(KERN_WARNING "3w-xxxx: tw_decode_error()\n");
625 switch (status) {
626 case 0xc7:
627 switch (flags) {
628 case 0x1b:
629 printk(KERN_WARNING "3w-xxxx: scsi%d: Drive timeout on unit %d, check drive and drive cables.\n", tw_dev->host->host_no, unit);
630 break;
631 case 0x51:
632 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);
633 break;
634 }
635 break;
636 }
637 } /* End tw_decode_error() */
638
639 /* This function will disable interrupts on the controller */
640 void tw_disable_interrupts(TW_Device_Extension *tw_dev)
641 {
642 u32 control_reg_value, control_reg_addr;
643
644 control_reg_addr = tw_dev->registers.control_reg_addr;
645 control_reg_value = TW_CONTROL_DISABLE_INTERRUPTS;
646 outl(control_reg_value, control_reg_addr);
647 } /* End tw_disable_interrupts() */
648
649 /* This function will empty the response que */
650 int tw_empty_response_que(TW_Device_Extension *tw_dev)
651 {
652 u32 status_reg_addr, status_reg_value;
653 u32 response_que_addr, response_que_value;
654
655 status_reg_addr = tw_dev->registers.status_reg_addr;
656 response_que_addr = tw_dev->registers.response_que_addr;
657
658 status_reg_value = inl(status_reg_addr);
659
660 if (tw_check_bits(status_reg_value)) {
661 printk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 1.\n");
662 tw_decode_bits(tw_dev, status_reg_value);
663 return 1;
664 }
665
666 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
667 response_que_value = inl(response_que_addr);
668 status_reg_value = inl(status_reg_addr);
669 if (tw_check_bits(status_reg_value)) {
670 printk(KERN_WARNING "3w-xxxx: tw_empty_response_queue(): Unexpected bits 2.\n");
671 tw_decode_bits(tw_dev, status_reg_value);
672 return 1;
673 }
674 }
675 return 0;
676 } /* End tw_empty_response_que() */
677
678 /* This function will enable interrupts on the controller */
679 void tw_enable_interrupts(TW_Device_Extension *tw_dev)
680 {
681 u32 control_reg_value, control_reg_addr;
682
683 control_reg_addr = tw_dev->registers.control_reg_addr;
684 control_reg_value = (TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |
685 TW_CONTROL_UNMASK_RESPONSE_INTERRUPT |
686 TW_CONTROL_ENABLE_INTERRUPTS);
687 outl(control_reg_value, control_reg_addr);
688 } /* End tw_enable_interrupts() */
689
690 /* This function will find and initialize all cards */
691 int tw_findcards(Scsi_Host_Template *tw_host)
692 {
693 int numcards = 0, tries = 0, error = 0;
694 struct Scsi_Host *host;
695 TW_Device_Extension *tw_dev;
696 TW_Device_Extension *tw_dev2;
697 struct pci_dev *tw_pci_dev = NULL;
698 u32 status_reg_value;
699 unsigned char c = 1;
700 int i;
701 u16 device[TW_NUMDEVICES] = { TW_DEVICE_ID, TW_DEVICE_ID2 };
702
703 dprintk(KERN_NOTICE "3w-xxxx: tw_findcards()\n");
704
705 for (i=0;i<TW_NUMDEVICES;i++) {
706 while ((tw_pci_dev = pci_find_device(TW_VENDOR_ID, device[i], tw_pci_dev))) {
707 if (pci_enable_device(tw_pci_dev))
708 continue;
709 /* Prepare temporary device extension */
710 tw_dev=(TW_Device_Extension *)kmalloc(sizeof(TW_Device_Extension), GFP_ATOMIC);
711 if (tw_dev == NULL) {
712 printk(KERN_WARNING "3w-xxxx: tw_findcards(): kmalloc() failed for card %d.\n", numcards);
713 continue;
714 }
715 memset(tw_dev, 0, sizeof(TW_Device_Extension));
716
717 error = tw_initialize_device_extension(tw_dev);
718 if (error) {
719 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initialize device extension for card %d.\n", numcards);
720 tw_free_device_extension(tw_dev);
721 kfree(tw_dev);
722 continue;
723 }
724
725 /* Calculate the cards register addresses */
726 tw_dev->registers.base_addr = pci_resource_start(tw_pci_dev, 0);
727 tw_dev->registers.control_reg_addr = pci_resource_start(tw_pci_dev, 0);
728 tw_dev->registers.status_reg_addr = pci_resource_start(tw_pci_dev, 0) + 0x4;
729 tw_dev->registers.command_que_addr = pci_resource_start(tw_pci_dev, 0) + 0x8;
730 tw_dev->registers.response_que_addr = pci_resource_start(tw_pci_dev, 0) + 0xC;
731 /* Save pci_dev struct to device extension */
732 tw_dev->tw_pci_dev = tw_pci_dev;
733
734 /* Check for errors and clear them */
735 status_reg_value = inl(tw_dev->registers.status_reg_addr);
736 if (TW_STATUS_ERRORS(status_reg_value))
737 tw_decode_bits(tw_dev, status_reg_value);
738
739 /* Poll status register for 60 secs for 'Controller Ready' flag */
740 if (tw_poll_status(tw_dev, TW_STATUS_MICROCONTROLLER_READY, 60)) {
741 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Microcontroller not ready for card %d.\n", numcards);
742 tw_free_device_extension(tw_dev);
743 kfree(tw_dev);
744 continue;
745 }
746
747 /* Disable interrupts on the card */
748 tw_disable_interrupts(tw_dev);
749
750 while (tries < TW_MAX_RESET_TRIES) {
751 /* Do soft reset */
752 tw_soft_reset(tw_dev);
753
754 error = tw_aen_drain_queue(tw_dev);
755 if (error) {
756 printk(KERN_WARNING "3w-xxxx: tw_findcards(): No attention interrupt for card %d.\n", numcards);
757 tries++;
758 continue;
759 }
760
761 /* Check for controller errors */
762 if (tw_check_errors(tw_dev)) {
763 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Controller errors found, soft resetting card %d.\n", numcards);
764 tries++;
765 continue;
766 }
767
768 /* Empty the response queue */
769 error = tw_empty_response_que(tw_dev);
770 if (error) {
771 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't empty response queue for card %d.\n", numcards);
772 tries++;
773 continue;
774 }
775
776 /* Now the controller is in a good state */
777 break;
778 }
779
780 if (tries >= TW_MAX_RESET_TRIES) {
781 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Controller error or no attention interrupt: giving up for card %d.\n", numcards);
782 tw_free_device_extension(tw_dev);
783 kfree(tw_dev);
784 continue;
785 }
786
787 /* Make sure that io region isn't already taken */
788 if (check_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE)) {
789 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't get io range 0x%lx-0x%lx for card %d.\n",
790 (tw_dev->tw_pci_dev->resource[0].start),
791 (tw_dev->tw_pci_dev->resource[0].start) +
792 TW_IO_ADDRESS_RANGE, numcards);
793 tw_free_device_extension(tw_dev);
794 kfree(tw_dev);
795 continue;
796 }
797
798 /* Reserve the io address space */
799 request_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE, TW_DEVICE_NAME);
800 error = tw_initialize_units(tw_dev);
801 if (error) {
802 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initialize units for card %d.\n", numcards);
803 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
804 tw_free_device_extension(tw_dev);
805 kfree(tw_dev);
806 continue;
807 }
808
809 error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
810 if (error) {
811 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Couldn't initconnection for card %d.\n", numcards);
812 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
813 tw_free_device_extension(tw_dev);
814 kfree(tw_dev);
815 continue;
816 }
817
818 /* Calculate max cmds per lun */
819 if (tw_dev->num_units > 0)
820 tw_host->cmd_per_lun = (TW_Q_LENGTH-2)/tw_dev->num_units;
821
822 /* Register the card with the kernel SCSI layer */
823 host = scsi_register(tw_host, sizeof(TW_Device_Extension));
824 if (host == NULL) {
825 printk(KERN_WARNING "3w-xxxx: tw_findcards(): scsi_register() failed for card %d.\n", numcards-1);
826 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
827 tw_free_device_extension(tw_dev);
828 kfree(tw_dev);
829 continue;
830 }
831
832 /* Set max sectors per io */
833 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,7)
834 host->max_sectors = TW_MAX_SECTORS;
835 #endif
836
837 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,4)
838 scsi_set_pci_device(host, tw_pci_dev);
839 #endif
840
841 status_reg_value = inl(tw_dev->registers.status_reg_addr);
842
843 printk(KERN_NOTICE "scsi%d : Found a 3ware Storage Controller at 0x%x, IRQ: %d, P-chip: %d.%d\n", host->host_no,
844 (u32)(tw_pci_dev->resource[0].start), tw_pci_dev->irq,
845 (status_reg_value & TW_STATUS_MAJOR_VERSION_MASK) >> 28,
846 (status_reg_value & TW_STATUS_MINOR_VERSION_MASK) >> 24);
847
848 if (host->hostdata) {
849 tw_dev2 = (TW_Device_Extension *)host->hostdata;
850 memcpy(tw_dev2, tw_dev, sizeof(TW_Device_Extension));
851 tw_device_extension_list[tw_device_extension_count] = tw_dev2;
852 numcards++;
853 tw_device_extension_count = numcards;
854 tw_dev2->host = host;
855 } else {
856 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Bad scsi host data for card %d.\n", numcards-1);
857 scsi_unregister(host);
858 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
859 tw_free_device_extension(tw_dev);
860 kfree(tw_dev);
861 continue;
862 }
863
864 /* Tell the firmware we support shutdown notification*/
865 tw_setfeature(tw_dev2, 2, 1, &c);
866
867 /* Now setup the interrupt handler */
868 error = tw_setup_irq(tw_dev2);
869 if (error) {
870 printk(KERN_WARNING "3w-xxxx: tw_findcards(): Error requesting irq for card %d.\n", numcards-1);
871 scsi_unregister(host);
872 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
873
874 tw_free_device_extension(tw_dev);
875 kfree(tw_dev);
876 numcards--;
877 continue;
878 }
879
880 /* Re-enable interrupts on the card */
881 tw_enable_interrupts(tw_dev2);
882
883 /* Free the temporary device extension */
884 if (tw_dev)
885 kfree(tw_dev);
886 }
887 }
888
889 if (numcards == 0)
890 printk(KERN_WARNING "3w-xxxx: tw_findcards(): No cards found.\n");
891 else
892 register_reboot_notifier(&tw_notifier);
893
894 return numcards;
895 } /* End tw_findcards() */
896
897 /* This function will free up device extension resources */
898 void tw_free_device_extension(TW_Device_Extension *tw_dev)
899 {
900 int i, imax;
901 imax = TW_Q_LENGTH;
902
903 dprintk(KERN_NOTICE "3w-xxxx: tw_free_device_extension()\n");
904 /* Free command packet and generic buffer memory */
905 for (i=0;i<imax;i++) {
906 if (tw_dev->command_packet_virtual_address[i])
907 kfree(tw_dev->command_packet_virtual_address[i]);
908
909 if (tw_dev->alignment_virtual_address[i])
910 kfree(tw_dev->alignment_virtual_address[i]);
911
912 if (tw_dev->bounce_buffer[i])
913 kfree(tw_dev->bounce_buffer[i]);
914 }
915 } /* End tw_free_device_extension() */
916
917 /* Clean shutdown routine */
918 static int tw_halt(struct notifier_block *nb, ulong event, void *buf)
919 {
920 int i;
921
922 for (i=0;i<tw_device_extension_count;i++) {
923 printk(KERN_NOTICE "3w-xxxx: Notifying card #%d\n", i);
924 tw_shutdown_device(tw_device_extension_list[i]);
925 }
926 unregister_reboot_notifier(&tw_notifier);
927
928 return NOTIFY_OK;
929 } /* End tw_halt() */
930
931 /* This function will send an initconnection command to controller */
932 int tw_initconnection(TW_Device_Extension *tw_dev, int message_credits)
933 {
934 u32 command_que_addr, command_que_value;
935 u32 status_reg_addr, status_reg_value;
936 u32 response_que_addr;
937 TW_Command *command_packet;
938 TW_Response_Queue response_queue;
939 int request_id = 0;
940 int i = 0;
941 int imax = 0;
942
943 dprintk(KERN_NOTICE "3w-xxxx: tw_initconnection()\n");
944 command_que_addr = tw_dev->registers.command_que_addr;
945 status_reg_addr = tw_dev->registers.status_reg_addr;
946 response_que_addr = tw_dev->registers.response_que_addr;
947
948 /* Initialize InitConnection command packet */
949 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
950 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet virtual address.\n");
951 return 1;
952 }
953
954 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
955 memset(command_packet, 0, sizeof(TW_Sector));
956 command_packet->byte0.opcode = TW_OP_INIT_CONNECTION;
957 command_packet->byte0.sgl_offset = 0x0;
958 command_packet->size = TW_INIT_COMMAND_PACKET_SIZE;
959 command_packet->request_id = request_id;
960 command_packet->byte3.unit = 0x0;
961 command_packet->byte3.host_id = 0x0;
962 command_packet->status = 0x0;
963 command_packet->flags = 0x0;
964 command_packet->byte6.message_credits = message_credits;
965 command_packet->byte8.init_connection.response_queue_pointer = 0x0;
966 command_que_value = tw_dev->command_packet_physical_address[request_id];
967
968 if (command_que_value == 0) {
969 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad command packet physical address.\n");
970 return 1;
971 }
972
973 /* Send command packet to the board */
974 outl(command_que_value, command_que_addr);
975
976 /* Poll for completion */
977 imax = TW_POLL_MAX_RETRIES;
978 for (i=0;i<imax;i++) {
979 mdelay(5);
980 status_reg_value = inl(status_reg_addr);
981 if (tw_check_bits(status_reg_value)) {
982 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected bits.\n");
983 tw_decode_bits(tw_dev, status_reg_value);
984 return 1;
985 }
986 if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
987 response_queue.value = inl(response_que_addr);
988 request_id = (unsigned char)response_queue.u.response_id;
989 if (request_id != 0) {
990 /* unexpected request id */
991 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Unexpected request id.\n");
992 return 1;
993 }
994 if (command_packet->status != 0) {
995 /* bad response */
996 printk(KERN_WARNING "3w-xxxx: tw_initconnection(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
997 return 1;
998 }
999 break; /* Response was okay, so we exit */
1000 }
1001 }
1002 return 0;
1003 } /* End tw_initconnection() */
1004
1005 /* This function will initialize the fields of a device extension */
1006 int tw_initialize_device_extension(TW_Device_Extension *tw_dev)
1007 {
1008 int i, imax;
1009
1010 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_device_extension()\n");
1011 imax = TW_Q_LENGTH;
1012
1013 for (i=0; i<imax; i++) {
1014 /* Initialize command packet buffers */
1015 tw_allocate_memory(tw_dev, i, sizeof(TW_Sector), 0);
1016 if (tw_dev->command_packet_virtual_address[i] == NULL) {
1017 printk(KERN_WARNING "3w-xxxx: tw_initialize_device_extension(): Bad command packet virtual address.\n");
1018 return 1;
1019 }
1020 memset(tw_dev->command_packet_virtual_address[i], 0, sizeof(TW_Sector));
1021
1022 /* Initialize generic buffer */
1023 tw_allocate_memory(tw_dev, i, sizeof(TW_Sector), 1);
1024 if (tw_dev->alignment_virtual_address[i] == NULL) {
1025 printk(KERN_WARNING "3w-xxxx: tw_initialize_device_extension(): Bad alignment virtual address.\n");
1026 return 1;
1027 }
1028 memset(tw_dev->alignment_virtual_address[i], 0, sizeof(TW_Sector));
1029
1030 tw_dev->free_queue[i] = i;
1031 tw_dev->state[i] = TW_S_INITIAL;
1032 tw_dev->ioctl_size[i] = 0;
1033 tw_dev->aen_queue[i] = 0;
1034 }
1035
1036 for (i=0;i<TW_MAX_UNITS;i++) {
1037 tw_dev->is_unit_present[i] = 0;
1038 tw_dev->is_raid_five[i] = 0;
1039 }
1040
1041 tw_dev->num_units = 0;
1042 tw_dev->num_aborts = 0;
1043 tw_dev->num_resets = 0;
1044 tw_dev->free_head = TW_Q_START;
1045 tw_dev->free_tail = TW_Q_LENGTH - 1;
1046 tw_dev->posted_request_count = 0;
1047 tw_dev->max_posted_request_count = 0;
1048 tw_dev->max_sgl_entries = 0;
1049 tw_dev->sgl_entries = 0;
1050 tw_dev->host = NULL;
1051 tw_dev->pending_head = TW_Q_START;
1052 tw_dev->pending_tail = TW_Q_START;
1053 tw_dev->aen_head = 0;
1054 tw_dev->aen_tail = 0;
1055 tw_dev->sector_count = 0;
1056 tw_dev->max_sector_count = 0;
1057 tw_dev->aen_count = 0;
1058 tw_dev->num_raid_five = 0;
1059 spin_lock_init(&tw_dev->tw_lock);
1060 tw_dev->flags = 0;
1061 return 0;
1062 } /* End tw_initialize_device_extension() */
1063
1064 /* This function will get unit info from the controller */
1065 int tw_initialize_units(TW_Device_Extension *tw_dev)
1066 {
1067 int found = 0;
1068 unsigned char request_id = 0;
1069 TW_Command *command_packet;
1070 TW_Param *param;
1071 int i, j, imax, num_units = 0, num_raid_five = 0;
1072 u32 status_reg_addr, status_reg_value;
1073 u32 command_que_addr, command_que_value;
1074 u32 response_que_addr;
1075 TW_Response_Queue response_queue;
1076 u32 param_value;
1077 unsigned char *is_unit_present;
1078 unsigned char *raid_level;
1079
1080 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units()\n");
1081
1082 status_reg_addr = tw_dev->registers.status_reg_addr;
1083 command_que_addr = tw_dev->registers.command_que_addr;
1084 response_que_addr = tw_dev->registers.response_que_addr;
1085
1086 /* Setup the command packet */
1087 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1088 if (command_packet == NULL) {
1089 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet virtual address.\n");
1090 return 1;
1091 }
1092 memset(command_packet, 0, sizeof(TW_Sector));
1093 command_packet->byte0.opcode = TW_OP_GET_PARAM;
1094 command_packet->byte0.sgl_offset = 2;
1095 command_packet->size = 4;
1096 command_packet->request_id = request_id;
1097 command_packet->byte3.unit = 0;
1098 command_packet->byte3.host_id = 0;
1099 command_packet->status = 0;
1100 command_packet->flags = 0;
1101 command_packet->byte6.block_count = 1;
1102
1103 /* Now setup the param */
1104 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1105 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment virtual address.\n");
1106 return 1;
1107 }
1108 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1109 memset(param, 0, sizeof(TW_Sector));
1110 param->table_id = 3; /* unit summary table */
1111 param->parameter_id = 3; /* unitstatus parameter */
1112 param->parameter_size_bytes = TW_MAX_UNITS;
1113 param_value = tw_dev->alignment_physical_address[request_id];
1114 if (param_value == 0) {
1115 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment physical address.\n");
1116 return 1;
1117 }
1118
1119 command_packet->byte8.param.sgl[0].address = param_value;
1120 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1121
1122 /* Post the command packet to the board */
1123 command_que_value = tw_dev->command_packet_physical_address[request_id];
1124 if (command_que_value == 0) {
1125 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet physical address.\n");
1126 return 1;
1127 }
1128 outl(command_que_value, command_que_addr);
1129
1130 /* Poll for completion */
1131 imax = TW_POLL_MAX_RETRIES;
1132 for(i=0; i<imax; i++) {
1133 mdelay(5);
1134 status_reg_value = inl(status_reg_addr);
1135 if (tw_check_bits(status_reg_value)) {
1136 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n");
1137 tw_decode_bits(tw_dev, status_reg_value);
1138 return 1;
1139 }
1140 if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
1141 response_queue.value = inl(response_que_addr);
1142 request_id = (unsigned char)response_queue.u.response_id;
1143 if (request_id != 0) {
1144 /* unexpected request id */
1145 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected request id.\n");
1146 return 1;
1147 }
1148 if (command_packet->status != 0) {
1149 /* bad response */
1150 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
1151 return 1;
1152 }
1153 found = 1;
1154 break;
1155 }
1156 }
1157 if (found == 0) {
1158 /* response never received */
1159 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No response.\n");
1160 return 1;
1161 }
1162
1163 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1164 is_unit_present = (unsigned char *)&(param->data[0]);
1165
1166 /* Show all units present */
1167 imax = TW_MAX_UNITS;
1168 for(i=0; i<imax; i++) {
1169 if (is_unit_present[i] == 0) {
1170 tw_dev->is_unit_present[i] = FALSE;
1171 } else {
1172 if (is_unit_present[i] & TW_UNIT_ONLINE) {
1173 dprintk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): Unit %d found.\n", i);
1174 tw_dev->is_unit_present[i] = TRUE;
1175 num_units++;
1176 }
1177 }
1178 }
1179 tw_dev->num_units = num_units;
1180
1181 if (num_units == 0) {
1182 printk(KERN_NOTICE "3w-xxxx: tw_initialize_units(): No units found.\n");
1183 return 1;
1184 }
1185
1186 /* Find raid 5 arrays */
1187 for (j=0;j<TW_MAX_UNITS;j++) {
1188 if (tw_dev->is_unit_present[j] == 0)
1189 continue;
1190 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1191 if (command_packet == NULL) {
1192 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet virtual address.\n");
1193 return 1;
1194 }
1195 memset(command_packet, 0, sizeof(TW_Sector));
1196 command_packet->byte0.opcode = TW_OP_GET_PARAM;
1197 command_packet->byte0.sgl_offset = 2;
1198 command_packet->size = 4;
1199 command_packet->request_id = request_id;
1200 command_packet->byte3.unit = 0;
1201 command_packet->byte3.host_id = 0;
1202 command_packet->status = 0;
1203 command_packet->flags = 0;
1204 command_packet->byte6.block_count = 1;
1205
1206 /* Now setup the param */
1207 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1208 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment virtual address.\n");
1209 return 1;
1210 }
1211 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1212 memset(param, 0, sizeof(TW_Sector));
1213 param->table_id = 0x300+j; /* unit summary table */
1214 param->parameter_id = 0x6; /* unit descriptor */
1215 param->parameter_size_bytes = 0xc;
1216 param_value = tw_dev->alignment_physical_address[request_id];
1217 if (param_value == 0) {
1218 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad alignment physical address.\n");
1219 return 1;
1220 }
1221
1222 command_packet->byte8.param.sgl[0].address = param_value;
1223 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1224
1225 /* Post the command packet to the board */
1226 command_que_value = tw_dev->command_packet_physical_address[request_id];
1227 if (command_que_value == 0) {
1228 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad command packet physical address.\n");
1229 return 1;
1230 }
1231 outl(command_que_value, command_que_addr);
1232
1233 /* Poll for completion */
1234 imax = TW_POLL_MAX_RETRIES;
1235 for(i=0; i<imax; i++) {
1236 mdelay(5);
1237 status_reg_value = inl(status_reg_addr);
1238 if (tw_check_bits(status_reg_value)) {
1239 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected bits.\n");
1240 tw_decode_bits(tw_dev, status_reg_value);
1241 return 1;
1242 }
1243 if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
1244 response_queue.value = inl(response_que_addr);
1245 request_id = (unsigned char)response_queue.u.response_id;
1246 if (request_id != 0) {
1247 /* unexpected request id */
1248 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Unexpected request id.\n");
1249 return 1;
1250 }
1251 if (command_packet->status != 0) {
1252 /* bad response */
1253 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
1254 return 1;
1255 }
1256 found = 1;
1257 break;
1258 }
1259 }
1260 if (found == 0) {
1261 /* response never received */
1262 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): No response.\n");
1263 return 1;
1264 }
1265
1266 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1267 raid_level = (unsigned char *)&(param->data[1]);
1268 if (*raid_level == 5) {
1269 dprintk(KERN_WARNING "3w-xxxx: Found unit %d to be a raid5 unit.\n", j);
1270 tw_dev->is_raid_five[j] = 1;
1271 num_raid_five++;
1272 }
1273 }
1274 tw_dev->num_raid_five = num_raid_five;
1275
1276 /* Now allocate raid5 bounce buffers */
1277 if ((num_raid_five != 0) && (tw_dev->tw_pci_dev->device == TW_DEVICE_ID)) {
1278 for (i=0;i<TW_Q_LENGTH;i++) {
1279 tw_allocate_memory(tw_dev, i, sizeof(TW_Sector)*TW_MAX_SECTORS, 2);
1280 if (tw_dev->bounce_buffer[i] == NULL) {
1281 printk(KERN_WARNING "3w-xxxx: tw_initialize_units(): Bounce buffer allocation failed.\n");
1282 return 1;
1283 }
1284 memset(tw_dev->bounce_buffer[i], 0, sizeof(TW_Sector)*TW_MAX_SECTORS);
1285 }
1286 }
1287
1288 return 0;
1289 } /* End tw_initialize_units() */
1290
1291 /* This function is the interrupt service routine */
1292 static void tw_interrupt(int irq, void *dev_instance, struct pt_regs *regs)
1293 {
1294 int request_id;
1295 u32 status_reg_addr, status_reg_value;
1296 u32 response_que_addr;
1297 TW_Device_Extension *tw_dev = (TW_Device_Extension *)dev_instance;
1298 TW_Response_Queue response_que;
1299 int error = 0;
1300 int do_response_interrupt=0;
1301 int do_attention_interrupt=0;
1302 int do_host_interrupt=0;
1303 int do_command_interrupt=0;
1304 unsigned long flags = 0;
1305 TW_Command *command_packet;
1306 if (test_and_set_bit(TW_IN_INTR, &tw_dev->flags))
1307 return;
1308 spin_lock_irqsave(&io_request_lock, flags);
1309
1310 if (tw_dev->tw_pci_dev->irq == irq) {
1311 spin_lock(&tw_dev->tw_lock);
1312 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt()\n");
1313
1314 /* Read the registers */
1315 status_reg_addr = tw_dev->registers.status_reg_addr;
1316 response_que_addr = tw_dev->registers.response_que_addr;
1317 status_reg_value = inl(status_reg_addr);
1318
1319 /* Check which interrupt */
1320 if (status_reg_value & TW_STATUS_HOST_INTERRUPT)
1321 do_host_interrupt=1;
1322 if (status_reg_value & TW_STATUS_ATTENTION_INTERRUPT)
1323 do_attention_interrupt=1;
1324 if (status_reg_value & TW_STATUS_COMMAND_INTERRUPT)
1325 do_command_interrupt=1;
1326 if (status_reg_value & TW_STATUS_RESPONSE_INTERRUPT)
1327 do_response_interrupt=1;
1328
1329 /* Handle host interrupt */
1330 if (do_host_interrupt) {
1331 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received host interrupt.\n");
1332 tw_clear_host_interrupt(tw_dev);
1333 }
1334
1335 /* Handle attention interrupt */
1336 if (do_attention_interrupt) {
1337 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Received attention interrupt.\n");
1338 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Clearing attention interrupt.\n");
1339 tw_clear_attention_interrupt(tw_dev);
1340 tw_state_request_start(tw_dev, &request_id);
1341 error = tw_aen_read_queue(tw_dev, request_id);
1342 if (error) {
1343 printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Error reading aen queue.\n");
1344 tw_dev->state[request_id] = TW_S_COMPLETED;
1345 tw_state_request_finish(tw_dev, request_id);
1346 }
1347 }
1348
1349 /* Handle command interrupt */
1350 if (do_command_interrupt) {
1351 /* Drain as many pending commands as we can */
1352 while (tw_dev->pending_request_count > 0) {
1353 request_id = tw_dev->pending_queue[tw_dev->pending_head];
1354 if (tw_dev->state[request_id] != TW_S_PENDING) {
1355 printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found request id that wasn't pending.\n");
1356 break;
1357 }
1358 if (tw_post_command_packet(tw_dev, request_id)==0) {
1359 if (tw_dev->pending_head == TW_Q_LENGTH-1) {
1360 tw_dev->pending_head = TW_Q_START;
1361 } else {
1362 tw_dev->pending_head = tw_dev->pending_head + 1;
1363 }
1364 tw_dev->pending_request_count--;
1365 } else {
1366 break;
1367 }
1368 }
1369 /* If there are no more pending requests, we mask command interrupt */
1370 if (tw_dev->pending_request_count == 0)
1371 tw_mask_command_interrupt(tw_dev);
1372 }
1373
1374 /* Handle response interrupt */
1375 if (do_response_interrupt) {
1376 /* Drain the response queue from the board */
1377 while ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
1378 response_que.value = inl(response_que_addr);
1379 request_id = response_que.u.response_id;
1380 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1381 error = 0;
1382 if (command_packet->status != 0) {
1383 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);
1384 tw_decode_error(tw_dev, command_packet->status, command_packet->flags, command_packet->byte3.unit);
1385 error = 1;
1386 }
1387 if (tw_dev->state[request_id] != TW_S_POSTED) {
1388 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);
1389 error = 1;
1390 }
1391 if (TW_STATUS_ERRORS(status_reg_value)) {
1392 tw_decode_bits(tw_dev, status_reg_value);
1393 error = 1;
1394 }
1395 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): Response queue request id: %d.\n", request_id);
1396 /* Check for internal command */
1397 if (tw_dev->srb[request_id] == 0) {
1398 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Found internally posted command.\n");
1399 error = tw_aen_complete(tw_dev, request_id);
1400 if (error) {
1401 printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Error completing aen.\n");
1402 }
1403 status_reg_value = inl(status_reg_addr);
1404 if (tw_check_bits(status_reg_value)) {
1405 printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
1406 tw_decode_bits(tw_dev, status_reg_value);
1407 }
1408 } else {
1409 switch (tw_dev->srb[request_id]->cmnd[0]) {
1410 case READ_10:
1411 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_10\n");
1412 case READ_6:
1413 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_6\n");
1414 break;
1415 case WRITE_10:
1416 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_10\n");
1417 case WRITE_6:
1418 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught WRITE_6\n");
1419 break;
1420 case INQUIRY:
1421 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught INQUIRY\n");
1422 error = tw_scsiop_inquiry_complete(tw_dev, request_id);
1423 break;
1424 case READ_CAPACITY:
1425 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught READ_CAPACITY\n");
1426 error = tw_scsiop_read_capacity_complete(tw_dev, request_id);
1427 break;
1428 case TW_IOCTL:
1429 dprintk(KERN_NOTICE "3w-xxxx: tw_interrupt(): caught TW_IOCTL\n");
1430 error = tw_ioctl_complete(tw_dev, request_id);
1431 break;
1432 default:
1433 printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unknown scsi opcode: 0x%x.\n", tw_dev->srb[request_id]->cmnd[0]);
1434 tw_dev->srb[request_id]->result = (DID_BAD_TARGET << 16);
1435 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1436 }
1437 if (error) {
1438 /* Tell scsi layer there was an error */
1439 dprintk(KERN_WARNING "3w-xxxx: tw_interrupt(): Scsi Error.\n");
1440 tw_dev->srb[request_id]->result = (DID_RESET << 16);
1441 } else {
1442 /* Tell scsi layer command was a success */
1443 tw_dev->srb[request_id]->result = (DID_OK << 16);
1444 }
1445 tw_dev->state[request_id] = TW_S_COMPLETED;
1446 tw_state_request_finish(tw_dev, request_id);
1447 tw_dev->posted_request_count--;
1448 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1449 status_reg_value = inl(status_reg_addr);
1450 if (tw_check_bits(status_reg_value)) {
1451 printk(KERN_WARNING "3w-xxxx: tw_interrupt(): Unexpected bits.\n");
1452 tw_decode_bits(tw_dev, status_reg_value);
1453 }
1454 }
1455 }
1456 }
1457 spin_unlock(&tw_dev->tw_lock);
1458 }
1459 spin_unlock_irqrestore(&io_request_lock, flags);
1460 clear_bit(TW_IN_INTR, &tw_dev->flags);
1461 } /* End tw_interrupt() */
1462
1463 /* This function handles ioctls from userspace to the driver */
1464 int tw_ioctl(TW_Device_Extension *tw_dev, int request_id)
1465 {
1466 unsigned char opcode;
1467 int bufflen;
1468 TW_Param *param;
1469 TW_Command *command_packet;
1470 u32 param_value;
1471 TW_Ioctl *ioctl = NULL;
1472 int tw_aen_code;
1473
1474 ioctl = (TW_Ioctl *)tw_dev->srb[request_id]->request_buffer;
1475 if (ioctl == NULL) {
1476 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Request buffer NULL.\n");
1477 tw_dev->state[request_id] = TW_S_COMPLETED;
1478 tw_state_request_finish(tw_dev, request_id);
1479 tw_dev->srb[request_id]->result = (DID_OK << 16);
1480 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1481 return 0;
1482 }
1483 bufflen = tw_dev->srb[request_id]->request_bufflen;
1484
1485 /* Initialize command packet */
1486 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
1487 if (command_packet == NULL) {
1488 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad command packet virtual address.\n");
1489 tw_dev->state[request_id] = TW_S_COMPLETED;
1490 tw_state_request_finish(tw_dev, request_id);
1491 tw_dev->srb[request_id]->result = (DID_OK << 16);
1492 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1493 return 0;
1494 }
1495 memset(command_packet, 0, sizeof(TW_Sector));
1496
1497 /* Initialize param */
1498 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
1499 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment virtual address.\n");
1500 tw_dev->state[request_id] = TW_S_COMPLETED;
1501 tw_state_request_finish(tw_dev, request_id);
1502 tw_dev->srb[request_id]->result = (DID_OK << 16);
1503 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1504 return 0;
1505 }
1506 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1507 memset(param, 0, sizeof(TW_Sector));
1508
1509 dprintk(KERN_NOTICE "opcode = %d table_id = %d parameter_id = %d parameter_size_bytes = %d\n", ioctl->opcode, ioctl->table_id, ioctl->parameter_id, ioctl->parameter_size_bytes);
1510 opcode = ioctl->opcode;
1511
1512 switch (opcode) {
1513 case TW_OP_NOP:
1514 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_NOP.\n");
1515 command_packet->byte0.opcode = TW_OP_NOP;
1516 break;
1517 case TW_OP_GET_PARAM:
1518 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_GET_PARAM.\n");
1519 command_packet->byte0.opcode = TW_OP_GET_PARAM;
1520 param->table_id = ioctl->table_id;
1521 param->parameter_id = ioctl->parameter_id;
1522 param->parameter_size_bytes = ioctl->parameter_size_bytes;
1523 tw_dev->ioctl_size[request_id] = ioctl->parameter_size_bytes;
1524 dprintk(KERN_NOTICE "table_id = %d parameter_id = %d parameter_size_bytes %d\n", param->table_id, param->parameter_id, param->parameter_size_bytes);
1525 break;
1526 case TW_OP_SET_PARAM:
1527 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_SET_PARAM: table_id = %d, parameter_id = %d, parameter_size_bytes = %d.\n",
1528 ioctl->table_id, ioctl->parameter_id, ioctl->parameter_size_bytes);
1529 if (ioctl->data != NULL) {
1530 command_packet->byte0.opcode = TW_OP_SET_PARAM;
1531 param->table_id = ioctl->table_id;
1532 param->parameter_id = ioctl->parameter_id;
1533 param->parameter_size_bytes = ioctl->parameter_size_bytes;
1534 memcpy(param->data, ioctl->data, ioctl->parameter_size_bytes);
1535 break;
1536 } else {
1537 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
1538 return 1;
1539 }
1540 case TW_OP_AEN_LISTEN:
1541 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): caught TW_OP_AEN_LISTEN.\n");
1542 if (tw_dev->aen_head == tw_dev->aen_tail) {
1543 /* aen queue empty */
1544 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Aen queue empty.\n");
1545 tw_aen_code = TW_AEN_QUEUE_EMPTY;
1546 memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes);
1547 } else {
1548 /* Copy aen queue entry to request buffer */
1549 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl(): Returning aen 0x%x\n", tw_dev->aen_queue[tw_dev->aen_head]);
1550 tw_aen_code = tw_dev->aen_queue[tw_dev->aen_head];
1551 memcpy(tw_dev->srb[request_id]->request_buffer, &tw_aen_code, ioctl->parameter_size_bytes);
1552 if (tw_dev->aen_head == TW_Q_LENGTH - 1) {
1553 tw_dev->aen_head = TW_Q_START;
1554 } else {
1555 tw_dev->aen_head = tw_dev->aen_head + 1;
1556 }
1557 }
1558 tw_dev->state[request_id] = TW_S_COMPLETED;
1559 tw_state_request_finish(tw_dev, request_id);
1560 tw_dev->srb[request_id]->result = (DID_OK << 16);
1561 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1562 return 0;
1563 case TW_CMD_PACKET:
1564 if (ioctl->data != NULL) {
1565 memcpy(command_packet, ioctl->data, sizeof(TW_Command));
1566 command_packet->request_id = request_id;
1567 tw_post_command_packet(tw_dev, request_id);
1568 return 0;
1569 } else {
1570 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): ioctl->data NULL.\n");
1571 return 1;
1572 }
1573 default:
1574 printk(KERN_WARNING "3w-xxxx: Unknown ioctl 0x%x.\n", opcode);
1575 tw_dev->state[request_id] = TW_S_COMPLETED;
1576 tw_state_request_finish(tw_dev, request_id);
1577 tw_dev->srb[request_id]->result = (DID_OK << 16);
1578 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1579 return 0;
1580 }
1581
1582 param_value = tw_dev->alignment_physical_address[request_id];
1583 if (param_value == 0) {
1584 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n");
1585 tw_dev->state[request_id] = TW_S_COMPLETED;
1586 tw_state_request_finish(tw_dev, request_id);
1587 tw_dev->srb[request_id]->result = (DID_OK << 16);
1588 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
1589 }
1590
1591 command_packet->byte8.param.sgl[0].address = param_value;
1592 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
1593
1594 command_packet->byte0.sgl_offset = 2;
1595 command_packet->size = 4;
1596 command_packet->request_id = request_id;
1597 command_packet->byte3.unit = 0;
1598 command_packet->byte3.host_id = 0;
1599 command_packet->status = 0;
1600 command_packet->flags = 0;
1601 command_packet->byte6.parameter_count = 1;
1602
1603 /* Now try to post the command to the board */
1604 tw_post_command_packet(tw_dev, request_id);
1605
1606 return 0;
1607 } /* End tw_ioctl() */
1608
1609 /* This function is called by the isr to complete ioctl requests */
1610 int tw_ioctl_complete(TW_Device_Extension *tw_dev, int request_id)
1611 {
1612 unsigned char *param_data;
1613 unsigned char *buff;
1614 TW_Param *param;
1615
1616 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete()\n");
1617 buff = tw_dev->srb[request_id]->request_buffer;
1618 if (buff == NULL) {
1619 printk(KERN_WARNING "3w-xxxx: tw_ioctl_complete(): Request buffer NULL.\n");
1620 return 1;
1621 }
1622 dprintk(KERN_NOTICE "3w-xxxx: tw_ioctl_complete(): Request_bufflen = %d\n", tw_dev->srb[request_id]->request_bufflen);
1623 memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
1624 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
1625 if (param == NULL) {
1626 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
1627 return 1;
1628 }
1629 param_data = &(param->data[0]);
1630
1631 memcpy(buff, param_data, tw_dev->ioctl_size[request_id]);
1632
1633 return 0;
1634 } /* End tw_ioctl_complete() */
1635
1636 /* This function will mask the command interrupt */
1637 void tw_mask_command_interrupt(TW_Device_Extension *tw_dev)
1638 {
1639 u32 control_reg_addr, control_reg_value;
1640
1641 control_reg_addr = tw_dev->registers.control_reg_addr;
1642 control_reg_value = TW_CONTROL_MASK_COMMAND_INTERRUPT;
1643 outl(control_reg_value, control_reg_addr);
1644 } /* End tw_mask_command_interrupt() */
1645
1646 /* This function will poll the status register for a flag */
1647 int tw_poll_status(TW_Device_Extension *tw_dev, u32 flag, int seconds)
1648 {
1649 u32 status_reg_addr, status_reg_value;
1650 struct timeval before, timeout;
1651
1652 status_reg_addr = tw_dev->registers.status_reg_addr;
1653 do_gettimeofday(&before);
1654 status_reg_value = inl(status_reg_addr);
1655
1656 while ((status_reg_value & flag) != flag) {
1657 status_reg_value = inl(status_reg_addr);
1658 do_gettimeofday(&timeout);
1659 if (before.tv_sec + seconds < timeout.tv_sec) {
1660 printk(KERN_WARNING "3w-xxxx: tw_poll_status(): Flag 0x%x not found.\n", flag);
1661 return 1;
1662 }
1663 mdelay(1);
1664 }
1665 return 0;
1666 } /* End tw_poll_status() */
1667
1668 /* This function will attempt to post a command packet to the board */
1669 int tw_post_command_packet(TW_Device_Extension *tw_dev, int request_id)
1670 {
1671 u32 status_reg_addr, status_reg_value;
1672 u32 command_que_addr, command_que_value;
1673
1674 dprintk(KERN_NOTICE "3w-xxxx: tw_post_command_packet()\n");
1675 command_que_addr = tw_dev->registers.command_que_addr;
1676 command_que_value = tw_dev->command_packet_physical_address[request_id];
1677 status_reg_addr = tw_dev->registers.status_reg_addr;
1678 status_reg_value = inl(status_reg_addr);
1679
1680 if (tw_check_bits(status_reg_value)) {
1681 printk(KERN_WARNING "3w-xxxx: tw_post_command_packet(): Unexpected bits.\n");
1682 tw_decode_bits(tw_dev, status_reg_value);
1683 }
1684
1685 if ((status_reg_value & TW_STATUS_COMMAND_QUEUE_FULL) == 0) {
1686 /* We successfully posted the command packet */
1687 outl(command_que_value, command_que_addr);
1688 tw_dev->state[request_id] = TW_S_POSTED;
1689 tw_dev->posted_request_count++;
1690 if (tw_dev->posted_request_count > tw_dev->max_posted_request_count) {
1691 tw_dev->max_posted_request_count = tw_dev->posted_request_count;
1692 }
1693 } else {
1694 /* Couldn't post the command packet, so we do it in the isr */
1695 if (tw_dev->state[request_id] != TW_S_PENDING) {
1696 tw_dev->state[request_id] = TW_S_PENDING;
1697 tw_dev->pending_request_count++;
1698 if (tw_dev->pending_request_count > tw_dev->max_pending_request_count) {
1699 tw_dev->max_pending_request_count = tw_dev->pending_request_count;
1700 }
1701 tw_dev->pending_queue[tw_dev->pending_tail] = request_id;
1702 if (tw_dev->pending_tail == TW_Q_LENGTH-1) {
1703 tw_dev->pending_tail = TW_Q_START;
1704 } else {
1705 tw_dev->pending_tail = tw_dev->pending_tail + 1;
1706 }
1707 }
1708 tw_unmask_command_interrupt(tw_dev);
1709 return 1;
1710 }
1711 return 0;
1712 } /* End tw_post_command_packet() */
1713
1714 /* This function will reset a device extension */
1715 int tw_reset_device_extension(TW_Device_Extension *tw_dev)
1716 {
1717 int imax = 0;
1718 int i = 0;
1719 Scsi_Cmnd *srb;
1720
1721 dprintk(KERN_NOTICE "3w-xxxx: tw_reset_device_extension()\n");
1722 imax = TW_Q_LENGTH;
1723
1724 if (tw_reset_sequence(tw_dev)) {
1725 printk(KERN_WARNING "3w-xxxx: tw_reset_device_extension(): Reset sequence failed for card %d.\n", tw_dev->host->host_no);
1726 return 1;
1727 }
1728
1729 /* Abort all requests that are in progress */
1730 for (i=0;i<imax;i++) {
1731 if ((tw_dev->state[i] != TW_S_FINISHED) &&
1732 (tw_dev->state[i] != TW_S_INITIAL) &&
1733 (tw_dev->state[i] != TW_S_COMPLETED)) {
1734 srb = tw_dev->srb[i];
1735 if (srb != NULL) {
1736 srb = tw_dev->srb[i];
1737 srb->result = (DID_RESET << 16);
1738 tw_dev->srb[i]->scsi_done(tw_dev->srb[i]);
1739 }
1740 }
1741 }
1742
1743 /* Reset queues and counts */
1744 for (i=0;i<imax;i++) {
1745 tw_dev->free_queue[i] = i;
1746 tw_dev->state[i] = TW_S_INITIAL;
1747 }
1748 tw_dev->free_head = TW_Q_START;
1749 tw_dev->free_tail = TW_Q_LENGTH - 1;
1750 tw_dev->posted_request_count = 0;
1751 tw_dev->pending_request_count = 0;
1752 tw_dev->pending_head = TW_Q_START;
1753 tw_dev->pending_tail = TW_Q_START;
1754
1755 return 0;
1756 } /* End tw_reset_device_extension() */
1757
1758 /* This function will reset a controller */
1759 int tw_reset_sequence(TW_Device_Extension *tw_dev)
1760 {
1761 int error = 0;
1762 int tries = 0;
1763
1764 /* Disable interrupts */
1765 tw_disable_interrupts(tw_dev);
1766
1767 /* Reset the board */
1768 while (tries < TW_MAX_RESET_TRIES) {
1769 tw_soft_reset(tw_dev);
1770
1771 error = tw_aen_drain_queue(tw_dev);
1772 if (error) {
1773 printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): No attention interrupt for card %d.\n", tw_dev->host->host_no);
1774 tries++;
1775 continue;
1776 }
1777
1778 /* Check for controller errors */
1779 if (tw_check_errors(tw_dev)) {
1780 printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Controller errors found, soft resetting card %d.\n", tw_dev->host->host_no);
1781 tries++;
1782 continue;
1783 }
1784
1785 /* Empty the response queue again */
1786 error = tw_empty_response_que(tw_dev);
1787 if (error) {
1788 printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Couldn't empty response queue for card %d.\n", tw_dev->host->host_no);
1789 tries++;
1790 continue;
1791 }
1792
1793 /* Now the controller is in a good state */
1794 break;
1795 }
1796
1797 if (tries >= TW_MAX_RESET_TRIES) {
1798 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);
1799 return 1;
1800 }
1801
1802 error = tw_initconnection(tw_dev, TW_INIT_MESSAGE_CREDITS);
1803 if (error) {
1804 printk(KERN_WARNING "3w-xxxx: tw_reset_sequence(): Couldn't initconnection for card %d.\n", tw_dev->host->host_no);
1805 return 1;
1806 }
1807
1808 /* Re-enable interrupts */
1809 tw_enable_interrupts(tw_dev);
1810
1811 return 0;
1812 } /* End tw_reset_sequence() */
1813
1814 /* This funciton returns unit geometry in cylinders/heads/sectors */
1815 int tw_scsi_biosparam(Disk *disk, kdev_t dev, int geom[])
1816 {
1817 int heads, sectors, cylinders;
1818 TW_Device_Extension *tw_dev;
1819
1820 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam()\n");
1821 tw_dev = (TW_Device_Extension *)disk->device->host->hostdata;
1822
1823 heads = 64;
1824 sectors = 32;
1825 cylinders = disk->capacity / (heads * sectors);
1826
1827 if (disk->capacity >= 0x200000) {
1828 heads = 255;
1829 sectors = 63;
1830 cylinders = disk->capacity / (heads * sectors);
1831 }
1832
1833 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_biosparam(): heads = %d, sectors = %d, cylinders = %d\n", heads, sectors, cylinders);
1834 geom[0] = heads;
1835 geom[1] = sectors;
1836 geom[2] = cylinders;
1837
1838 return 0;
1839 } /* End tw_scsi_biosparam() */
1840
1841 /* This function will find and initialize any cards */
1842 int tw_scsi_detect(Scsi_Host_Template *tw_host)
1843 {
1844 int ret;
1845
1846 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_detect()\n");
1847
1848 printk(KERN_WARNING "3ware Storage Controller device driver for Linux v%s.\n", tw_driver_version);
1849
1850 /* Check if the kernel has PCI interface compiled in */
1851 if (!pci_present()) {
1852 printk(KERN_WARNING "3w-xxxx: tw_scsi_detect(): No pci interface present.\n");
1853 return 0;
1854 }
1855
1856 spin_unlock_irq(&io_request_lock);
1857 ret = tw_findcards(tw_host);
1858 spin_lock_irq(&io_request_lock);
1859
1860 return ret;
1861 } /* End tw_scsi_detect() */
1862
1863 /* This is the new scsi eh abort function */
1864 int tw_scsi_eh_abort(Scsi_Cmnd *SCpnt)
1865 {
1866 TW_Device_Extension *tw_dev=NULL;
1867 int i = 0;
1868
1869 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_eh_abort()\n");
1870
1871 if (!SCpnt) {
1872 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid Scsi_Cmnd.\n");
1873 return (FAILED);
1874 }
1875
1876 tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
1877 if (tw_dev == NULL) {
1878 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Invalid device extension.\n");
1879 return (FAILED);
1880 }
1881
1882 /* We have to let AEN requests through before the reset */
1883 spin_unlock_irq(&io_request_lock);
1884 mdelay(TW_AEN_WAIT_TIME);
1885 spin_lock_irq(&io_request_lock);
1886
1887 spin_lock(&tw_dev->tw_lock);
1888 tw_dev->num_aborts++;
1889
1890 /* If the command hasn't been posted yet, we can do the abort */
1891 for (i=0;i<TW_Q_LENGTH;i++) {
1892 if (tw_dev->srb[i] == SCpnt) {
1893 if (tw_dev->state[i] == TW_S_STARTED) {
1894 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Abort succeeded for started Scsi_Cmnd 0x%x\n", (u32)tw_dev->srb[i]);
1895 tw_dev->state[i] = TW_S_COMPLETED;
1896 tw_state_request_finish(tw_dev, i);
1897 spin_unlock(&tw_dev->tw_lock);
1898 return (SUCCESS);
1899 }
1900 if (tw_dev->state[i] == TW_S_PENDING) {
1901 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Abort succeeded for pending Scsi_Cmnd 0x%x\n", (u32)tw_dev->srb[i]);
1902 if (tw_dev->pending_head == TW_Q_LENGTH-1) {
1903 tw_dev->pending_head = TW_Q_START;
1904 } else {
1905 tw_dev->pending_head = tw_dev->pending_head + 1;
1906 }
1907 tw_dev->pending_request_count--;
1908 tw_dev->state[i] = TW_S_COMPLETED;
1909 tw_state_request_finish(tw_dev, i);
1910 spin_unlock(&tw_dev->tw_lock);
1911 return (SUCCESS);
1912 }
1913 }
1914 }
1915
1916 /* If the command has already been posted, we have to reset the card */
1917 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);
1918
1919 if (tw_reset_device_extension(tw_dev)) {
1920 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_abort(): Reset failed for card %d.\n", tw_dev->host->host_no);
1921 spin_unlock(&tw_dev->tw_lock);
1922 return (FAILED);
1923 }
1924 spin_unlock(&tw_dev->tw_lock);
1925
1926 return (SUCCESS);
1927 } /* End tw_scsi_eh_abort() */
1928
1929 /* This is the new scsi eh reset function */
1930 int tw_scsi_eh_reset(Scsi_Cmnd *SCpnt)
1931 {
1932 TW_Device_Extension *tw_dev=NULL;
1933
1934 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_eh_reset()\n");
1935
1936 if (!SCpnt) {
1937 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid Scsi_Cmnd.\n");
1938 return (FAILED);
1939 }
1940
1941 tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
1942 if (tw_dev == NULL) {
1943 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Invalid device extension.\n");
1944 return (FAILED);
1945 }
1946
1947 /* We have to let AEN requests through before the reset */
1948 spin_unlock_irq(&io_request_lock);
1949 mdelay(TW_AEN_WAIT_TIME);
1950 spin_lock_irq(&io_request_lock);
1951
1952 spin_lock(&tw_dev->tw_lock);
1953 tw_dev->num_resets++;
1954
1955 /* Now reset the card and some of the device extension data */
1956 if (tw_reset_device_extension(tw_dev)) {
1957 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Reset failed for card %d.\n", tw_dev->host->host_no);
1958 spin_unlock(&tw_dev->tw_lock);
1959 return (FAILED);
1960 }
1961 printk(KERN_WARNING "3w-xxxx: tw_scsi_eh_reset(): Reset succeeded for card %d.\n", tw_dev->host->host_no);
1962 spin_unlock(&tw_dev->tw_lock);
1963
1964 return (SUCCESS);
1965 } /* End tw_scsi_eh_reset() */
1966
1967 /* This function handles input and output from /proc/scsi/3w-xxxx/x */
1968 int tw_scsi_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout)
1969 {
1970 TW_Device_Extension *tw_dev = NULL;
1971 TW_Info info;
1972 int i;
1973 int j;
1974
1975 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_proc_info()\n");
1976
1977 /* Find the correct device extension */
1978 for (i=0;i<tw_device_extension_count;i++)
1979 if (tw_device_extension_list[i]->host->host_no == hostno)
1980 tw_dev = tw_device_extension_list[i];
1981 if (tw_dev == NULL) {
1982 printk(KERN_WARNING "3w-xxxx: tw_scsi_proc_info(): Couldn't locate device extension.\n");
1983 return (-EINVAL);
1984 }
1985
1986 info.buffer = buffer;
1987 info.length = length;
1988 info.offset = offset;
1989 info.position = 0;
1990
1991 if (inout) {
1992 /* Write */
1993 if (strncmp(buffer, "debug", 5) == 0) {
1994 printk(KERN_INFO "3w-xxxx: Posted commands:\n");
1995 for (j=0;j<TW_Q_LENGTH;j++) {
1996 if (tw_dev->state[j] == TW_S_POSTED) {
1997 TW_Command *command = (TW_Command *)tw_dev->command_packet_virtual_address[j];
1998 printk(KERN_INFO "3w-xxxx: Request_id: %d\n", j);
1999 printk(KERN_INFO "Opcode: 0x%x\n", command->byte0.opcode);
2000 printk(KERN_INFO "Block_count: 0x%x\n", command->byte6.block_count);
2001 printk(KERN_INFO "LBA: 0x%x\n", (u32)command->byte8.io.lba);
2002 printk(KERN_INFO "Physical command packet addr: 0x%x\n", tw_dev->command_packet_physical_address[j]);
2003 printk(KERN_INFO "Scsi_Cmnd: 0x%x\n", (u32)tw_dev->srb[j]);
2004 }
2005 }
2006 printk(KERN_INFO "3w-xxxx: Free_head: %3d\n", tw_dev->free_head);
2007 printk(KERN_INFO "3w-xxxx: Free_tail: %3d\n", tw_dev->free_tail);
2008 }
2009 return length;
2010 } else {
2011 /* Read */
2012 if (start) {
2013 *start = buffer;
2014 }
2015 tw_copy_info(&info, "scsi%d: 3ware Storage Controller\n", hostno);
2016 tw_copy_info(&info, "Driver version: %s\n", tw_driver_version);
2017 tw_copy_info(&info, "Current commands posted: %3d\n", tw_dev->posted_request_count);
2018 tw_copy_info(&info, "Max commands posted: %3d\n", tw_dev->max_posted_request_count);
2019 tw_copy_info(&info, "Current pending commands: %3d\n", tw_dev->pending_request_count);
2020 tw_copy_info(&info, "Max pending commands: %3d\n", tw_dev->max_pending_request_count);
2021 tw_copy_info(&info, "Last sgl length: %3d\n", tw_dev->sgl_entries);
2022 tw_copy_info(&info, "Max sgl length: %3d\n", tw_dev->max_sgl_entries);
2023 tw_copy_info(&info, "Last sector count: %3d\n", tw_dev->sector_count);
2024 tw_copy_info(&info, "Max sector count: %3d\n", tw_dev->max_sector_count);
2025 tw_copy_info(&info, "Resets: %3d\n", tw_dev->num_resets);
2026 tw_copy_info(&info, "Aborts: %3d\n", tw_dev->num_aborts);
2027 tw_copy_info(&info, "AEN's: %3d\n", tw_dev->aen_count);
2028 }
2029 if (info.position > info.offset) {
2030 return (info.position - info.offset);
2031 } else {
2032 return 0;
2033 }
2034 } /* End tw_scsi_proc_info() */
2035
2036 /* This is the main scsi queue function to handle scsi opcodes */
2037 int tw_scsi_queue(Scsi_Cmnd *SCpnt, void (*done)(Scsi_Cmnd *))
2038 {
2039 unsigned char *command = SCpnt->cmnd;
2040 int request_id = 0;
2041 int error = 0;
2042 unsigned long flags = 0;
2043 TW_Device_Extension *tw_dev = (TW_Device_Extension *)SCpnt->host->hostdata;
2044
2045 if (tw_dev == NULL) {
2046 printk(KERN_WARNING "3w-xxxx: tw_scsi_queue(): Invalid device extension.\n");
2047 SCpnt->result = (DID_ERROR << 16);
2048 done(SCpnt);
2049 return 0;
2050 }
2051
2052 spin_lock_irqsave(&tw_dev->tw_lock, flags);
2053 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue()\n");
2054
2055 /* Skip scsi command if it isn't for us */
2056 if ((tw_dev->is_unit_present[SCpnt->target] == FALSE) || (SCpnt->lun != 0)) {
2057 SCpnt->result = (DID_BAD_TARGET << 16);
2058 done(SCpnt);
2059 spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
2060 return 0;
2061 }
2062
2063 /* Save done function into Scsi_Cmnd struct */
2064 SCpnt->scsi_done = done;
2065
2066 /* Queue the command and get a request id */
2067 tw_state_request_start(tw_dev, &request_id);
2068
2069 /* Save the scsi command for use by the ISR */
2070 tw_dev->srb[request_id] = SCpnt;
2071
2072 switch (*command) {
2073 case READ_10:
2074 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_10.\n");
2075 case READ_6:
2076 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_6.\n");
2077 case WRITE_10:
2078 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught WRITE_10.\n");
2079 case WRITE_6:
2080 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught WRITE_6.\n");
2081 error = tw_scsiop_read_write(tw_dev, request_id);
2082 break;
2083 case TEST_UNIT_READY:
2084 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TEST_UNIT_READY.\n");
2085 error = tw_scsiop_test_unit_ready(tw_dev, request_id);
2086 break;
2087 case INQUIRY:
2088 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught INQUIRY.\n");
2089 error = tw_scsiop_inquiry(tw_dev, request_id);
2090 break;
2091 case READ_CAPACITY:
2092 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught READ_CAPACITY.\n");
2093 error = tw_scsiop_read_capacity(tw_dev, request_id);
2094 break;
2095 case REQUEST_SENSE:
2096 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught REQUEST_SENSE.\n");
2097 error = tw_scsiop_request_sense(tw_dev, request_id);
2098 break;
2099 case TW_IOCTL:
2100 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): caught TW_SCSI_IOCTL.\n");
2101 error = tw_ioctl(tw_dev, request_id);
2102 break;
2103 default:
2104 printk(KERN_NOTICE "3w-xxxx: tw_scsi_queue(): Unknown scsi opcode: 0x%x\n", *command);
2105 tw_dev->state[request_id] = TW_S_COMPLETED;
2106 tw_state_request_finish(tw_dev, request_id);
2107 SCpnt->result = (DID_BAD_TARGET << 16);
2108 done(SCpnt);
2109 }
2110 if (error) {
2111 tw_dev->state[request_id] = TW_S_COMPLETED;
2112 tw_state_request_finish(tw_dev, request_id);
2113 SCpnt->result = (DID_ERROR << 16);
2114 done(SCpnt);
2115 }
2116 spin_unlock_irqrestore(&tw_dev->tw_lock, flags);
2117
2118 return 0;
2119 } /* End tw_scsi_queue() */
2120
2121 /* This function will release the resources on an rmmod call */
2122 int tw_scsi_release(struct Scsi_Host *tw_host)
2123 {
2124 TW_Device_Extension *tw_dev;
2125 tw_dev = (TW_Device_Extension *)tw_host->hostdata;
2126
2127 dprintk(KERN_NOTICE "3w-xxxx: tw_scsi_release()\n");
2128
2129 /* Free up the IO region */
2130 release_region((tw_dev->tw_pci_dev->resource[0].start), TW_IO_ADDRESS_RANGE);
2131
2132 /* Free up the IRQ */
2133 free_irq(tw_dev->tw_pci_dev->irq, tw_dev);
2134
2135 /* Free up device extension resources */
2136 tw_free_device_extension(tw_dev);
2137
2138 /* Tell kernel scsi-layer we are gone */
2139 scsi_unregister(tw_host);
2140
2141 /* Fake like we just shut down, so notify the card that
2142 * we "shut down cleanly".
2143 */
2144 tw_halt(0, 0, 0); // parameters aren't actually used
2145
2146 return 0;
2147 } /* End tw_scsi_release() */
2148
2149 /* This function handles scsi inquiry commands */
2150 int tw_scsiop_inquiry(TW_Device_Extension *tw_dev, int request_id)
2151 {
2152 TW_Param *param;
2153 TW_Command *command_packet;
2154 u32 command_que_value, command_que_addr;
2155 u32 param_value;
2156
2157 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry()\n");
2158
2159 /* Initialize command packet */
2160 command_que_addr = tw_dev->registers.command_que_addr;
2161 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2162 if (command_packet == NULL) {
2163 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet virtual address.\n");
2164 return 1;
2165 }
2166 memset(command_packet, 0, sizeof(TW_Sector));
2167 command_packet->byte0.opcode = TW_OP_GET_PARAM;
2168 command_packet->byte0.sgl_offset = 2;
2169 command_packet->size = 4;
2170 command_packet->request_id = request_id;
2171 command_packet->byte3.unit = 0;
2172 command_packet->byte3.host_id = 0;
2173 command_packet->status = 0;
2174 command_packet->flags = 0;
2175 command_packet->byte6.parameter_count = 1;
2176
2177 /* Now setup the param */
2178 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
2179 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment virtual address.\n");
2180 return 1;
2181 }
2182 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2183 memset(param, 0, sizeof(TW_Sector));
2184 param->table_id = 3; /* unit summary table */
2185 param->parameter_id = 3; /* unitsstatus parameter */
2186 param->parameter_size_bytes = TW_MAX_UNITS;
2187 param_value = tw_dev->alignment_physical_address[request_id];
2188 if (param_value == 0) {
2189 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad alignment physical address.\n");
2190 return 1;
2191 }
2192
2193 command_packet->byte8.param.sgl[0].address = param_value;
2194 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2195 command_que_value = tw_dev->command_packet_physical_address[request_id];
2196 if (command_que_value == 0) {
2197 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry(): Bad command packet physical address.\n");
2198 return 1;
2199 }
2200
2201 /* Now try to post the command packet */
2202 tw_post_command_packet(tw_dev, request_id);
2203
2204 return 0;
2205 } /* End tw_scsiop_inquiry() */
2206
2207 /* This function is called by the isr to complete an inquiry command */
2208 int tw_scsiop_inquiry_complete(TW_Device_Extension *tw_dev, int request_id)
2209 {
2210 unsigned char *is_unit_present;
2211 unsigned char *request_buffer;
2212 int i;
2213 TW_Param *param;
2214
2215 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete()\n");
2216
2217 /* Fill request buffer */
2218 if (tw_dev->srb[request_id]->request_buffer == NULL) {
2219 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Request buffer NULL.\n");
2220 return 1;
2221 }
2222 request_buffer = tw_dev->srb[request_id]->request_buffer;
2223 memset(request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
2224 request_buffer[0] = TYPE_DISK; /* Peripheral device type */
2225 request_buffer[1] = 0; /* Device type modifier */
2226 request_buffer[2] = 0; /* No ansi/iso compliance */
2227 request_buffer[4] = 31; /* Additional length */
2228 memcpy(&request_buffer[8], "3ware ", 8); /* Vendor ID */
2229 memcpy(&request_buffer[16], "3w-xxxx ", 16); /* Product ID */
2230 memcpy(&request_buffer[32], tw_driver_version, 3);
2231
2232 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2233 if (param == NULL) {
2234 printk(KERN_WARNING "3w-xxxx: tw_scsiop_inquiry_complete(): Bad alignment virtual address.\n");
2235 return 1;
2236 }
2237 is_unit_present = &(param->data[0]);
2238
2239 for (i=0 ; i<TW_MAX_UNITS; i++) {
2240 if (is_unit_present[i] == 0) {
2241 tw_dev->is_unit_present[i] = FALSE;
2242 } else {
2243 if (is_unit_present[i] & TW_UNIT_ONLINE) {
2244 tw_dev->is_unit_present[i] = TRUE;
2245 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_inquiry_complete: Unit %d found.\n", i);
2246 }
2247 }
2248 }
2249
2250 return 0;
2251 } /* End tw_scsiop_inquiry_complete() */
2252
2253 /* This function handles scsi read_capacity commands */
2254 int tw_scsiop_read_capacity(TW_Device_Extension *tw_dev, int request_id)
2255 {
2256 TW_Param *param;
2257 TW_Command *command_packet;
2258 u32 command_que_addr, command_que_value;
2259 u32 param_value;
2260
2261 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity()\n");
2262
2263 /* Initialize command packet */
2264 command_que_addr = tw_dev->registers.command_que_addr;
2265 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2266
2267 if (command_packet == NULL) {
2268 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet virtual address.\n");
2269 return 1;
2270 }
2271 memset(command_packet, 0, sizeof(TW_Sector));
2272 command_packet->byte0.opcode = TW_OP_GET_PARAM;
2273 command_packet->byte0.sgl_offset = 2;
2274 command_packet->size = 4;
2275 command_packet->request_id = request_id;
2276 command_packet->byte3.unit = tw_dev->srb[request_id]->target;
2277 command_packet->byte3.host_id = 0;
2278 command_packet->status = 0;
2279 command_packet->flags = 0;
2280 command_packet->byte6.block_count = 1;
2281
2282 /* Now setup the param */
2283 if (tw_dev->alignment_virtual_address[request_id] == NULL) {
2284 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment virtual address.\n");
2285 return 1;
2286 }
2287 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2288 memset(param, 0, sizeof(TW_Sector));
2289 param->table_id = TW_UNIT_INFORMATION_TABLE_BASE +
2290 tw_dev->srb[request_id]->target;
2291 param->parameter_id = 4; /* unitcapacity parameter */
2292 param->parameter_size_bytes = 4;
2293 param_value = tw_dev->alignment_physical_address[request_id];
2294 if (param_value == 0) {
2295 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad alignment physical address.\n");
2296 return 1;
2297 }
2298
2299 command_packet->byte8.param.sgl[0].address = param_value;
2300 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2301 command_que_value = tw_dev->command_packet_physical_address[request_id];
2302 if (command_que_value == 0) {
2303 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity(): Bad command packet physical address.\n");
2304 return 1;
2305 }
2306
2307 /* Now try to post the command to the board */
2308 tw_post_command_packet(tw_dev, request_id);
2309
2310 return 0;
2311 } /* End tw_scsiop_read_capacity() */
2312
2313 /* This function is called by the isr to complete a readcapacity command */
2314 int tw_scsiop_read_capacity_complete(TW_Device_Extension *tw_dev, int request_id)
2315 {
2316 unsigned char *param_data;
2317 u32 capacity;
2318 char *buff;
2319 TW_Param *param;
2320
2321 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete()\n");
2322
2323 buff = tw_dev->srb[request_id]->request_buffer;
2324 if (buff == NULL) {
2325 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Request buffer NULL.\n");
2326 return 1;
2327 }
2328 memset(buff, 0, tw_dev->srb[request_id]->request_bufflen);
2329 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2330 if (param == NULL) {
2331 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_capacity_complete(): Bad alignment virtual address.\n");
2332 return 1;
2333 }
2334 param_data = &(param->data[0]);
2335
2336 capacity = (param_data[3] << 24) | (param_data[2] << 16) |
2337 (param_data[1] << 8) | param_data[0];
2338
2339 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_capacity_complete(): Capacity = 0x%x.\n", capacity);
2340
2341 /* Number of LBA's */
2342 buff[0] = (capacity >> 24);
2343 buff[1] = (capacity >> 16) & 0xff;
2344 buff[2] = (capacity >> 8) & 0xff;
2345 buff[3] = capacity & 0xff;
2346
2347 /* Block size in bytes (512) */
2348 buff[4] = (TW_BLOCK_SIZE >> 24);
2349 buff[5] = (TW_BLOCK_SIZE >> 16) & 0xff;
2350 buff[6] = (TW_BLOCK_SIZE >> 8) & 0xff;
2351 buff[7] = TW_BLOCK_SIZE & 0xff;
2352
2353 return 0;
2354 } /* End tw_scsiop_read_capacity_complete() */
2355
2356 /* This function handles scsi read or write commands */
2357 int tw_scsiop_read_write(TW_Device_Extension *tw_dev, int request_id)
2358 {
2359 TW_Command *command_packet;
2360 u32 command_que_addr, command_que_value = 0;
2361 u32 lba = 0x0, num_sectors = 0x0;
2362 int i, count = 0;
2363 Scsi_Cmnd *srb;
2364 struct scatterlist *sglist;
2365
2366 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write()\n");
2367
2368 if (tw_dev->srb[request_id]->request_buffer == NULL) {
2369 printk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Request buffer NULL.\n");
2370 return 1;
2371 }
2372 sglist = (struct scatterlist *)tw_dev->srb[request_id]->request_buffer;
2373 srb = tw_dev->srb[request_id];
2374
2375 /* Initialize command packet */
2376 command_que_addr = tw_dev->registers.command_que_addr;
2377 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2378 if (command_packet == NULL) {
2379 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): Bad command packet virtual address.\n");
2380 return 1;
2381 }
2382
2383 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == READ_10) {
2384 command_packet->byte0.opcode = TW_OP_READ;
2385 } else {
2386 command_packet->byte0.opcode = TW_OP_WRITE;
2387 }
2388
2389 command_packet->byte0.sgl_offset = 3;
2390 command_packet->size = 5;
2391 command_packet->request_id = request_id;
2392 command_packet->byte3.unit = srb->target;
2393 command_packet->byte3.host_id = 0;
2394 command_packet->status = 0;
2395 command_packet->flags = 0;
2396
2397 if (srb->cmnd[0] == WRITE_10) {
2398 if ((srb->cmnd[1] & 0x8) || (srb->cmnd[1] & 0x10))
2399 command_packet->flags = 1;
2400 }
2401
2402 if (srb->cmnd[0] == READ_6 || srb->cmnd[0] == WRITE_6) {
2403 lba = ((u32)srb->cmnd[1] << 16) | ((u32)srb->cmnd[2] << 8) | (u32)srb->cmnd[3];
2404 num_sectors = (u32)srb->cmnd[4];
2405 } else {
2406 lba = ((u32)srb->cmnd[2] << 24) | ((u32)srb->cmnd[3] << 16) | ((u32)srb->cmnd[4] << 8) | (u32)srb->cmnd[5];
2407 num_sectors = (u32)srb->cmnd[8] | ((u32)srb->cmnd[7] << 8);
2408 }
2409
2410 /* Update sector statistic */
2411 tw_dev->sector_count = num_sectors;
2412 if (tw_dev->sector_count > tw_dev->max_sector_count)
2413 tw_dev->max_sector_count = tw_dev->sector_count;
2414
2415 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): lba = 0x%x num_sectors = 0x%x\n", lba, num_sectors);
2416 command_packet->byte8.io.lba = lba;
2417 command_packet->byte6.block_count = num_sectors;
2418
2419 if ((tw_dev->is_raid_five[tw_dev->srb[request_id]->target] == 0) || (srb->cmnd[0] == READ_6) || (srb->cmnd[0] == READ_10) || (tw_dev->tw_pci_dev->device == TW_DEVICE_ID2)) {
2420 /* Do this if there are no sg list entries */
2421 if (tw_dev->srb[request_id]->use_sg == 0) {
2422 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_read_write(): SG = 0\n");
2423 command_packet->byte8.io.sgl[0].address = virt_to_bus(tw_dev->srb[request_id]->request_buffer);
2424 command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
2425 }
2426
2427 /* Do this if we have multiple sg list entries */
2428 if (tw_dev->srb[request_id]->use_sg > 0) {
2429 for (i=0;i<tw_dev->srb[request_id]->use_sg; i++) {
2430 command_packet->byte8.io.sgl[i].address = virt_to_bus(sglist[i].address);
2431 command_packet->byte8.io.sgl[i].length = sglist[i].length;
2432 command_packet->size+=2;
2433 }
2434 if (tw_dev->srb[request_id]->use_sg >= 1)
2435 command_packet->size-=2;
2436 }
2437 } else {
2438 /* Do this if there are no sg list entries for raid 5 */
2439 if (tw_dev->srb[request_id]->use_sg == 0) {
2440 dprintk(KERN_WARNING "doing raid 5 write use_sg = 0, bounce_buffer[%d] = 0x%p\n", request_id, tw_dev->bounce_buffer[request_id]);
2441 memcpy(tw_dev->bounce_buffer[request_id], tw_dev->srb[request_id]->request_buffer, tw_dev->srb[request_id]->request_bufflen);
2442 command_packet->byte8.io.sgl[0].address = virt_to_bus(tw_dev->bounce_buffer[request_id]);
2443 command_packet->byte8.io.sgl[0].length = tw_dev->srb[request_id]->request_bufflen;
2444 }
2445
2446 /* Do this if we have multiple sg list entries for raid 5 */
2447 if (tw_dev->srb[request_id]->use_sg > 0) {
2448 dprintk(KERN_WARNING "doing raid 5 write use_sg = %d, sglist[0].length = %d\n", tw_dev->srb[request_id]->use_sg, sglist[0].length);
2449 for (i=0;i<tw_dev->srb[request_id]->use_sg; i++) {
2450 memcpy((char *)(tw_dev->bounce_buffer[request_id])+count, sglist[i].address, sglist[i].length);
2451 count+=sglist[i].length;
2452 }
2453 command_packet->byte8.io.sgl[0].address = virt_to_bus(tw_dev->bounce_buffer[request_id]);
2454 command_packet->byte8.io.sgl[0].length = count;
2455 command_packet->size = 5; /* single sgl */
2456 }
2457 }
2458
2459 /* Update SG statistics */
2460 tw_dev->sgl_entries = tw_dev->srb[request_id]->use_sg;
2461 if (tw_dev->sgl_entries > tw_dev->max_sgl_entries)
2462 tw_dev->max_sgl_entries = tw_dev->sgl_entries;
2463
2464 command_que_value = tw_dev->command_packet_physical_address[request_id];
2465 if (command_que_value == 0) {
2466 dprintk(KERN_WARNING "3w-xxxx: tw_scsiop_read_write(): Bad command packet physical address.\n");
2467 return 1;
2468 }
2469
2470 /* Now try to post the command to the board */
2471 tw_post_command_packet(tw_dev, request_id);
2472
2473 return 0;
2474 } /* End tw_scsiop_read_write() */
2475
2476 /* This function will handle the request sense scsi command */
2477 int tw_scsiop_request_sense(TW_Device_Extension *tw_dev, int request_id)
2478 {
2479 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_request_sense()\n");
2480
2481 /* For now we just zero the sense buffer */
2482 memset(tw_dev->srb[request_id]->request_buffer, 0, tw_dev->srb[request_id]->request_bufflen);
2483 tw_dev->state[request_id] = TW_S_COMPLETED;
2484 tw_state_request_finish(tw_dev, request_id);
2485
2486 /* If we got a request_sense, we probably want a reset, return error */
2487 tw_dev->srb[request_id]->result = (DID_ERROR << 16);
2488 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2489
2490 return 0;
2491 } /* End tw_scsiop_request_sense() */
2492
2493 /* This function will handle test unit ready scsi command */
2494 int tw_scsiop_test_unit_ready(TW_Device_Extension *tw_dev, int request_id)
2495 {
2496 dprintk(KERN_NOTICE "3w-xxxx: tw_scsiop_test_unit_ready()\n");
2497
2498 /* Tell the scsi layer were done */
2499 tw_dev->state[request_id] = TW_S_COMPLETED;
2500 tw_state_request_finish(tw_dev, request_id);
2501 tw_dev->srb[request_id]->result = (DID_OK << 16);
2502 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2503
2504 return 0;
2505 } /* End tw_scsiop_test_unit_ready() */
2506
2507 /* Set a value in the features table */
2508 int tw_setfeature(TW_Device_Extension *tw_dev, int parm, int param_size,
2509 unsigned char *val)
2510 {
2511 TW_Param *param;
2512 TW_Command *command_packet;
2513 TW_Response_Queue response_queue;
2514 int request_id = 0;
2515 u32 command_que_value, command_que_addr;
2516 u32 status_reg_addr, status_reg_value;
2517 u32 response_que_addr;
2518 u32 param_value;
2519 int imax, i;
2520
2521 /* Initialize SetParam command packet */
2522 if (tw_dev->command_packet_virtual_address[request_id] == NULL) {
2523 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet virtual address.\n");
2524 return 1;
2525 }
2526 command_packet = (TW_Command *)tw_dev->command_packet_virtual_address[request_id];
2527 memset(command_packet, 0, sizeof(TW_Sector));
2528 param = (TW_Param *)tw_dev->alignment_virtual_address[request_id];
2529
2530 command_packet->byte0.opcode = TW_OP_SET_PARAM;
2531 command_packet->byte0.sgl_offset = 2;
2532 param->table_id = 0x404; /* Features table */
2533 param->parameter_id = parm;
2534 param->parameter_size_bytes = param_size;
2535 memcpy(param->data, val, param_size);
2536
2537 param_value = tw_dev->alignment_physical_address[request_id];
2538 if (param_value == 0) {
2539 printk(KERN_WARNING "3w-xxxx: tw_ioctl(): Bad alignment physical address.\n");
2540 tw_dev->state[request_id] = TW_S_COMPLETED;
2541 tw_state_request_finish(tw_dev, request_id);
2542 tw_dev->srb[request_id]->result = (DID_OK << 16);
2543 tw_dev->srb[request_id]->scsi_done(tw_dev->srb[request_id]);
2544 }
2545 command_packet->byte8.param.sgl[0].address = param_value;
2546 command_packet->byte8.param.sgl[0].length = sizeof(TW_Sector);
2547
2548 command_packet->size = 4;
2549 command_packet->request_id = request_id;
2550 command_packet->byte6.parameter_count = 1;
2551
2552 command_que_value = tw_dev->command_packet_physical_address[request_id];
2553 if (command_que_value == 0) {
2554 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad command packet physical address.\n");
2555 return 1;
2556 }
2557 command_que_addr = tw_dev->registers.command_que_addr;
2558 status_reg_addr = tw_dev->registers.status_reg_addr;
2559 response_que_addr = tw_dev->registers.response_que_addr;
2560
2561 /* Send command packet to the board */
2562 outl(command_que_value, command_que_addr);
2563
2564 /* Poll for completion */
2565 imax = TW_POLL_MAX_RETRIES;
2566 for (i=0;i<imax;i++) {
2567 mdelay(5);
2568 status_reg_value = inl(status_reg_addr);
2569 if (tw_check_bits(status_reg_value)) {
2570 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected bits.\n");
2571 tw_decode_bits(tw_dev, status_reg_value);
2572 return 1;
2573 }
2574 if ((status_reg_value & TW_STATUS_RESPONSE_QUEUE_EMPTY) == 0) {
2575 response_queue.value = inl(response_que_addr);
2576 request_id = (unsigned char)response_queue.u.response_id;
2577 if (request_id != 0) {
2578 /* unexpected request id */
2579 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Unexpected request id.\n");
2580 return 1;
2581 }
2582 if (command_packet->status != 0) {
2583 /* bad response */
2584 printk(KERN_WARNING "3w-xxxx: tw_setfeature(): Bad response, status = 0x%x, flags = 0x%x.\n", command_packet->status, command_packet->flags);
2585 return 1;
2586 }
2587 break; /* Response was okay, so we exit */
2588 }
2589 }
2590
2591 return 0;
2592 } /* End tw_setfeature() */
2593
2594 /* This function will setup the interrupt handler */
2595 int tw_setup_irq(TW_Device_Extension *tw_dev)
2596 {
2597 char *device = TW_DEVICE_NAME;
2598 int error;
2599
2600 dprintk(KERN_NOTICE "3w-xxxx: tw_setup_irq()\n");
2601 error = request_irq(tw_dev->tw_pci_dev->irq, tw_interrupt, SA_SHIRQ, device, tw_dev);
2602
2603 if (error < 0) {
2604 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);
2605 return 1;
2606 }
2607 return 0;
2608 } /* End tw_setup_irq() */
2609
2610 /* This function will tell the controller we're shutting down by sending
2611 initconnection with a 1 */
2612 int tw_shutdown_device(TW_Device_Extension *tw_dev)
2613 {
2614 int error;
2615
2616 /* Disable interrupts */
2617 tw_disable_interrupts(tw_dev);
2618
2619 /* poke the board */
2620 error = tw_initconnection(tw_dev, 1);
2621 if (error) {
2622 printk(KERN_WARNING "3w-xxxx: tw_shutdown_device(): Couldn't initconnection for card %d.\n", tw_dev->host->host_no);
2623 } else {
2624 printk(KERN_NOTICE "3w-xxxx shutdown succeeded\n");
2625 }
2626
2627 /* Re-enable interrupts */
2628 tw_enable_interrupts(tw_dev);
2629
2630 return 0;
2631 } /* End tw_shutdown_device() */
2632
2633 /* This function will soft reset the controller */
2634 void tw_soft_reset(TW_Device_Extension *tw_dev)
2635 {
2636 u32 control_reg_addr, control_reg_value;
2637
2638 control_reg_addr = tw_dev->registers.control_reg_addr;
2639 control_reg_value = ( TW_CONTROL_ISSUE_SOFT_RESET |
2640 TW_CONTROL_CLEAR_HOST_INTERRUPT |
2641 TW_CONTROL_CLEAR_ATTENTION_INTERRUPT |
2642 TW_CONTROL_MASK_COMMAND_INTERRUPT |
2643 TW_CONTROL_MASK_RESPONSE_INTERRUPT |
2644 TW_CONTROL_CLEAR_ERROR_STATUS |
2645 TW_CONTROL_DISABLE_INTERRUPTS);
2646 outl(control_reg_value, control_reg_addr);
2647 } /* End tw_soft_reset() */
2648
2649 /* This function will free a request_id */
2650 int tw_state_request_finish(TW_Device_Extension *tw_dev, int request_id)
2651 {
2652 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish()\n");
2653
2654 do {
2655 if (tw_dev->free_tail == TW_Q_LENGTH-1) {
2656 tw_dev->free_tail = TW_Q_START;
2657 } else {
2658 tw_dev->free_tail = tw_dev->free_tail + 1;
2659 }
2660 } while ((tw_dev->state[tw_dev->free_queue[tw_dev->free_tail]] != TW_S_COMPLETED));
2661
2662 tw_dev->free_queue[tw_dev->free_tail] = request_id;
2663
2664 tw_dev->state[request_id] = TW_S_FINISHED;
2665 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_finish(): Freeing request_id %d\n", request_id);
2666
2667 return 0;
2668 } /* End tw_state_request_finish() */
2669
2670 /* This function will assign an available request_id */
2671 int tw_state_request_start(TW_Device_Extension *tw_dev, int *request_id)
2672 {
2673 int id = 0;
2674
2675 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start()\n");
2676
2677 /* Obtain next free request_id */
2678 do {
2679 if (tw_dev->free_head == TW_Q_LENGTH - 1) {
2680 tw_dev->free_head = TW_Q_START;
2681 } else {
2682 tw_dev->free_head = tw_dev->free_head + 1;
2683 }
2684 } while ((tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_STARTED) ||
2685 (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_POSTED) ||
2686 (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_PENDING) ||
2687 (tw_dev->state[tw_dev->free_queue[tw_dev->free_head]] == TW_S_COMPLETED));
2688
2689 id = tw_dev->free_queue[tw_dev->free_head];
2690
2691 if (tw_dev->free_head == TW_Q_LENGTH - 1) {
2692 tw_dev->free_head = TW_Q_START;
2693 } else {
2694 tw_dev->free_head = tw_dev->free_head + 1;
2695 }
2696
2697 dprintk(KERN_NOTICE "3w-xxxx: tw_state_request_start(): id = %d.\n", id);
2698 *request_id = id;
2699 tw_dev->state[id] = TW_S_STARTED;
2700
2701 return 0;
2702 } /* End tw_state_request_start() */
2703
2704 /* This function will unmask the command interrupt on the controller */
2705 void tw_unmask_command_interrupt(TW_Device_Extension *tw_dev)
2706 {
2707 u32 control_reg_addr, control_reg_value;
2708
2709 control_reg_addr = tw_dev->registers.control_reg_addr;
2710 control_reg_value = TW_CONTROL_UNMASK_COMMAND_INTERRUPT;
2711 outl(control_reg_value, control_reg_addr);
2712 } /* End tw_unmask_command_interrupt() */
2713
2714 /* Now get things going */
2715
2716 static Scsi_Host_Template driver_template = TWXXXX;
2717 #include "scsi_module.c"
2718
2719