blob: e1233aabda771493718b5f37f9228e00301098e3 [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/*
Mike Millerbd4f36d2007-10-24 10:30:34 +02002 * Disk Array driver for HP Smart Array controllers, SCSI Tape module.
3 * (C) Copyright 2001, 2007 Hewlett-Packard Development Company, L.P.
Linus Torvalds1da177e2005-04-16 15:20:36 -07004 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
Mike Millerbd4f36d2007-10-24 10:30:34 +02007 * the Free Software Foundation; version 2 of the License.
Linus Torvalds1da177e2005-04-16 15:20:36 -07008 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Mike Millerbd4f36d2007-10-24 10:30:34 +020011 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
Linus Torvalds1da177e2005-04-16 15:20:36 -070013 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
Mike Millerbd4f36d2007-10-24 10:30:34 +020016 * Foundation, Inc., 59 Temple Place, Suite 300, Boston, MA
17 * 02111-1307, USA.
Linus Torvalds1da177e2005-04-16 15:20:36 -070018 *
19 * Questions/Comments/Bugfixes to iss_storagedev@hp.com
20 *
21 * Author: Stephen M. Cameron
22 */
23#ifdef CONFIG_CISS_SCSI_TAPE
24
25/* Here we have code to present the driver as a scsi driver
26 as it is simultaneously presented as a block driver. The
27 reason for doing this is to allow access to SCSI tape drives
28 through the array controller. Note in particular, neither
29 physical nor logical disks are presented through the scsi layer. */
30
Tim Schmielau4e57b682005-10-30 15:03:48 -080031#include <linux/timer.h>
32#include <linux/completion.h>
33#include <linux/slab.h>
34#include <linux/string.h>
35
36#include <asm/atomic.h>
37
Linus Torvalds1da177e2005-04-16 15:20:36 -070038#include <scsi/scsi_cmnd.h>
39#include <scsi/scsi_device.h>
40#include <scsi/scsi_host.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070041
42#include "cciss_scsi.h"
43
mike.miller@hp.com3da8b712005-11-04 12:30:37 -060044#define CCISS_ABORT_MSG 0x00
45#define CCISS_RESET_MSG 0x01
46
Linus Torvalds1da177e2005-04-16 15:20:36 -070047/* some prototypes... */
48static int sendcmd(
49 __u8 cmd,
50 int ctlr,
51 void *buff,
52 size_t size,
53 unsigned int use_unit_num, /* 0: address the controller,
54 1: address logical volume log_unit,
55 2: address is in scsi3addr */
56 unsigned int log_unit,
57 __u8 page_code,
58 unsigned char *scsi3addr,
59 int cmd_type);
60
61
62static int cciss_scsi_proc_info(
63 struct Scsi_Host *sh,
64 char *buffer, /* data buffer */
65 char **start, /* where data in buffer starts */
66 off_t offset, /* offset from start of imaginary file */
67 int length, /* length of data in buffer */
68 int func); /* 0 == read, 1 == write */
69
70static int cciss_scsi_queue_command (struct scsi_cmnd *cmd,
71 void (* done)(struct scsi_cmnd *));
mike.miller@hp.com3da8b712005-11-04 12:30:37 -060072static int cciss_eh_device_reset_handler(struct scsi_cmnd *);
73static int cciss_eh_abort_handler(struct scsi_cmnd *);
Linus Torvalds1da177e2005-04-16 15:20:36 -070074
75static struct cciss_scsi_hba_t ccissscsi[MAX_CTLR] = {
76 { .name = "cciss0", .ndevices = 0 },
77 { .name = "cciss1", .ndevices = 0 },
78 { .name = "cciss2", .ndevices = 0 },
79 { .name = "cciss3", .ndevices = 0 },
80 { .name = "cciss4", .ndevices = 0 },
81 { .name = "cciss5", .ndevices = 0 },
82 { .name = "cciss6", .ndevices = 0 },
83 { .name = "cciss7", .ndevices = 0 },
84};
85
86static struct scsi_host_template cciss_driver_template = {
87 .module = THIS_MODULE,
88 .name = "cciss",
89 .proc_name = "cciss",
90 .proc_info = cciss_scsi_proc_info,
91 .queuecommand = cciss_scsi_queue_command,
92 .can_queue = SCSI_CCISS_CAN_QUEUE,
93 .this_id = 7,
94 .sg_tablesize = MAXSGENTRIES,
95 .cmd_per_lun = 1,
96 .use_clustering = DISABLE_CLUSTERING,
mike.miller@hp.com3da8b712005-11-04 12:30:37 -060097 /* Can't have eh_bus_reset_handler or eh_host_reset_handler for cciss */
98 .eh_device_reset_handler= cciss_eh_device_reset_handler,
99 .eh_abort_handler = cciss_eh_abort_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100};
101
102#pragma pack(1)
103struct cciss_scsi_cmd_stack_elem_t {
104 CommandList_struct cmd;
105 ErrorInfo_struct Err;
106 __u32 busaddr;
Mike Miller33079b22005-09-13 01:25:22 -0700107 __u32 pad;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700108};
109
110#pragma pack()
111
112#define CMD_STACK_SIZE (SCSI_CCISS_CAN_QUEUE * \
113 CCISS_MAX_SCSI_DEVS_PER_HBA + 2)
114 // plus two for init time usage
115
116#pragma pack(1)
117struct cciss_scsi_cmd_stack_t {
118 struct cciss_scsi_cmd_stack_elem_t *pool;
119 struct cciss_scsi_cmd_stack_elem_t *elem[CMD_STACK_SIZE];
120 dma_addr_t cmd_pool_handle;
121 int top;
122};
123#pragma pack()
124
125struct cciss_scsi_adapter_data_t {
126 struct Scsi_Host *scsi_host;
127 struct cciss_scsi_cmd_stack_t cmd_stack;
128 int registered;
129 spinlock_t lock; // to protect ccissscsi[ctlr];
130};
131
132#define CPQ_TAPE_LOCK(ctlr, flags) spin_lock_irqsave( \
133 &(((struct cciss_scsi_adapter_data_t *) \
134 hba[ctlr]->scsi_ctlr)->lock), flags);
135#define CPQ_TAPE_UNLOCK(ctlr, flags) spin_unlock_irqrestore( \
136 &(((struct cciss_scsi_adapter_data_t *) \
137 hba[ctlr]->scsi_ctlr)->lock), flags);
138
139static CommandList_struct *
140scsi_cmd_alloc(ctlr_info_t *h)
141{
142 /* assume only one process in here at a time, locking done by caller. */
143 /* use CCISS_LOCK(ctlr) */
144 /* might be better to rewrite how we allocate scsi commands in a way that */
145 /* needs no locking at all. */
146
147 /* take the top memory chunk off the stack and return it, if any. */
148 struct cciss_scsi_cmd_stack_elem_t *c;
149 struct cciss_scsi_adapter_data_t *sa;
150 struct cciss_scsi_cmd_stack_t *stk;
151 u64bit temp64;
152
153 sa = (struct cciss_scsi_adapter_data_t *) h->scsi_ctlr;
154 stk = &sa->cmd_stack;
155
156 if (stk->top < 0)
157 return NULL;
158 c = stk->elem[stk->top];
159 /* memset(c, 0, sizeof(*c)); */
160 memset(&c->cmd, 0, sizeof(c->cmd));
161 memset(&c->Err, 0, sizeof(c->Err));
162 /* set physical addr of cmd and addr of scsi parameters */
163 c->cmd.busaddr = c->busaddr;
164 /* (__u32) (stk->cmd_pool_handle +
165 (sizeof(struct cciss_scsi_cmd_stack_elem_t)*stk->top)); */
166
167 temp64.val = (__u64) (c->busaddr + sizeof(CommandList_struct));
168 /* (__u64) (stk->cmd_pool_handle +
169 (sizeof(struct cciss_scsi_cmd_stack_elem_t)*stk->top) +
170 sizeof(CommandList_struct)); */
171 stk->top--;
172 c->cmd.ErrDesc.Addr.lower = temp64.val32.lower;
173 c->cmd.ErrDesc.Addr.upper = temp64.val32.upper;
174 c->cmd.ErrDesc.Len = sizeof(ErrorInfo_struct);
175
176 c->cmd.ctlr = h->ctlr;
177 c->cmd.err_info = &c->Err;
178
179 return (CommandList_struct *) c;
180}
181
182static void
183scsi_cmd_free(ctlr_info_t *h, CommandList_struct *cmd)
184{
185 /* assume only one process in here at a time, locking done by caller. */
186 /* use CCISS_LOCK(ctlr) */
187 /* drop the free memory chunk on top of the stack. */
188
189 struct cciss_scsi_adapter_data_t *sa;
190 struct cciss_scsi_cmd_stack_t *stk;
191
192 sa = (struct cciss_scsi_adapter_data_t *) h->scsi_ctlr;
193 stk = &sa->cmd_stack;
194 if (stk->top >= CMD_STACK_SIZE) {
195 printk("cciss: scsi_cmd_free called too many times.\n");
196 BUG();
197 }
198 stk->top++;
199 stk->elem[stk->top] = (struct cciss_scsi_cmd_stack_elem_t *) cmd;
200}
201
202static int
203scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa)
204{
205 int i;
206 struct cciss_scsi_cmd_stack_t *stk;
207 size_t size;
208
209 stk = &sa->cmd_stack;
210 size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;
211
212 // pci_alloc_consistent guarantees 32-bit DMA address will
213 // be used
214
215 stk->pool = (struct cciss_scsi_cmd_stack_elem_t *)
216 pci_alloc_consistent(hba[ctlr]->pdev, size, &stk->cmd_pool_handle);
217
218 if (stk->pool == NULL) {
219 printk("stk->pool is null\n");
220 return -1;
221 }
222
223 for (i=0; i<CMD_STACK_SIZE; i++) {
224 stk->elem[i] = &stk->pool[i];
225 stk->elem[i]->busaddr = (__u32) (stk->cmd_pool_handle +
226 (sizeof(struct cciss_scsi_cmd_stack_elem_t) * i));
227 }
228 stk->top = CMD_STACK_SIZE-1;
229 return 0;
230}
231
232static void
233scsi_cmd_stack_free(int ctlr)
234{
235 struct cciss_scsi_adapter_data_t *sa;
236 struct cciss_scsi_cmd_stack_t *stk;
237 size_t size;
238
239 sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
240 stk = &sa->cmd_stack;
241 if (stk->top != CMD_STACK_SIZE-1) {
242 printk( "cciss: %d scsi commands are still outstanding.\n",
243 CMD_STACK_SIZE - stk->top);
244 // BUG();
245 printk("WE HAVE A BUG HERE!!! stk=0x%p\n", stk);
246 }
247 size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;
248
249 pci_free_consistent(hba[ctlr]->pdev, size, stk->pool, stk->cmd_pool_handle);
250 stk->pool = NULL;
251}
252
Grant Coady400bb232005-11-15 00:09:20 -0800253#if 0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700254static int xmargin=8;
255static int amargin=60;
256
257static void
258print_bytes (unsigned char *c, int len, int hex, int ascii)
259{
260
261 int i;
262 unsigned char *x;
263
264 if (hex)
265 {
266 x = c;
267 for (i=0;i<len;i++)
268 {
269 if ((i % xmargin) == 0 && i>0) printk("\n");
270 if ((i % xmargin) == 0) printk("0x%04x:", i);
271 printk(" %02x", *x);
272 x++;
273 }
274 printk("\n");
275 }
276 if (ascii)
277 {
278 x = c;
279 for (i=0;i<len;i++)
280 {
281 if ((i % amargin) == 0 && i>0) printk("\n");
282 if ((i % amargin) == 0) printk("0x%04x:", i);
283 if (*x > 26 && *x < 128) printk("%c", *x);
284 else printk(".");
285 x++;
286 }
287 printk("\n");
288 }
289}
290
291static void
292print_cmd(CommandList_struct *cp)
293{
294 printk("queue:%d\n", cp->Header.ReplyQueue);
295 printk("sglist:%d\n", cp->Header.SGList);
296 printk("sgtot:%d\n", cp->Header.SGTotal);
297 printk("Tag:0x%08x/0x%08x\n", cp->Header.Tag.upper,
298 cp->Header.Tag.lower);
299 printk("LUN:0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
300 cp->Header.LUN.LunAddrBytes[0],
301 cp->Header.LUN.LunAddrBytes[1],
302 cp->Header.LUN.LunAddrBytes[2],
303 cp->Header.LUN.LunAddrBytes[3],
304 cp->Header.LUN.LunAddrBytes[4],
305 cp->Header.LUN.LunAddrBytes[5],
306 cp->Header.LUN.LunAddrBytes[6],
307 cp->Header.LUN.LunAddrBytes[7]);
308 printk("CDBLen:%d\n", cp->Request.CDBLen);
309 printk("Type:%d\n",cp->Request.Type.Type);
310 printk("Attr:%d\n",cp->Request.Type.Attribute);
311 printk(" Dir:%d\n",cp->Request.Type.Direction);
312 printk("Timeout:%d\n",cp->Request.Timeout);
313 printk( "CDB: %02x %02x %02x %02x %02x %02x %02x %02x"
314 " %02x %02x %02x %02x %02x %02x %02x %02x\n",
315 cp->Request.CDB[0], cp->Request.CDB[1],
316 cp->Request.CDB[2], cp->Request.CDB[3],
317 cp->Request.CDB[4], cp->Request.CDB[5],
318 cp->Request.CDB[6], cp->Request.CDB[7],
319 cp->Request.CDB[8], cp->Request.CDB[9],
320 cp->Request.CDB[10], cp->Request.CDB[11],
321 cp->Request.CDB[12], cp->Request.CDB[13],
322 cp->Request.CDB[14], cp->Request.CDB[15]),
323 printk("edesc.Addr: 0x%08x/0%08x, Len = %d\n",
324 cp->ErrDesc.Addr.upper, cp->ErrDesc.Addr.lower,
325 cp->ErrDesc.Len);
326 printk("sgs..........Errorinfo:\n");
327 printk("scsistatus:%d\n", cp->err_info->ScsiStatus);
328 printk("senselen:%d\n", cp->err_info->SenseLen);
329 printk("cmd status:%d\n", cp->err_info->CommandStatus);
330 printk("resid cnt:%d\n", cp->err_info->ResidualCnt);
331 printk("offense size:%d\n", cp->err_info->MoreErrInfo.Invalid_Cmd.offense_size);
332 printk("offense byte:%d\n", cp->err_info->MoreErrInfo.Invalid_Cmd.offense_num);
333 printk("offense value:%d\n", cp->err_info->MoreErrInfo.Invalid_Cmd.offense_value);
334
335}
336
337#endif
338
339static int
340find_bus_target_lun(int ctlr, int *bus, int *target, int *lun)
341{
342 /* finds an unused bus, target, lun for a new device */
343 /* assumes hba[ctlr]->scsi_ctlr->lock is held */
344 int i, found=0;
345 unsigned char target_taken[CCISS_MAX_SCSI_DEVS_PER_HBA];
346
347 memset(&target_taken[0], 0, CCISS_MAX_SCSI_DEVS_PER_HBA);
348
349 target_taken[SELF_SCSI_ID] = 1;
350 for (i=0;i<ccissscsi[ctlr].ndevices;i++)
351 target_taken[ccissscsi[ctlr].dev[i].target] = 1;
352
353 for (i=0;i<CCISS_MAX_SCSI_DEVS_PER_HBA;i++) {
354 if (!target_taken[i]) {
355 *bus = 0; *target=i; *lun = 0; found=1;
356 break;
357 }
358 }
359 return (!found);
360}
Mike Millerf4a93bc2008-08-04 11:54:53 +0200361struct scsi2map {
362 char scsi3addr[8];
363 int bus, target, lun;
364};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365
366static int
367cciss_scsi_add_entry(int ctlr, int hostno,
Mike Millerf4a93bc2008-08-04 11:54:53 +0200368 unsigned char *scsi3addr, int devtype,
369 struct scsi2map *added, int *nadded)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700370{
371 /* assumes hba[ctlr]->scsi_ctlr->lock is held */
372 int n = ccissscsi[ctlr].ndevices;
373 struct cciss_scsi_dev_t *sd;
Mike Miller935dc8d2008-08-04 11:54:54 +0200374 int i, bus, target, lun;
375 unsigned char addr1[8], addr2[8];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700376
377 if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) {
378 printk("cciss%d: Too many devices, "
379 "some will be inaccessible.\n", ctlr);
380 return -1;
381 }
Mike Millerf4a93bc2008-08-04 11:54:53 +0200382
Mike Miller935dc8d2008-08-04 11:54:54 +0200383 bus = target = -1;
384 lun = 0;
385 /* Is this device a non-zero lun of a multi-lun device */
386 /* byte 4 of the 8-byte LUN addr will contain the logical unit no. */
387 if (scsi3addr[4] != 0) {
388 /* Search through our list and find the device which */
389 /* has the same 8 byte LUN address, excepting byte 4. */
390 /* Assign the same bus and target for this new LUN. */
391 /* Use the logical unit number from the firmware. */
392 memcpy(addr1, scsi3addr, 8);
393 addr1[4] = 0;
394 for (i = 0; i < n; i++) {
395 sd = &ccissscsi[ctlr].dev[i];
396 memcpy(addr2, sd->scsi3addr, 8);
397 addr2[4] = 0;
398 /* differ only in byte 4? */
399 if (memcmp(addr1, addr2, 8) == 0) {
400 bus = sd->bus;
401 target = sd->target;
402 lun = scsi3addr[4];
403 break;
404 }
405 }
406 }
407
408 sd = &ccissscsi[ctlr].dev[n];
409 if (lun == 0) {
410 if (find_bus_target_lun(ctlr,
411 &sd->bus, &sd->target, &sd->lun) != 0)
412 return -1;
413 } else {
414 sd->bus = bus;
415 sd->target = target;
416 sd->lun = lun;
417 }
Mike Millerf4a93bc2008-08-04 11:54:53 +0200418 added[*nadded].bus = sd->bus;
419 added[*nadded].target = sd->target;
420 added[*nadded].lun = sd->lun;
421 (*nadded)++;
422
Linus Torvalds1da177e2005-04-16 15:20:36 -0700423 memcpy(&sd->scsi3addr[0], scsi3addr, 8);
424 sd->devtype = devtype;
425 ccissscsi[ctlr].ndevices++;
426
427 /* initially, (before registering with scsi layer) we don't
428 know our hostno and we don't want to print anything first
429 time anyway (the scsi layer's inquiries will show that info) */
430 if (hostno != -1)
431 printk("cciss%d: %s device c%db%dt%dl%d added.\n",
Matthew Wilcox4ff36712006-07-04 12:15:20 -0600432 ctlr, scsi_device_type(sd->devtype), hostno,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700433 sd->bus, sd->target, sd->lun);
434 return 0;
435}
436
437static void
Mike Millerf4a93bc2008-08-04 11:54:53 +0200438cciss_scsi_remove_entry(int ctlr, int hostno, int entry,
439 struct scsi2map *removed, int *nremoved)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700440{
441 /* assumes hba[ctlr]->scsi_ctlr->lock is held */
442 int i;
443 struct cciss_scsi_dev_t sd;
444
445 if (entry < 0 || entry >= CCISS_MAX_SCSI_DEVS_PER_HBA) return;
446 sd = ccissscsi[ctlr].dev[entry];
Mike Millerf4a93bc2008-08-04 11:54:53 +0200447 removed[*nremoved].bus = sd.bus;
448 removed[*nremoved].target = sd.target;
449 removed[*nremoved].lun = sd.lun;
450 (*nremoved)++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700451 for (i=entry;i<ccissscsi[ctlr].ndevices-1;i++)
452 ccissscsi[ctlr].dev[i] = ccissscsi[ctlr].dev[i+1];
453 ccissscsi[ctlr].ndevices--;
454 printk("cciss%d: %s device c%db%dt%dl%d removed.\n",
Matthew Wilcox4ff36712006-07-04 12:15:20 -0600455 ctlr, scsi_device_type(sd.devtype), hostno,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456 sd.bus, sd.target, sd.lun);
457}
458
459
460#define SCSI3ADDR_EQ(a,b) ( \
461 (a)[7] == (b)[7] && \
462 (a)[6] == (b)[6] && \
463 (a)[5] == (b)[5] && \
464 (a)[4] == (b)[4] && \
465 (a)[3] == (b)[3] && \
466 (a)[2] == (b)[2] && \
467 (a)[1] == (b)[1] && \
468 (a)[0] == (b)[0])
469
Mike Millerf4a93bc2008-08-04 11:54:53 +0200470static void fixup_botched_add(int ctlr, char *scsi3addr)
471{
472 /* called when scsi_add_device fails in order to re-adjust */
473 /* ccissscsi[] to match the mid layer's view. */
474 unsigned long flags;
475 int i, j;
476 CPQ_TAPE_LOCK(ctlr, flags);
477 for (i = 0; i < ccissscsi[ctlr].ndevices; i++) {
478 if (memcmp(scsi3addr,
479 ccissscsi[ctlr].dev[i].scsi3addr, 8) == 0) {
480 for (j = i; j < ccissscsi[ctlr].ndevices-1; j++)
481 ccissscsi[ctlr].dev[j] =
482 ccissscsi[ctlr].dev[j+1];
483 ccissscsi[ctlr].ndevices--;
484 break;
485 }
486 }
487 CPQ_TAPE_UNLOCK(ctlr, flags);
488}
489
Linus Torvalds1da177e2005-04-16 15:20:36 -0700490static int
491adjust_cciss_scsi_table(int ctlr, int hostno,
492 struct cciss_scsi_dev_t sd[], int nsds)
493{
494 /* sd contains scsi3 addresses and devtypes, but
495 bus target and lun are not filled in. This funciton
496 takes what's in sd to be the current and adjusts
497 ccissscsi[] to be in line with what's in sd. */
498
499 int i,j, found, changes=0;
500 struct cciss_scsi_dev_t *csd;
501 unsigned long flags;
Mike Millerf4a93bc2008-08-04 11:54:53 +0200502 struct scsi2map *added, *removed;
503 int nadded, nremoved;
504 struct Scsi_Host *sh = NULL;
505
506 added = kzalloc(sizeof(*added) * CCISS_MAX_SCSI_DEVS_PER_HBA,
507 GFP_KERNEL);
508 removed = kzalloc(sizeof(*removed) * CCISS_MAX_SCSI_DEVS_PER_HBA,
509 GFP_KERNEL);
510
511 if (!added || !removed) {
512 printk(KERN_WARNING "cciss%d: Out of memory in "
513 "adjust_cciss_scsi_table\n", ctlr);
514 goto free_and_out;
515 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700516
517 CPQ_TAPE_LOCK(ctlr, flags);
518
Mike Millerf4a93bc2008-08-04 11:54:53 +0200519 if (hostno != -1) /* if it's not the first time... */
520 sh = ((struct cciss_scsi_adapter_data_t *)
521 hba[ctlr]->scsi_ctlr)->scsi_host;
522
Linus Torvalds1da177e2005-04-16 15:20:36 -0700523 /* find any devices in ccissscsi[] that are not in
524 sd[] and remove them from ccissscsi[] */
525
526 i = 0;
Mike Millerf4a93bc2008-08-04 11:54:53 +0200527 nremoved = 0;
528 nadded = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700529 while(i<ccissscsi[ctlr].ndevices) {
530 csd = &ccissscsi[ctlr].dev[i];
531 found=0;
532 for (j=0;j<nsds;j++) {
533 if (SCSI3ADDR_EQ(sd[j].scsi3addr,
534 csd->scsi3addr)) {
535 if (sd[j].devtype == csd->devtype)
536 found=2;
537 else
538 found=1;
539 break;
540 }
541 }
542
543 if (found == 0) { /* device no longer present. */
544 changes++;
545 /* printk("cciss%d: %s device c%db%dt%dl%d removed.\n",
Matthew Wilcox4ff36712006-07-04 12:15:20 -0600546 ctlr, scsi_device_type(csd->devtype), hostno,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700547 csd->bus, csd->target, csd->lun); */
Mike Millerf4a93bc2008-08-04 11:54:53 +0200548 cciss_scsi_remove_entry(ctlr, hostno, i,
549 removed, &nremoved);
550 /* remove ^^^, hence i not incremented */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700551 }
552 else if (found == 1) { /* device is different kind */
553 changes++;
554 printk("cciss%d: device c%db%dt%dl%d type changed "
555 "(device type now %s).\n",
556 ctlr, hostno, csd->bus, csd->target, csd->lun,
Matthew Wilcox4ff36712006-07-04 12:15:20 -0600557 scsi_device_type(csd->devtype));
Mike Millerf4a93bc2008-08-04 11:54:53 +0200558 cciss_scsi_remove_entry(ctlr, hostno, i,
559 removed, &nremoved);
560 /* remove ^^^, hence i not incremented */
561 if (cciss_scsi_add_entry(ctlr, hostno,
562 &sd[j].scsi3addr[0], sd[j].devtype,
563 added, &nadded) != 0)
564 /* we just removed one, so add can't fail. */
565 BUG();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 csd->devtype = sd[j].devtype;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700567 } else /* device is same as it ever was, */
568 i++; /* so just move along. */
569 }
570
571 /* Now, make sure every device listed in sd[] is also
572 listed in ccissscsi[], adding them if they aren't found */
573
574 for (i=0;i<nsds;i++) {
575 found=0;
576 for (j=0;j<ccissscsi[ctlr].ndevices;j++) {
577 csd = &ccissscsi[ctlr].dev[j];
578 if (SCSI3ADDR_EQ(sd[i].scsi3addr,
579 csd->scsi3addr)) {
580 if (sd[i].devtype == csd->devtype)
581 found=2; /* found device */
582 else
583 found=1; /* found a bug. */
584 break;
585 }
586 }
587 if (!found) {
588 changes++;
589 if (cciss_scsi_add_entry(ctlr, hostno,
Mike Millerf4a93bc2008-08-04 11:54:53 +0200590
591 &sd[i].scsi3addr[0], sd[i].devtype,
592 added, &nadded) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700593 break;
594 } else if (found == 1) {
595 /* should never happen... */
596 changes++;
597 printk("cciss%d: device unexpectedly changed type\n",
598 ctlr);
599 /* but if it does happen, we just ignore that device */
600 }
601 }
602 CPQ_TAPE_UNLOCK(ctlr, flags);
603
Mike Millerf4a93bc2008-08-04 11:54:53 +0200604 /* Don't notify scsi mid layer of any changes the first time through */
605 /* (or if there are no changes) scsi_scan_host will do it later the */
606 /* first time through. */
607 if (hostno == -1 || !changes)
608 goto free_and_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609
Mike Millerf4a93bc2008-08-04 11:54:53 +0200610 /* Notify scsi mid layer of any removed devices */
611 for (i = 0; i < nremoved; i++) {
612 struct scsi_device *sdev =
613 scsi_device_lookup(sh, removed[i].bus,
614 removed[i].target, removed[i].lun);
615 if (sdev != NULL) {
616 scsi_remove_device(sdev);
617 scsi_device_put(sdev);
618 } else {
619 /* We don't expect to get here. */
620 /* future cmds to this device will get selection */
621 /* timeout as if the device was gone. */
622 printk(KERN_WARNING "cciss%d: didn't find "
623 "c%db%dt%dl%d\n for removal.",
624 ctlr, hostno, removed[i].bus,
625 removed[i].target, removed[i].lun);
626 }
627 }
628
629 /* Notify scsi mid layer of any added devices */
630 for (i = 0; i < nadded; i++) {
631 int rc;
632 rc = scsi_add_device(sh, added[i].bus,
633 added[i].target, added[i].lun);
634 if (rc == 0)
635 continue;
636 printk(KERN_WARNING "cciss%d: scsi_add_device "
637 "c%db%dt%dl%d failed, device not added.\n",
638 ctlr, hostno,
639 added[i].bus, added[i].target, added[i].lun);
640 /* now we have to remove it from ccissscsi, */
641 /* since it didn't get added to scsi mid layer */
642 fixup_botched_add(ctlr, added[i].scsi3addr);
643 }
644
645free_and_out:
646 kfree(added);
647 kfree(removed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700648 return 0;
649}
650
651static int
652lookup_scsi3addr(int ctlr, int bus, int target, int lun, char *scsi3addr)
653{
654 int i;
655 struct cciss_scsi_dev_t *sd;
656 unsigned long flags;
657
658 CPQ_TAPE_LOCK(ctlr, flags);
659 for (i=0;i<ccissscsi[ctlr].ndevices;i++) {
660 sd = &ccissscsi[ctlr].dev[i];
661 if (sd->bus == bus &&
662 sd->target == target &&
663 sd->lun == lun) {
664 memcpy(scsi3addr, &sd->scsi3addr[0], 8);
665 CPQ_TAPE_UNLOCK(ctlr, flags);
666 return 0;
667 }
668 }
669 CPQ_TAPE_UNLOCK(ctlr, flags);
670 return -1;
671}
672
673static void
674cciss_scsi_setup(int cntl_num)
675{
676 struct cciss_scsi_adapter_data_t * shba;
677
678 ccissscsi[cntl_num].ndevices = 0;
679 shba = (struct cciss_scsi_adapter_data_t *)
680 kmalloc(sizeof(*shba), GFP_KERNEL);
681 if (shba == NULL)
682 return;
683 shba->scsi_host = NULL;
684 spin_lock_init(&shba->lock);
685 shba->registered = 0;
686 if (scsi_cmd_stack_setup(cntl_num, shba) != 0) {
687 kfree(shba);
688 shba = NULL;
689 }
690 hba[cntl_num]->scsi_ctlr = (void *) shba;
691 return;
692}
693
694static void
695complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag)
696{
697 struct scsi_cmnd *cmd;
698 ctlr_info_t *ctlr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700699 ErrorInfo_struct *ei;
700
701 ei = cp->err_info;
702
703 /* First, see if it was a message rather than a command */
704 if (cp->Request.Type.Type == TYPE_MSG) {
705 cp->cmd_type = CMD_MSG_DONE;
706 return;
707 }
708
709 cmd = (struct scsi_cmnd *) cp->scsi_cmd;
710 ctlr = hba[cp->ctlr];
711
FUJITA Tomonori41ce6392007-05-26 02:45:17 +0900712 scsi_dma_unmap(cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700713
714 cmd->result = (DID_OK << 16); /* host byte */
715 cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
716 /* cmd->result |= (GOOD < 1); */ /* status byte */
717
718 cmd->result |= (ei->ScsiStatus);
719 /* printk("Scsistatus is 0x%02x\n", ei->ScsiStatus); */
720
721 /* copy the sense data whether we need to or not. */
722
723 memcpy(cmd->sense_buffer, ei->SenseInfo,
724 ei->SenseLen > SCSI_SENSE_BUFFERSIZE ?
725 SCSI_SENSE_BUFFERSIZE :
726 ei->SenseLen);
FUJITA Tomonori41ce6392007-05-26 02:45:17 +0900727 scsi_set_resid(cmd, ei->ResidualCnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700728
729 if(ei->CommandStatus != 0)
730 { /* an error has occurred */
731 switch(ei->CommandStatus)
732 {
733 case CMD_TARGET_STATUS:
734 /* Pass it up to the upper layers... */
735 if( ei->ScsiStatus)
736 {
737#if 0
738 printk(KERN_WARNING "cciss: cmd %p "
739 "has SCSI Status = %x\n",
740 cp,
741 ei->ScsiStatus);
742#endif
743 cmd->result |= (ei->ScsiStatus < 1);
744 }
745 else { /* scsi status is zero??? How??? */
746
747 /* Ordinarily, this case should never happen, but there is a bug
748 in some released firmware revisions that allows it to happen
749 if, for example, a 4100 backplane loses power and the tape
750 drive is in it. We assume that it's a fatal error of some
751 kind because we can't show that it wasn't. We will make it
752 look like selection timeout since that is the most common
753 reason for this to occur, and it's severe enough. */
754
755 cmd->result = DID_NO_CONNECT << 16;
756 }
757 break;
758 case CMD_DATA_UNDERRUN: /* let mid layer handle it. */
759 break;
760 case CMD_DATA_OVERRUN:
761 printk(KERN_WARNING "cciss: cp %p has"
762 " completed with data overrun "
763 "reported\n", cp);
764 break;
765 case CMD_INVALID: {
766 /* print_bytes(cp, sizeof(*cp), 1, 0);
767 print_cmd(cp); */
768 /* We get CMD_INVALID if you address a non-existent tape drive instead
769 of a selection timeout (no response). You will see this if you yank
770 out a tape drive, then try to access it. This is kind of a shame
771 because it means that any other CMD_INVALID (e.g. driver bug) will
772 get interpreted as a missing target. */
773 cmd->result = DID_NO_CONNECT << 16;
774 }
775 break;
776 case CMD_PROTOCOL_ERR:
777 printk(KERN_WARNING "cciss: cp %p has "
778 "protocol error \n", cp);
779 break;
780 case CMD_HARDWARE_ERR:
781 cmd->result = DID_ERROR << 16;
782 printk(KERN_WARNING "cciss: cp %p had "
783 " hardware error\n", cp);
784 break;
785 case CMD_CONNECTION_LOST:
786 cmd->result = DID_ERROR << 16;
787 printk(KERN_WARNING "cciss: cp %p had "
788 "connection lost\n", cp);
789 break;
790 case CMD_ABORTED:
791 cmd->result = DID_ABORT << 16;
792 printk(KERN_WARNING "cciss: cp %p was "
793 "aborted\n", cp);
794 break;
795 case CMD_ABORT_FAILED:
796 cmd->result = DID_ERROR << 16;
797 printk(KERN_WARNING "cciss: cp %p reports "
798 "abort failed\n", cp);
799 break;
800 case CMD_UNSOLICITED_ABORT:
801 cmd->result = DID_ABORT << 16;
802 printk(KERN_WARNING "cciss: cp %p aborted "
803 "do to an unsolicited abort\n", cp);
804 break;
805 case CMD_TIMEOUT:
806 cmd->result = DID_TIME_OUT << 16;
807 printk(KERN_WARNING "cciss: cp %p timedout\n",
808 cp);
809 break;
810 default:
811 cmd->result = DID_ERROR << 16;
812 printk(KERN_WARNING "cciss: cp %p returned "
813 "unknown status %x\n", cp,
814 ei->CommandStatus);
815 }
816 }
817 // printk("c:%p:c%db%dt%dl%d ", cmd, ctlr->ctlr, cmd->channel,
818 // cmd->target, cmd->lun);
819 cmd->scsi_done(cmd);
820 scsi_cmd_free(ctlr, cp);
821}
822
823static int
824cciss_scsi_detect(int ctlr)
825{
826 struct Scsi_Host *sh;
827 int error;
828
829 sh = scsi_host_alloc(&cciss_driver_template, sizeof(struct ctlr_info *));
830 if (sh == NULL)
831 goto fail;
832 sh->io_port = 0; // good enough? FIXME,
833 sh->n_io_port = 0; // I don't think we use these two...
834 sh->this_id = SELF_SCSI_ID;
835
836 ((struct cciss_scsi_adapter_data_t *)
837 hba[ctlr]->scsi_ctlr)->scsi_host = (void *) sh;
838 sh->hostdata[0] = (unsigned long) hba[ctlr];
Mike Millerfb86a352006-01-08 01:03:50 -0800839 sh->irq = hba[ctlr]->intr[SIMPLE_MODE_INT];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700840 sh->unique_id = sh->irq;
841 error = scsi_add_host(sh, &hba[ctlr]->pdev->dev);
842 if (error)
843 goto fail_host_put;
844 scsi_scan_host(sh);
845 return 1;
846
847 fail_host_put:
848 scsi_host_put(sh);
849 fail:
850 return 0;
851}
852
853static void
854cciss_unmap_one(struct pci_dev *pdev,
855 CommandList_struct *cp,
856 size_t buflen,
857 int data_direction)
858{
859 u64bit addr64;
860
861 addr64.val32.lower = cp->SG[0].Addr.lower;
862 addr64.val32.upper = cp->SG[0].Addr.upper;
863 pci_unmap_single(pdev, (dma_addr_t) addr64.val, buflen, data_direction);
864}
865
866static void
867cciss_map_one(struct pci_dev *pdev,
868 CommandList_struct *cp,
869 unsigned char *buf,
870 size_t buflen,
871 int data_direction)
872{
873 __u64 addr64;
874
875 addr64 = (__u64) pci_map_single(pdev, buf, buflen, data_direction);
876 cp->SG[0].Addr.lower =
877 (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
878 cp->SG[0].Addr.upper =
879 (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
880 cp->SG[0].Len = buflen;
881 cp->Header.SGList = (__u8) 1; /* no. SGs contig in this cmd */
882 cp->Header.SGTotal = (__u16) 1; /* total sgs in this cmd list */
883}
884
885static int
886cciss_scsi_do_simple_cmd(ctlr_info_t *c,
887 CommandList_struct *cp,
888 unsigned char *scsi3addr,
889 unsigned char *cdb,
890 unsigned char cdblen,
891 unsigned char *buf, int bufsize,
892 int direction)
893{
894 unsigned long flags;
Peter Zijlstra6e9a4732006-09-30 23:28:10 -0700895 DECLARE_COMPLETION_ONSTACK(wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700896
897 cp->cmd_type = CMD_IOCTL_PEND; // treat this like an ioctl
898 cp->scsi_cmd = NULL;
899 cp->Header.ReplyQueue = 0; // unused in simple mode
900 memcpy(&cp->Header.LUN, scsi3addr, sizeof(cp->Header.LUN));
901 cp->Header.Tag.lower = cp->busaddr; // Use k. address of cmd as tag
902 // Fill in the request block...
903
904 /* printk("Using scsi3addr 0x%02x%0x2%0x2%0x2%0x2%0x2%0x2%0x2\n",
905 scsi3addr[0], scsi3addr[1], scsi3addr[2], scsi3addr[3],
906 scsi3addr[4], scsi3addr[5], scsi3addr[6], scsi3addr[7]); */
907
908 memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB));
909 memcpy(cp->Request.CDB, cdb, cdblen);
910 cp->Request.Timeout = 0;
911 cp->Request.CDBLen = cdblen;
912 cp->Request.Type.Type = TYPE_CMD;
913 cp->Request.Type.Attribute = ATTR_SIMPLE;
914 cp->Request.Type.Direction = direction;
915
916 /* Fill in the SG list and do dma mapping */
917 cciss_map_one(c->pdev, cp, (unsigned char *) buf,
918 bufsize, DMA_FROM_DEVICE);
919
920 cp->waiting = &wait;
921
922 /* Put the request on the tail of the request queue */
923 spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
924 addQ(&c->reqQ, cp);
925 c->Qdepth++;
926 start_io(c);
927 spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
928
929 wait_for_completion(&wait);
930
931 /* undo the dma mapping */
932 cciss_unmap_one(c->pdev, cp, bufsize, DMA_FROM_DEVICE);
933 return(0);
934}
935
936static void
937cciss_scsi_interpret_error(CommandList_struct *cp)
938{
939 ErrorInfo_struct *ei;
940
941 ei = cp->err_info;
942 switch(ei->CommandStatus)
943 {
944 case CMD_TARGET_STATUS:
945 printk(KERN_WARNING "cciss: cmd %p has "
946 "completed with errors\n", cp);
947 printk(KERN_WARNING "cciss: cmd %p "
948 "has SCSI Status = %x\n",
949 cp,
950 ei->ScsiStatus);
951 if (ei->ScsiStatus == 0)
952 printk(KERN_WARNING
953 "cciss:SCSI status is abnormally zero. "
954 "(probably indicates selection timeout "
955 "reported incorrectly due to a known "
956 "firmware bug, circa July, 2001.)\n");
957 break;
958 case CMD_DATA_UNDERRUN: /* let mid layer handle it. */
959 printk("UNDERRUN\n");
960 break;
961 case CMD_DATA_OVERRUN:
962 printk(KERN_WARNING "cciss: cp %p has"
963 " completed with data overrun "
964 "reported\n", cp);
965 break;
966 case CMD_INVALID: {
967 /* controller unfortunately reports SCSI passthru's */
968 /* to non-existent targets as invalid commands. */
969 printk(KERN_WARNING "cciss: cp %p is "
970 "reported invalid (probably means "
971 "target device no longer present)\n",
972 cp);
973 /* print_bytes((unsigned char *) cp, sizeof(*cp), 1, 0);
974 print_cmd(cp); */
975 }
976 break;
977 case CMD_PROTOCOL_ERR:
978 printk(KERN_WARNING "cciss: cp %p has "
979 "protocol error \n", cp);
980 break;
981 case CMD_HARDWARE_ERR:
982 /* cmd->result = DID_ERROR << 16; */
983 printk(KERN_WARNING "cciss: cp %p had "
984 " hardware error\n", cp);
985 break;
986 case CMD_CONNECTION_LOST:
987 printk(KERN_WARNING "cciss: cp %p had "
988 "connection lost\n", cp);
989 break;
990 case CMD_ABORTED:
991 printk(KERN_WARNING "cciss: cp %p was "
992 "aborted\n", cp);
993 break;
994 case CMD_ABORT_FAILED:
995 printk(KERN_WARNING "cciss: cp %p reports "
996 "abort failed\n", cp);
997 break;
998 case CMD_UNSOLICITED_ABORT:
999 printk(KERN_WARNING "cciss: cp %p aborted "
1000 "do to an unsolicited abort\n", cp);
1001 break;
1002 case CMD_TIMEOUT:
1003 printk(KERN_WARNING "cciss: cp %p timedout\n",
1004 cp);
1005 break;
1006 default:
1007 printk(KERN_WARNING "cciss: cp %p returned "
1008 "unknown status %x\n", cp,
1009 ei->CommandStatus);
1010 }
1011}
1012
1013static int
1014cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr,
Mike Miller47922d02005-09-13 01:25:25 -07001015 unsigned char *buf, unsigned char bufsize)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001016{
1017 int rc;
1018 CommandList_struct *cp;
1019 char cdb[6];
1020 ErrorInfo_struct *ei;
1021 unsigned long flags;
1022
1023 spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
1024 cp = scsi_cmd_alloc(c);
1025 spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
1026
1027 if (cp == NULL) { /* trouble... */
1028 printk("cmd_alloc returned NULL!\n");
1029 return -1;
1030 }
1031
1032 ei = cp->err_info;
1033
1034 cdb[0] = CISS_INQUIRY;
1035 cdb[1] = 0;
1036 cdb[2] = 0;
1037 cdb[3] = 0;
Mike Miller47922d02005-09-13 01:25:25 -07001038 cdb[4] = bufsize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001039 cdb[5] = 0;
1040 rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr, cdb,
Mike Miller47922d02005-09-13 01:25:25 -07001041 6, buf, bufsize, XFER_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001042
1043 if (rc != 0) return rc; /* something went wrong */
1044
1045 if (ei->CommandStatus != 0 &&
1046 ei->CommandStatus != CMD_DATA_UNDERRUN) {
1047 cciss_scsi_interpret_error(cp);
1048 rc = -1;
1049 }
1050 spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
1051 scsi_cmd_free(c, cp);
1052 spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
1053 return rc;
1054}
1055
1056static int
1057cciss_scsi_do_report_phys_luns(ctlr_info_t *c,
1058 ReportLunData_struct *buf, int bufsize)
1059{
1060 int rc;
1061 CommandList_struct *cp;
1062 unsigned char cdb[12];
1063 unsigned char scsi3addr[8];
1064 ErrorInfo_struct *ei;
1065 unsigned long flags;
1066
1067 spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
1068 cp = scsi_cmd_alloc(c);
1069 spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
1070 if (cp == NULL) { /* trouble... */
1071 printk("cmd_alloc returned NULL!\n");
1072 return -1;
1073 }
1074
1075 memset(&scsi3addr[0], 0, 8); /* address the controller */
1076 cdb[0] = CISS_REPORT_PHYS;
1077 cdb[1] = 0;
1078 cdb[2] = 0;
1079 cdb[3] = 0;
1080 cdb[4] = 0;
1081 cdb[5] = 0;
1082 cdb[6] = (bufsize >> 24) & 0xFF; //MSB
1083 cdb[7] = (bufsize >> 16) & 0xFF;
1084 cdb[8] = (bufsize >> 8) & 0xFF;
1085 cdb[9] = bufsize & 0xFF;
1086 cdb[10] = 0;
1087 cdb[11] = 0;
1088
1089 rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr,
1090 cdb, 12,
1091 (unsigned char *) buf,
1092 bufsize, XFER_READ);
1093
1094 if (rc != 0) return rc; /* something went wrong */
1095
1096 ei = cp->err_info;
1097 if (ei->CommandStatus != 0 &&
1098 ei->CommandStatus != CMD_DATA_UNDERRUN) {
1099 cciss_scsi_interpret_error(cp);
1100 rc = -1;
1101 }
1102 spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
1103 scsi_cmd_free(c, cp);
1104 spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
1105 return rc;
1106}
1107
1108static void
1109cciss_update_non_disk_devices(int cntl_num, int hostno)
1110{
1111 /* the idea here is we could get notified from /proc
1112 that some devices have changed, so we do a report
1113 physical luns cmd, and adjust our list of devices
1114 accordingly. (We can't rely on the scsi-mid layer just
1115 doing inquiries, because the "busses" that the scsi
1116 mid-layer probes are totally fabricated by this driver,
1117 so new devices wouldn't show up.
1118
1119 the scsi3addr's of devices won't change so long as the
1120 adapter is not reset. That means we can rescan and
1121 tell which devices we already know about, vs. new
1122 devices, vs. disappearing devices.
1123
1124 Also, if you yank out a tape drive, then put in a disk
1125 in it's place, (say, a configured volume from another
1126 array controller for instance) _don't_ poke this driver
1127 (so it thinks it's still a tape, but _do_ poke the scsi
1128 mid layer, so it does an inquiry... the scsi mid layer
1129 will see the physical disk. This would be bad. Need to
1130 think about how to prevent that. One idea would be to
1131 snoop all scsi responses and if an inquiry repsonse comes
1132 back that reports a disk, chuck it an return selection
1133 timeout instead and adjust our table... Not sure i like
1134 that though.
1135
1136 */
Mike Miller47922d02005-09-13 01:25:25 -07001137#define OBDR_TAPE_INQ_SIZE 49
1138#define OBDR_TAPE_SIG "$DR-10"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139 ReportLunData_struct *ld_buff;
Mike Miller47922d02005-09-13 01:25:25 -07001140 unsigned char *inq_buff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 unsigned char scsi3addr[8];
1142 ctlr_info_t *c;
1143 __u32 num_luns=0;
1144 unsigned char *ch;
1145 /* unsigned char found[CCISS_MAX_SCSI_DEVS_PER_HBA]; */
1146 struct cciss_scsi_dev_t currentsd[CCISS_MAX_SCSI_DEVS_PER_HBA];
1147 int ncurrent=0;
1148 int reportlunsize = sizeof(*ld_buff) + CISS_MAX_PHYS_LUN * 8;
1149 int i;
1150
1151 c = (ctlr_info_t *) hba[cntl_num];
Eric Sesterhenn06ff37f2006-03-08 11:21:52 +01001152 ld_buff = kzalloc(reportlunsize, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001153 if (ld_buff == NULL) {
1154 printk(KERN_ERR "cciss: out of memory\n");
1155 return;
1156 }
Mike Miller47922d02005-09-13 01:25:25 -07001157 inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001158 if (inq_buff == NULL) {
1159 printk(KERN_ERR "cciss: out of memory\n");
1160 kfree(ld_buff);
1161 return;
1162 }
1163
1164 if (cciss_scsi_do_report_phys_luns(c, ld_buff, reportlunsize) == 0) {
1165 ch = &ld_buff->LUNListLength[0];
1166 num_luns = ((ch[0]<<24) | (ch[1]<<16) | (ch[2]<<8) | ch[3]) / 8;
1167 if (num_luns > CISS_MAX_PHYS_LUN) {
1168 printk(KERN_WARNING
1169 "cciss: Maximum physical LUNs (%d) exceeded. "
1170 "%d LUNs ignored.\n", CISS_MAX_PHYS_LUN,
1171 num_luns - CISS_MAX_PHYS_LUN);
1172 num_luns = CISS_MAX_PHYS_LUN;
1173 }
1174 }
1175 else {
1176 printk(KERN_ERR "cciss: Report physical LUNs failed.\n");
1177 goto out;
1178 }
1179
1180
1181 /* adjust our table of devices */
1182 for(i=0; i<num_luns; i++)
1183 {
1184 int devtype;
1185
1186 /* for each physical lun, do an inquiry */
1187 if (ld_buff->LUN[i][3] & 0xC0) continue;
Mike Miller47922d02005-09-13 01:25:25 -07001188 memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001189 memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8);
1190
Mike Miller47922d02005-09-13 01:25:25 -07001191 if (cciss_scsi_do_inquiry(hba[cntl_num], scsi3addr, inq_buff,
1192 (unsigned char) OBDR_TAPE_INQ_SIZE) != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 /* Inquiry failed (msg printed already) */
1194 devtype = 0; /* so we will skip this device. */
1195 } else /* what kind of device is this? */
Mike Miller47922d02005-09-13 01:25:25 -07001196 devtype = (inq_buff[0] & 0x1f);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001197
1198 switch (devtype)
1199 {
Mike Miller47922d02005-09-13 01:25:25 -07001200 case 0x05: /* CD-ROM */ {
1201
1202 /* We don't *really* support actual CD-ROM devices,
1203 * just this "One Button Disaster Recovery" tape drive
1204 * which temporarily pretends to be a CD-ROM drive.
1205 * So we check that the device is really an OBDR tape
1206 * device by checking for "$DR-10" in bytes 43-48 of
1207 * the inquiry data.
1208 */
1209 char obdr_sig[7];
1210
1211 strncpy(obdr_sig, &inq_buff[43], 6);
1212 obdr_sig[6] = '\0';
1213 if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0)
1214 /* Not OBDR device, ignore it. */
1215 break;
1216 }
1217 /* fall through . . . */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 case 0x01: /* sequential access, (tape) */
1219 case 0x08: /* medium changer */
1220 if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) {
1221 printk(KERN_INFO "cciss%d: %s ignored, "
1222 "too many devices.\n", cntl_num,
Matthew Wilcox4ff36712006-07-04 12:15:20 -06001223 scsi_device_type(devtype));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224 break;
1225 }
1226 memcpy(&currentsd[ncurrent].scsi3addr[0],
1227 &scsi3addr[0], 8);
1228 currentsd[ncurrent].devtype = devtype;
1229 currentsd[ncurrent].bus = -1;
1230 currentsd[ncurrent].target = -1;
1231 currentsd[ncurrent].lun = -1;
1232 ncurrent++;
1233 break;
1234 default:
1235 break;
1236 }
1237 }
1238
1239 adjust_cciss_scsi_table(cntl_num, hostno, currentsd, ncurrent);
1240out:
1241 kfree(inq_buff);
1242 kfree(ld_buff);
1243 return;
1244}
1245
1246static int
1247is_keyword(char *ptr, int len, char *verb) // Thanks to ncr53c8xx.c
1248{
1249 int verb_len = strlen(verb);
1250 if (len >= verb_len && !memcmp(verb,ptr,verb_len))
1251 return verb_len;
1252 else
1253 return 0;
1254}
1255
1256static int
1257cciss_scsi_user_command(int ctlr, int hostno, char *buffer, int length)
1258{
1259 int arg_len;
1260
1261 if ((arg_len = is_keyword(buffer, length, "rescan")) != 0)
1262 cciss_update_non_disk_devices(ctlr, hostno);
1263 else
1264 return -EINVAL;
1265 return length;
1266}
1267
1268
1269static int
1270cciss_scsi_proc_info(struct Scsi_Host *sh,
1271 char *buffer, /* data buffer */
1272 char **start, /* where data in buffer starts */
1273 off_t offset, /* offset from start of imaginary file */
1274 int length, /* length of data in buffer */
1275 int func) /* 0 == read, 1 == write */
1276{
1277
1278 int buflen, datalen;
1279 ctlr_info_t *ci;
Mike Millerb9f0bd02005-09-13 01:25:26 -07001280 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001281 int cntl_num;
1282
1283
1284 ci = (ctlr_info_t *) sh->hostdata[0];
1285 if (ci == NULL) /* This really shouldn't ever happen. */
1286 return -EINVAL;
1287
1288 cntl_num = ci->ctlr; /* Get our index into the hba[] array */
1289
1290 if (func == 0) { /* User is reading from /proc/scsi/ciss*?/?* */
Mike Millerb9f0bd02005-09-13 01:25:26 -07001291 buflen = sprintf(buffer, "cciss%d: SCSI host: %d\n",
1292 cntl_num, sh->host_no);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001293
Mike Millerb9f0bd02005-09-13 01:25:26 -07001294 /* this information is needed by apps to know which cciss
1295 device corresponds to which scsi host number without
1296 having to open a scsi target device node. The device
1297 information is not a duplicate of /proc/scsi/scsi because
1298 the two may be out of sync due to scsi hotplug, rather
1299 this info is for an app to be able to use to know how to
1300 get them back in sync. */
1301
1302 for (i=0;i<ccissscsi[cntl_num].ndevices;i++) {
1303 struct cciss_scsi_dev_t *sd = &ccissscsi[cntl_num].dev[i];
1304 buflen += sprintf(&buffer[buflen], "c%db%dt%dl%d %02d "
1305 "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
1306 sh->host_no, sd->bus, sd->target, sd->lun,
1307 sd->devtype,
1308 sd->scsi3addr[0], sd->scsi3addr[1],
1309 sd->scsi3addr[2], sd->scsi3addr[3],
1310 sd->scsi3addr[4], sd->scsi3addr[5],
1311 sd->scsi3addr[6], sd->scsi3addr[7]);
1312 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001313 datalen = buflen - offset;
1314 if (datalen < 0) { /* they're reading past EOF. */
1315 datalen = 0;
1316 *start = buffer+buflen;
1317 } else
1318 *start = buffer + offset;
1319 return(datalen);
1320 } else /* User is writing to /proc/scsi/cciss*?/?* ... */
1321 return cciss_scsi_user_command(cntl_num, sh->host_no,
1322 buffer, length);
1323}
1324
1325/* cciss_scatter_gather takes a struct scsi_cmnd, (cmd), and does the pci
1326 dma mapping and fills in the scatter gather entries of the
1327 cciss command, cp. */
1328
1329static void
1330cciss_scatter_gather(struct pci_dev *pdev,
1331 CommandList_struct *cp,
1332 struct scsi_cmnd *cmd)
1333{
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001334 unsigned int len;
1335 struct scatterlist *sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001336 __u64 addr64;
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001337 int use_sg, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001339 BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001340
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001341 use_sg = scsi_dma_map(cmd);
1342 if (use_sg) { /* not too many addrs? */
1343 scsi_for_each_sg(cmd, sg, use_sg, i) {
1344 addr64 = (__u64) sg_dma_address(sg);
1345 len = sg_dma_len(sg);
1346 cp->SG[i].Addr.lower =
1347 (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
1348 cp->SG[i].Addr.upper =
1349 (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
1350 cp->SG[i].Len = len;
1351 cp->SG[i].Ext = 0; // we are not chaining
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352 }
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001353 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001355 cp->Header.SGList = (__u8) use_sg; /* no. SGs contig in this cmd */
1356 cp->Header.SGTotal = (__u16) use_sg; /* total sgs in this cmd list */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001357 return;
1358}
1359
1360
1361static int
1362cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
1363{
1364 ctlr_info_t **c;
1365 int ctlr, rc;
1366 unsigned char scsi3addr[8];
1367 CommandList_struct *cp;
1368 unsigned long flags;
1369
1370 // Get the ptr to our adapter structure (hba[i]) out of cmd->host.
1371 // We violate cmd->host privacy here. (Is there another way?)
1372 c = (ctlr_info_t **) &cmd->device->host->hostdata[0];
1373 ctlr = (*c)->ctlr;
1374
1375 rc = lookup_scsi3addr(ctlr, cmd->device->channel, cmd->device->id,
1376 cmd->device->lun, scsi3addr);
1377 if (rc != 0) {
1378 /* the scsi nexus does not match any that we presented... */
1379 /* pretend to mid layer that we got selection timeout */
1380 cmd->result = DID_NO_CONNECT << 16;
1381 done(cmd);
1382 /* we might want to think about registering controller itself
1383 as a processor device on the bus so sg binds to it. */
1384 return 0;
1385 }
1386
1387 /* printk("cciss_queue_command, p=%p, cmd=0x%02x, c%db%dt%dl%d\n",
1388 cmd, cmd->cmnd[0], ctlr, cmd->channel, cmd->target, cmd->lun);*/
1389 // printk("q:%p:c%db%dt%dl%d ", cmd, ctlr, cmd->channel,
1390 // cmd->target, cmd->lun);
1391
1392 /* Ok, we have a reasonable scsi nexus, so send the cmd down, and
1393 see what the device thinks of it. */
1394
1395 spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
1396 cp = scsi_cmd_alloc(*c);
1397 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
1398 if (cp == NULL) { /* trouble... */
1399 printk("scsi_cmd_alloc returned NULL!\n");
1400 /* FIXME: next 3 lines are -> BAD! <- */
1401 cmd->result = DID_NO_CONNECT << 16;
1402 done(cmd);
1403 return 0;
1404 }
1405
1406 // Fill in the command list header
1407
1408 cmd->scsi_done = done; // save this for use by completion code
1409
1410 // save cp in case we have to abort it
1411 cmd->host_scribble = (unsigned char *) cp;
1412
1413 cp->cmd_type = CMD_SCSI;
1414 cp->scsi_cmd = cmd;
1415 cp->Header.ReplyQueue = 0; // unused in simple mode
1416 memcpy(&cp->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8);
1417 cp->Header.Tag.lower = cp->busaddr; // Use k. address of cmd as tag
1418
1419 // Fill in the request block...
1420
1421 cp->Request.Timeout = 0;
1422 memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB));
Eric Sesterhenn089fe1b2006-03-24 18:50:27 +01001423 BUG_ON(cmd->cmd_len > sizeof(cp->Request.CDB));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001424 cp->Request.CDBLen = cmd->cmd_len;
1425 memcpy(cp->Request.CDB, cmd->cmnd, cmd->cmd_len);
1426 cp->Request.Type.Type = TYPE_CMD;
1427 cp->Request.Type.Attribute = ATTR_SIMPLE;
1428 switch(cmd->sc_data_direction)
1429 {
1430 case DMA_TO_DEVICE: cp->Request.Type.Direction = XFER_WRITE; break;
1431 case DMA_FROM_DEVICE: cp->Request.Type.Direction = XFER_READ; break;
1432 case DMA_NONE: cp->Request.Type.Direction = XFER_NONE; break;
1433 case DMA_BIDIRECTIONAL:
1434 // This can happen if a buggy application does a scsi passthru
1435 // and sets both inlen and outlen to non-zero. ( see
1436 // ../scsi/scsi_ioctl.c:scsi_ioctl_send_command() )
1437
1438 cp->Request.Type.Direction = XFER_RSVD;
1439 // This is technically wrong, and cciss controllers should
1440 // reject it with CMD_INVALID, which is the most correct
1441 // response, but non-fibre backends appear to let it
1442 // slide by, and give the same results as if this field
1443 // were set correctly. Either way is acceptable for
1444 // our purposes here.
1445
1446 break;
1447
1448 default:
1449 printk("cciss: unknown data direction: %d\n",
1450 cmd->sc_data_direction);
1451 BUG();
1452 break;
1453 }
1454
1455 cciss_scatter_gather((*c)->pdev, cp, cmd); // Fill the SG list
1456
1457 /* Put the request on the tail of the request queue */
1458
1459 spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
1460 addQ(&(*c)->reqQ, cp);
1461 (*c)->Qdepth++;
1462 start_io(*c);
1463 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
1464
1465 /* the cmd'll come back via intr handler in complete_scsi_command() */
1466 return 0;
1467}
1468
1469static void
1470cciss_unregister_scsi(int ctlr)
1471{
1472 struct cciss_scsi_adapter_data_t *sa;
1473 struct cciss_scsi_cmd_stack_t *stk;
1474 unsigned long flags;
1475
1476 /* we are being forcibly unloaded, and may not refuse. */
1477
1478 spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
1479 sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
1480 stk = &sa->cmd_stack;
1481
1482 /* if we weren't ever actually registered, don't unregister */
1483 if (sa->registered) {
1484 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
1485 scsi_remove_host(sa->scsi_host);
1486 scsi_host_put(sa->scsi_host);
1487 spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
1488 }
1489
1490 /* set scsi_host to NULL so our detect routine will
1491 find us on register */
1492 sa->scsi_host = NULL;
scameron@beardog.cca.cpqcorp.net61950572008-04-17 13:19:04 +02001493 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001494 scsi_cmd_stack_free(ctlr);
1495 kfree(sa);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001496}
1497
1498static int
Linus Torvalds1da177e2005-04-16 15:20:36 -07001499cciss_engage_scsi(int ctlr)
1500{
1501 struct cciss_scsi_adapter_data_t *sa;
1502 struct cciss_scsi_cmd_stack_t *stk;
1503 unsigned long flags;
1504
1505 spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
1506 sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
1507 stk = &sa->cmd_stack;
1508
Mike Millerf4a93bc2008-08-04 11:54:53 +02001509 if (sa->registered) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001510 printk("cciss%d: SCSI subsystem already engaged.\n", ctlr);
1511 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
1512 return ENXIO;
1513 }
Mike Millerf4a93bc2008-08-04 11:54:53 +02001514 sa->registered = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001515 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
1516 cciss_update_non_disk_devices(ctlr, -1);
Mike Millerf4a93bc2008-08-04 11:54:53 +02001517 cciss_scsi_detect(ctlr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001518 return 0;
1519}
1520
1521static void
Mike Miller89b6e742008-02-21 08:54:03 +01001522cciss_seq_tape_report(struct seq_file *seq, int ctlr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001523{
1524 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001525
1526 CPQ_TAPE_LOCK(ctlr, flags);
Mike Miller89b6e742008-02-21 08:54:03 +01001527 seq_printf(seq,
Mike Millerb9f0bd02005-09-13 01:25:26 -07001528 "Sequential access devices: %d\n\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001529 ccissscsi[ctlr].ndevices);
1530 CPQ_TAPE_UNLOCK(ctlr, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001531}
1532
Mike Miller89b6e742008-02-21 08:54:03 +01001533
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001534/* Need at least one of these error handlers to keep ../scsi/hosts.c from
1535 * complaining. Doing a host- or bus-reset can't do anything good here.
1536 * Despite what it might say in scsi_error.c, there may well be commands
1537 * on the controller, as the cciss driver registers twice, once as a block
1538 * device for the logical drives, and once as a scsi device, for any tape
1539 * drives. So we know there are no commands out on the tape drives, but we
1540 * don't know there are no commands on the controller, and it is likely
1541 * that there probably are, as the cciss block device is most commonly used
1542 * as a boot device (embedded controller on HP/Compaq systems.)
1543*/
1544
1545static int cciss_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
1546{
1547 int rc;
1548 CommandList_struct *cmd_in_trouble;
1549 ctlr_info_t **c;
1550 int ctlr;
1551
1552 /* find the controller to which the command to be aborted was sent */
1553 c = (ctlr_info_t **) &scsicmd->device->host->hostdata[0];
1554 if (c == NULL) /* paranoia */
1555 return FAILED;
1556 ctlr = (*c)->ctlr;
1557 printk(KERN_WARNING "cciss%d: resetting tape drive or medium changer.\n", ctlr);
1558
1559 /* find the command that's giving us trouble */
1560 cmd_in_trouble = (CommandList_struct *) scsicmd->host_scribble;
1561 if (cmd_in_trouble == NULL) { /* paranoia */
1562 return FAILED;
1563 }
1564 /* send a reset to the SCSI LUN which the command was sent to */
1565 rc = sendcmd(CCISS_RESET_MSG, ctlr, NULL, 0, 2, 0, 0,
1566 (unsigned char *) &cmd_in_trouble->Header.LUN.LunAddrBytes[0],
1567 TYPE_MSG);
Joe Perchesf66083c2008-02-03 17:09:38 +02001568 /* sendcmd turned off interrupts on the board, turn 'em back on. */
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001569 (*c)->access.set_intr_mask(*c, CCISS_INTR_ON);
1570 if (rc == 0)
1571 return SUCCESS;
1572 printk(KERN_WARNING "cciss%d: resetting device failed.\n", ctlr);
1573 return FAILED;
1574}
1575
1576static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd)
1577{
1578 int rc;
1579 CommandList_struct *cmd_to_abort;
1580 ctlr_info_t **c;
1581 int ctlr;
1582
1583 /* find the controller to which the command to be aborted was sent */
1584 c = (ctlr_info_t **) &scsicmd->device->host->hostdata[0];
1585 if (c == NULL) /* paranoia */
1586 return FAILED;
1587 ctlr = (*c)->ctlr;
1588 printk(KERN_WARNING "cciss%d: aborting tardy SCSI cmd\n", ctlr);
1589
1590 /* find the command to be aborted */
1591 cmd_to_abort = (CommandList_struct *) scsicmd->host_scribble;
1592 if (cmd_to_abort == NULL) /* paranoia */
1593 return FAILED;
1594 rc = sendcmd(CCISS_ABORT_MSG, ctlr, &cmd_to_abort->Header.Tag,
1595 0, 2, 0, 0,
1596 (unsigned char *) &cmd_to_abort->Header.LUN.LunAddrBytes[0],
1597 TYPE_MSG);
Joe Perchesf66083c2008-02-03 17:09:38 +02001598 /* sendcmd turned off interrupts on the board, turn 'em back on. */
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001599 (*c)->access.set_intr_mask(*c, CCISS_INTR_ON);
1600 if (rc == 0)
1601 return SUCCESS;
1602 return FAILED;
1603
1604}
1605
Linus Torvalds1da177e2005-04-16 15:20:36 -07001606#else /* no CONFIG_CISS_SCSI_TAPE */
1607
1608/* If no tape support, then these become defined out of existence */
1609
1610#define cciss_scsi_setup(cntl_num)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001611
1612#endif /* CONFIG_CISS_SCSI_TAPE */