blob: 8575c48c89170d4d9711b2099d3f27f6a9de3862 [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
Stephen M. Cameron88f627a2009-06-02 14:48:11 +020061static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff,
62 size_t size,
63 unsigned int use_unit_num, /* 0: address the controller,
64 1: address logical volume log_unit,
65 2: periph device address is scsi3addr */
66 unsigned int log_unit, __u8 page_code, unsigned char *scsi3addr,
67 int cmd_type);
68
69static int sendcmd_core(ctlr_info_t *h, CommandList_struct *c);
70
71static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool);
72static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool);
Linus Torvalds1da177e2005-04-16 15:20:36 -070073
74static int cciss_scsi_proc_info(
75 struct Scsi_Host *sh,
76 char *buffer, /* data buffer */
77 char **start, /* where data in buffer starts */
78 off_t offset, /* offset from start of imaginary file */
79 int length, /* length of data in buffer */
80 int func); /* 0 == read, 1 == write */
81
82static int cciss_scsi_queue_command (struct scsi_cmnd *cmd,
83 void (* done)(struct scsi_cmnd *));
mike.miller@hp.com3da8b712005-11-04 12:30:37 -060084static int cciss_eh_device_reset_handler(struct scsi_cmnd *);
85static int cciss_eh_abort_handler(struct scsi_cmnd *);
Linus Torvalds1da177e2005-04-16 15:20:36 -070086
87static struct cciss_scsi_hba_t ccissscsi[MAX_CTLR] = {
88 { .name = "cciss0", .ndevices = 0 },
89 { .name = "cciss1", .ndevices = 0 },
90 { .name = "cciss2", .ndevices = 0 },
91 { .name = "cciss3", .ndevices = 0 },
92 { .name = "cciss4", .ndevices = 0 },
93 { .name = "cciss5", .ndevices = 0 },
94 { .name = "cciss6", .ndevices = 0 },
95 { .name = "cciss7", .ndevices = 0 },
96};
97
98static struct scsi_host_template cciss_driver_template = {
99 .module = THIS_MODULE,
100 .name = "cciss",
101 .proc_name = "cciss",
102 .proc_info = cciss_scsi_proc_info,
103 .queuecommand = cciss_scsi_queue_command,
104 .can_queue = SCSI_CCISS_CAN_QUEUE,
105 .this_id = 7,
106 .sg_tablesize = MAXSGENTRIES,
107 .cmd_per_lun = 1,
108 .use_clustering = DISABLE_CLUSTERING,
mike.miller@hp.com3da8b712005-11-04 12:30:37 -0600109 /* Can't have eh_bus_reset_handler or eh_host_reset_handler for cciss */
110 .eh_device_reset_handler= cciss_eh_device_reset_handler,
111 .eh_abort_handler = cciss_eh_abort_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700112};
113
114#pragma pack(1)
115struct cciss_scsi_cmd_stack_elem_t {
116 CommandList_struct cmd;
117 ErrorInfo_struct Err;
118 __u32 busaddr;
Mike Miller33079b22005-09-13 01:25:22 -0700119 __u32 pad;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700120};
121
122#pragma pack()
123
124#define CMD_STACK_SIZE (SCSI_CCISS_CAN_QUEUE * \
125 CCISS_MAX_SCSI_DEVS_PER_HBA + 2)
126 // plus two for init time usage
127
128#pragma pack(1)
129struct cciss_scsi_cmd_stack_t {
130 struct cciss_scsi_cmd_stack_elem_t *pool;
131 struct cciss_scsi_cmd_stack_elem_t *elem[CMD_STACK_SIZE];
132 dma_addr_t cmd_pool_handle;
133 int top;
134};
135#pragma pack()
136
137struct cciss_scsi_adapter_data_t {
138 struct Scsi_Host *scsi_host;
139 struct cciss_scsi_cmd_stack_t cmd_stack;
140 int registered;
141 spinlock_t lock; // to protect ccissscsi[ctlr];
142};
143
144#define CPQ_TAPE_LOCK(ctlr, flags) spin_lock_irqsave( \
145 &(((struct cciss_scsi_adapter_data_t *) \
146 hba[ctlr]->scsi_ctlr)->lock), flags);
147#define CPQ_TAPE_UNLOCK(ctlr, flags) spin_unlock_irqrestore( \
148 &(((struct cciss_scsi_adapter_data_t *) \
149 hba[ctlr]->scsi_ctlr)->lock), flags);
150
151static CommandList_struct *
152scsi_cmd_alloc(ctlr_info_t *h)
153{
154 /* assume only one process in here at a time, locking done by caller. */
155 /* use CCISS_LOCK(ctlr) */
156 /* might be better to rewrite how we allocate scsi commands in a way that */
157 /* needs no locking at all. */
158
159 /* take the top memory chunk off the stack and return it, if any. */
160 struct cciss_scsi_cmd_stack_elem_t *c;
161 struct cciss_scsi_adapter_data_t *sa;
162 struct cciss_scsi_cmd_stack_t *stk;
163 u64bit temp64;
164
165 sa = (struct cciss_scsi_adapter_data_t *) h->scsi_ctlr;
166 stk = &sa->cmd_stack;
167
168 if (stk->top < 0)
169 return NULL;
170 c = stk->elem[stk->top];
171 /* memset(c, 0, sizeof(*c)); */
172 memset(&c->cmd, 0, sizeof(c->cmd));
173 memset(&c->Err, 0, sizeof(c->Err));
174 /* set physical addr of cmd and addr of scsi parameters */
175 c->cmd.busaddr = c->busaddr;
176 /* (__u32) (stk->cmd_pool_handle +
177 (sizeof(struct cciss_scsi_cmd_stack_elem_t)*stk->top)); */
178
179 temp64.val = (__u64) (c->busaddr + sizeof(CommandList_struct));
180 /* (__u64) (stk->cmd_pool_handle +
181 (sizeof(struct cciss_scsi_cmd_stack_elem_t)*stk->top) +
182 sizeof(CommandList_struct)); */
183 stk->top--;
184 c->cmd.ErrDesc.Addr.lower = temp64.val32.lower;
185 c->cmd.ErrDesc.Addr.upper = temp64.val32.upper;
186 c->cmd.ErrDesc.Len = sizeof(ErrorInfo_struct);
187
188 c->cmd.ctlr = h->ctlr;
189 c->cmd.err_info = &c->Err;
190
191 return (CommandList_struct *) c;
192}
193
194static void
195scsi_cmd_free(ctlr_info_t *h, CommandList_struct *cmd)
196{
197 /* assume only one process in here at a time, locking done by caller. */
198 /* use CCISS_LOCK(ctlr) */
199 /* drop the free memory chunk on top of the stack. */
200
201 struct cciss_scsi_adapter_data_t *sa;
202 struct cciss_scsi_cmd_stack_t *stk;
203
204 sa = (struct cciss_scsi_adapter_data_t *) h->scsi_ctlr;
205 stk = &sa->cmd_stack;
206 if (stk->top >= CMD_STACK_SIZE) {
207 printk("cciss: scsi_cmd_free called too many times.\n");
208 BUG();
209 }
210 stk->top++;
211 stk->elem[stk->top] = (struct cciss_scsi_cmd_stack_elem_t *) cmd;
212}
213
214static int
215scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa)
216{
217 int i;
218 struct cciss_scsi_cmd_stack_t *stk;
219 size_t size;
220
221 stk = &sa->cmd_stack;
222 size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;
223
224 // pci_alloc_consistent guarantees 32-bit DMA address will
225 // be used
226
227 stk->pool = (struct cciss_scsi_cmd_stack_elem_t *)
228 pci_alloc_consistent(hba[ctlr]->pdev, size, &stk->cmd_pool_handle);
229
230 if (stk->pool == NULL) {
231 printk("stk->pool is null\n");
232 return -1;
233 }
234
235 for (i=0; i<CMD_STACK_SIZE; i++) {
236 stk->elem[i] = &stk->pool[i];
237 stk->elem[i]->busaddr = (__u32) (stk->cmd_pool_handle +
238 (sizeof(struct cciss_scsi_cmd_stack_elem_t) * i));
239 }
240 stk->top = CMD_STACK_SIZE-1;
241 return 0;
242}
243
244static void
245scsi_cmd_stack_free(int ctlr)
246{
247 struct cciss_scsi_adapter_data_t *sa;
248 struct cciss_scsi_cmd_stack_t *stk;
249 size_t size;
250
251 sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
252 stk = &sa->cmd_stack;
253 if (stk->top != CMD_STACK_SIZE-1) {
254 printk( "cciss: %d scsi commands are still outstanding.\n",
255 CMD_STACK_SIZE - stk->top);
256 // BUG();
257 printk("WE HAVE A BUG HERE!!! stk=0x%p\n", stk);
258 }
259 size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;
260
261 pci_free_consistent(hba[ctlr]->pdev, size, stk->pool, stk->cmd_pool_handle);
262 stk->pool = NULL;
263}
264
Grant Coady400bb232005-11-15 00:09:20 -0800265#if 0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700266static int xmargin=8;
267static int amargin=60;
268
269static void
270print_bytes (unsigned char *c, int len, int hex, int ascii)
271{
272
273 int i;
274 unsigned char *x;
275
276 if (hex)
277 {
278 x = c;
279 for (i=0;i<len;i++)
280 {
281 if ((i % xmargin) == 0 && i>0) printk("\n");
282 if ((i % xmargin) == 0) printk("0x%04x:", i);
283 printk(" %02x", *x);
284 x++;
285 }
286 printk("\n");
287 }
288 if (ascii)
289 {
290 x = c;
291 for (i=0;i<len;i++)
292 {
293 if ((i % amargin) == 0 && i>0) printk("\n");
294 if ((i % amargin) == 0) printk("0x%04x:", i);
295 if (*x > 26 && *x < 128) printk("%c", *x);
296 else printk(".");
297 x++;
298 }
299 printk("\n");
300 }
301}
302
303static void
304print_cmd(CommandList_struct *cp)
305{
306 printk("queue:%d\n", cp->Header.ReplyQueue);
307 printk("sglist:%d\n", cp->Header.SGList);
308 printk("sgtot:%d\n", cp->Header.SGTotal);
309 printk("Tag:0x%08x/0x%08x\n", cp->Header.Tag.upper,
310 cp->Header.Tag.lower);
311 printk("LUN:0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
312 cp->Header.LUN.LunAddrBytes[0],
313 cp->Header.LUN.LunAddrBytes[1],
314 cp->Header.LUN.LunAddrBytes[2],
315 cp->Header.LUN.LunAddrBytes[3],
316 cp->Header.LUN.LunAddrBytes[4],
317 cp->Header.LUN.LunAddrBytes[5],
318 cp->Header.LUN.LunAddrBytes[6],
319 cp->Header.LUN.LunAddrBytes[7]);
320 printk("CDBLen:%d\n", cp->Request.CDBLen);
321 printk("Type:%d\n",cp->Request.Type.Type);
322 printk("Attr:%d\n",cp->Request.Type.Attribute);
323 printk(" Dir:%d\n",cp->Request.Type.Direction);
324 printk("Timeout:%d\n",cp->Request.Timeout);
325 printk( "CDB: %02x %02x %02x %02x %02x %02x %02x %02x"
326 " %02x %02x %02x %02x %02x %02x %02x %02x\n",
327 cp->Request.CDB[0], cp->Request.CDB[1],
328 cp->Request.CDB[2], cp->Request.CDB[3],
329 cp->Request.CDB[4], cp->Request.CDB[5],
330 cp->Request.CDB[6], cp->Request.CDB[7],
331 cp->Request.CDB[8], cp->Request.CDB[9],
332 cp->Request.CDB[10], cp->Request.CDB[11],
333 cp->Request.CDB[12], cp->Request.CDB[13],
334 cp->Request.CDB[14], cp->Request.CDB[15]),
335 printk("edesc.Addr: 0x%08x/0%08x, Len = %d\n",
336 cp->ErrDesc.Addr.upper, cp->ErrDesc.Addr.lower,
337 cp->ErrDesc.Len);
338 printk("sgs..........Errorinfo:\n");
339 printk("scsistatus:%d\n", cp->err_info->ScsiStatus);
340 printk("senselen:%d\n", cp->err_info->SenseLen);
341 printk("cmd status:%d\n", cp->err_info->CommandStatus);
342 printk("resid cnt:%d\n", cp->err_info->ResidualCnt);
343 printk("offense size:%d\n", cp->err_info->MoreErrInfo.Invalid_Cmd.offense_size);
344 printk("offense byte:%d\n", cp->err_info->MoreErrInfo.Invalid_Cmd.offense_num);
345 printk("offense value:%d\n", cp->err_info->MoreErrInfo.Invalid_Cmd.offense_value);
346
347}
348
349#endif
350
351static int
352find_bus_target_lun(int ctlr, int *bus, int *target, int *lun)
353{
354 /* finds an unused bus, target, lun for a new device */
355 /* assumes hba[ctlr]->scsi_ctlr->lock is held */
356 int i, found=0;
357 unsigned char target_taken[CCISS_MAX_SCSI_DEVS_PER_HBA];
358
359 memset(&target_taken[0], 0, CCISS_MAX_SCSI_DEVS_PER_HBA);
360
361 target_taken[SELF_SCSI_ID] = 1;
362 for (i=0;i<ccissscsi[ctlr].ndevices;i++)
363 target_taken[ccissscsi[ctlr].dev[i].target] = 1;
364
365 for (i=0;i<CCISS_MAX_SCSI_DEVS_PER_HBA;i++) {
366 if (!target_taken[i]) {
367 *bus = 0; *target=i; *lun = 0; found=1;
368 break;
369 }
370 }
371 return (!found);
372}
Mike Millerf4a93bc2008-08-04 11:54:53 +0200373struct scsi2map {
374 char scsi3addr[8];
375 int bus, target, lun;
376};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700377
378static int
379cciss_scsi_add_entry(int ctlr, int hostno,
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700380 struct cciss_scsi_dev_t *device,
Mike Millerf4a93bc2008-08-04 11:54:53 +0200381 struct scsi2map *added, int *nadded)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700382{
383 /* assumes hba[ctlr]->scsi_ctlr->lock is held */
384 int n = ccissscsi[ctlr].ndevices;
385 struct cciss_scsi_dev_t *sd;
Mike Miller935dc8d2008-08-04 11:54:54 +0200386 int i, bus, target, lun;
387 unsigned char addr1[8], addr2[8];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700388
389 if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) {
390 printk("cciss%d: Too many devices, "
391 "some will be inaccessible.\n", ctlr);
392 return -1;
393 }
Mike Millerf4a93bc2008-08-04 11:54:53 +0200394
Mike Miller935dc8d2008-08-04 11:54:54 +0200395 bus = target = -1;
396 lun = 0;
397 /* Is this device a non-zero lun of a multi-lun device */
398 /* byte 4 of the 8-byte LUN addr will contain the logical unit no. */
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700399 if (device->scsi3addr[4] != 0) {
Mike Miller935dc8d2008-08-04 11:54:54 +0200400 /* Search through our list and find the device which */
401 /* has the same 8 byte LUN address, excepting byte 4. */
402 /* Assign the same bus and target for this new LUN. */
403 /* Use the logical unit number from the firmware. */
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700404 memcpy(addr1, device->scsi3addr, 8);
Mike Miller935dc8d2008-08-04 11:54:54 +0200405 addr1[4] = 0;
406 for (i = 0; i < n; i++) {
407 sd = &ccissscsi[ctlr].dev[i];
408 memcpy(addr2, sd->scsi3addr, 8);
409 addr2[4] = 0;
410 /* differ only in byte 4? */
411 if (memcmp(addr1, addr2, 8) == 0) {
412 bus = sd->bus;
413 target = sd->target;
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700414 lun = device->scsi3addr[4];
Mike Miller935dc8d2008-08-04 11:54:54 +0200415 break;
416 }
417 }
418 }
419
420 sd = &ccissscsi[ctlr].dev[n];
421 if (lun == 0) {
422 if (find_bus_target_lun(ctlr,
423 &sd->bus, &sd->target, &sd->lun) != 0)
424 return -1;
425 } else {
426 sd->bus = bus;
427 sd->target = target;
428 sd->lun = lun;
429 }
Mike Millerf4a93bc2008-08-04 11:54:53 +0200430 added[*nadded].bus = sd->bus;
431 added[*nadded].target = sd->target;
432 added[*nadded].lun = sd->lun;
433 (*nadded)++;
434
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700435 memcpy(sd->scsi3addr, device->scsi3addr, 8);
436 memcpy(sd->vendor, device->vendor, sizeof(sd->vendor));
437 memcpy(sd->revision, device->revision, sizeof(sd->revision));
438 memcpy(sd->device_id, device->device_id, sizeof(sd->device_id));
439 sd->devtype = device->devtype;
440
Linus Torvalds1da177e2005-04-16 15:20:36 -0700441 ccissscsi[ctlr].ndevices++;
442
443 /* initially, (before registering with scsi layer) we don't
444 know our hostno and we don't want to print anything first
445 time anyway (the scsi layer's inquiries will show that info) */
446 if (hostno != -1)
447 printk("cciss%d: %s device c%db%dt%dl%d added.\n",
Matthew Wilcox4ff36712006-07-04 12:15:20 -0600448 ctlr, scsi_device_type(sd->devtype), hostno,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700449 sd->bus, sd->target, sd->lun);
450 return 0;
451}
452
453static void
Mike Millerf4a93bc2008-08-04 11:54:53 +0200454cciss_scsi_remove_entry(int ctlr, int hostno, int entry,
455 struct scsi2map *removed, int *nremoved)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700456{
457 /* assumes hba[ctlr]->scsi_ctlr->lock is held */
458 int i;
459 struct cciss_scsi_dev_t sd;
460
461 if (entry < 0 || entry >= CCISS_MAX_SCSI_DEVS_PER_HBA) return;
462 sd = ccissscsi[ctlr].dev[entry];
Mike Millerf4a93bc2008-08-04 11:54:53 +0200463 removed[*nremoved].bus = sd.bus;
464 removed[*nremoved].target = sd.target;
465 removed[*nremoved].lun = sd.lun;
466 (*nremoved)++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700467 for (i=entry;i<ccissscsi[ctlr].ndevices-1;i++)
468 ccissscsi[ctlr].dev[i] = ccissscsi[ctlr].dev[i+1];
469 ccissscsi[ctlr].ndevices--;
470 printk("cciss%d: %s device c%db%dt%dl%d removed.\n",
Matthew Wilcox4ff36712006-07-04 12:15:20 -0600471 ctlr, scsi_device_type(sd.devtype), hostno,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700472 sd.bus, sd.target, sd.lun);
473}
474
475
476#define SCSI3ADDR_EQ(a,b) ( \
477 (a)[7] == (b)[7] && \
478 (a)[6] == (b)[6] && \
479 (a)[5] == (b)[5] && \
480 (a)[4] == (b)[4] && \
481 (a)[3] == (b)[3] && \
482 (a)[2] == (b)[2] && \
483 (a)[1] == (b)[1] && \
484 (a)[0] == (b)[0])
485
Mike Millerf4a93bc2008-08-04 11:54:53 +0200486static void fixup_botched_add(int ctlr, char *scsi3addr)
487{
488 /* called when scsi_add_device fails in order to re-adjust */
489 /* ccissscsi[] to match the mid layer's view. */
490 unsigned long flags;
491 int i, j;
492 CPQ_TAPE_LOCK(ctlr, flags);
493 for (i = 0; i < ccissscsi[ctlr].ndevices; i++) {
494 if (memcmp(scsi3addr,
495 ccissscsi[ctlr].dev[i].scsi3addr, 8) == 0) {
496 for (j = i; j < ccissscsi[ctlr].ndevices-1; j++)
497 ccissscsi[ctlr].dev[j] =
498 ccissscsi[ctlr].dev[j+1];
499 ccissscsi[ctlr].ndevices--;
500 break;
501 }
502 }
503 CPQ_TAPE_UNLOCK(ctlr, flags);
504}
505
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700506static int device_is_the_same(struct cciss_scsi_dev_t *dev1,
507 struct cciss_scsi_dev_t *dev2)
508{
509 return dev1->devtype == dev2->devtype &&
510 memcmp(dev1->scsi3addr, dev2->scsi3addr,
511 sizeof(dev1->scsi3addr)) == 0 &&
512 memcmp(dev1->device_id, dev2->device_id,
513 sizeof(dev1->device_id)) == 0 &&
514 memcmp(dev1->vendor, dev2->vendor,
515 sizeof(dev1->vendor)) == 0 &&
516 memcmp(dev1->model, dev2->model,
517 sizeof(dev1->model)) == 0 &&
518 memcmp(dev1->revision, dev2->revision,
519 sizeof(dev1->revision)) == 0;
520}
521
Linus Torvalds1da177e2005-04-16 15:20:36 -0700522static int
523adjust_cciss_scsi_table(int ctlr, int hostno,
524 struct cciss_scsi_dev_t sd[], int nsds)
525{
526 /* sd contains scsi3 addresses and devtypes, but
527 bus target and lun are not filled in. This funciton
528 takes what's in sd to be the current and adjusts
529 ccissscsi[] to be in line with what's in sd. */
530
531 int i,j, found, changes=0;
532 struct cciss_scsi_dev_t *csd;
533 unsigned long flags;
Mike Millerf4a93bc2008-08-04 11:54:53 +0200534 struct scsi2map *added, *removed;
535 int nadded, nremoved;
536 struct Scsi_Host *sh = NULL;
537
538 added = kzalloc(sizeof(*added) * CCISS_MAX_SCSI_DEVS_PER_HBA,
539 GFP_KERNEL);
540 removed = kzalloc(sizeof(*removed) * CCISS_MAX_SCSI_DEVS_PER_HBA,
541 GFP_KERNEL);
542
543 if (!added || !removed) {
544 printk(KERN_WARNING "cciss%d: Out of memory in "
545 "adjust_cciss_scsi_table\n", ctlr);
546 goto free_and_out;
547 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548
549 CPQ_TAPE_LOCK(ctlr, flags);
550
Mike Millerf4a93bc2008-08-04 11:54:53 +0200551 if (hostno != -1) /* if it's not the first time... */
552 sh = ((struct cciss_scsi_adapter_data_t *)
553 hba[ctlr]->scsi_ctlr)->scsi_host;
554
Linus Torvalds1da177e2005-04-16 15:20:36 -0700555 /* find any devices in ccissscsi[] that are not in
556 sd[] and remove them from ccissscsi[] */
557
558 i = 0;
Mike Millerf4a93bc2008-08-04 11:54:53 +0200559 nremoved = 0;
560 nadded = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561 while(i<ccissscsi[ctlr].ndevices) {
562 csd = &ccissscsi[ctlr].dev[i];
563 found=0;
564 for (j=0;j<nsds;j++) {
565 if (SCSI3ADDR_EQ(sd[j].scsi3addr,
566 csd->scsi3addr)) {
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700567 if (device_is_the_same(&sd[j], csd))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700568 found=2;
569 else
570 found=1;
571 break;
572 }
573 }
574
575 if (found == 0) { /* device no longer present. */
576 changes++;
577 /* printk("cciss%d: %s device c%db%dt%dl%d removed.\n",
Matthew Wilcox4ff36712006-07-04 12:15:20 -0600578 ctlr, scsi_device_type(csd->devtype), hostno,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700579 csd->bus, csd->target, csd->lun); */
Mike Millerf4a93bc2008-08-04 11:54:53 +0200580 cciss_scsi_remove_entry(ctlr, hostno, i,
581 removed, &nremoved);
582 /* remove ^^^, hence i not incremented */
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700583 } else if (found == 1) { /* device is different in some way */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700584 changes++;
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700585 printk("cciss%d: device c%db%dt%dl%d has changed.\n",
586 ctlr, hostno, csd->bus, csd->target, csd->lun);
Mike Millerf4a93bc2008-08-04 11:54:53 +0200587 cciss_scsi_remove_entry(ctlr, hostno, i,
588 removed, &nremoved);
589 /* remove ^^^, hence i not incremented */
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700590 if (cciss_scsi_add_entry(ctlr, hostno, &sd[j],
Mike Millerf4a93bc2008-08-04 11:54:53 +0200591 added, &nadded) != 0)
592 /* we just removed one, so add can't fail. */
593 BUG();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700594 csd->devtype = sd[j].devtype;
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700595 memcpy(csd->device_id, sd[j].device_id,
596 sizeof(csd->device_id));
597 memcpy(csd->vendor, sd[j].vendor,
598 sizeof(csd->vendor));
599 memcpy(csd->model, sd[j].model,
600 sizeof(csd->model));
601 memcpy(csd->revision, sd[j].revision,
602 sizeof(csd->revision));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700603 } else /* device is same as it ever was, */
604 i++; /* so just move along. */
605 }
606
607 /* Now, make sure every device listed in sd[] is also
608 listed in ccissscsi[], adding them if they aren't found */
609
610 for (i=0;i<nsds;i++) {
611 found=0;
612 for (j=0;j<ccissscsi[ctlr].ndevices;j++) {
613 csd = &ccissscsi[ctlr].dev[j];
614 if (SCSI3ADDR_EQ(sd[i].scsi3addr,
615 csd->scsi3addr)) {
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700616 if (device_is_the_same(&sd[i], csd))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700617 found=2; /* found device */
618 else
619 found=1; /* found a bug. */
620 break;
621 }
622 }
623 if (!found) {
624 changes++;
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700625 if (cciss_scsi_add_entry(ctlr, hostno, &sd[i],
Mike Millerf4a93bc2008-08-04 11:54:53 +0200626 added, &nadded) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700627 break;
628 } else if (found == 1) {
629 /* should never happen... */
630 changes++;
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700631 printk(KERN_WARNING "cciss%d: device "
632 "unexpectedly changed\n", ctlr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700633 /* but if it does happen, we just ignore that device */
634 }
635 }
636 CPQ_TAPE_UNLOCK(ctlr, flags);
637
Mike Millerf4a93bc2008-08-04 11:54:53 +0200638 /* Don't notify scsi mid layer of any changes the first time through */
639 /* (or if there are no changes) scsi_scan_host will do it later the */
640 /* first time through. */
641 if (hostno == -1 || !changes)
642 goto free_and_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700643
Mike Millerf4a93bc2008-08-04 11:54:53 +0200644 /* Notify scsi mid layer of any removed devices */
645 for (i = 0; i < nremoved; i++) {
646 struct scsi_device *sdev =
647 scsi_device_lookup(sh, removed[i].bus,
648 removed[i].target, removed[i].lun);
649 if (sdev != NULL) {
650 scsi_remove_device(sdev);
651 scsi_device_put(sdev);
652 } else {
653 /* We don't expect to get here. */
654 /* future cmds to this device will get selection */
655 /* timeout as if the device was gone. */
656 printk(KERN_WARNING "cciss%d: didn't find "
657 "c%db%dt%dl%d\n for removal.",
658 ctlr, hostno, removed[i].bus,
659 removed[i].target, removed[i].lun);
660 }
661 }
662
663 /* Notify scsi mid layer of any added devices */
664 for (i = 0; i < nadded; i++) {
665 int rc;
666 rc = scsi_add_device(sh, added[i].bus,
667 added[i].target, added[i].lun);
668 if (rc == 0)
669 continue;
670 printk(KERN_WARNING "cciss%d: scsi_add_device "
671 "c%db%dt%dl%d failed, device not added.\n",
672 ctlr, hostno,
673 added[i].bus, added[i].target, added[i].lun);
674 /* now we have to remove it from ccissscsi, */
675 /* since it didn't get added to scsi mid layer */
676 fixup_botched_add(ctlr, added[i].scsi3addr);
677 }
678
679free_and_out:
680 kfree(added);
681 kfree(removed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700682 return 0;
683}
684
685static int
686lookup_scsi3addr(int ctlr, int bus, int target, int lun, char *scsi3addr)
687{
688 int i;
689 struct cciss_scsi_dev_t *sd;
690 unsigned long flags;
691
692 CPQ_TAPE_LOCK(ctlr, flags);
693 for (i=0;i<ccissscsi[ctlr].ndevices;i++) {
694 sd = &ccissscsi[ctlr].dev[i];
695 if (sd->bus == bus &&
696 sd->target == target &&
697 sd->lun == lun) {
698 memcpy(scsi3addr, &sd->scsi3addr[0], 8);
699 CPQ_TAPE_UNLOCK(ctlr, flags);
700 return 0;
701 }
702 }
703 CPQ_TAPE_UNLOCK(ctlr, flags);
704 return -1;
705}
706
707static void
708cciss_scsi_setup(int cntl_num)
709{
710 struct cciss_scsi_adapter_data_t * shba;
711
712 ccissscsi[cntl_num].ndevices = 0;
713 shba = (struct cciss_scsi_adapter_data_t *)
714 kmalloc(sizeof(*shba), GFP_KERNEL);
715 if (shba == NULL)
716 return;
717 shba->scsi_host = NULL;
718 spin_lock_init(&shba->lock);
719 shba->registered = 0;
720 if (scsi_cmd_stack_setup(cntl_num, shba) != 0) {
721 kfree(shba);
722 shba = NULL;
723 }
724 hba[cntl_num]->scsi_ctlr = (void *) shba;
725 return;
726}
727
728static void
729complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag)
730{
731 struct scsi_cmnd *cmd;
732 ctlr_info_t *ctlr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700733 ErrorInfo_struct *ei;
734
735 ei = cp->err_info;
736
737 /* First, see if it was a message rather than a command */
738 if (cp->Request.Type.Type == TYPE_MSG) {
739 cp->cmd_type = CMD_MSG_DONE;
740 return;
741 }
742
743 cmd = (struct scsi_cmnd *) cp->scsi_cmd;
744 ctlr = hba[cp->ctlr];
745
FUJITA Tomonori41ce6392007-05-26 02:45:17 +0900746 scsi_dma_unmap(cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700747
748 cmd->result = (DID_OK << 16); /* host byte */
749 cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
750 /* cmd->result |= (GOOD < 1); */ /* status byte */
751
752 cmd->result |= (ei->ScsiStatus);
753 /* printk("Scsistatus is 0x%02x\n", ei->ScsiStatus); */
754
755 /* copy the sense data whether we need to or not. */
756
757 memcpy(cmd->sense_buffer, ei->SenseInfo,
758 ei->SenseLen > SCSI_SENSE_BUFFERSIZE ?
759 SCSI_SENSE_BUFFERSIZE :
760 ei->SenseLen);
FUJITA Tomonori41ce6392007-05-26 02:45:17 +0900761 scsi_set_resid(cmd, ei->ResidualCnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700762
763 if(ei->CommandStatus != 0)
764 { /* an error has occurred */
765 switch(ei->CommandStatus)
766 {
767 case CMD_TARGET_STATUS:
768 /* Pass it up to the upper layers... */
769 if( ei->ScsiStatus)
770 {
771#if 0
772 printk(KERN_WARNING "cciss: cmd %p "
773 "has SCSI Status = %x\n",
774 cp,
775 ei->ScsiStatus);
776#endif
777 cmd->result |= (ei->ScsiStatus < 1);
778 }
779 else { /* scsi status is zero??? How??? */
780
781 /* Ordinarily, this case should never happen, but there is a bug
782 in some released firmware revisions that allows it to happen
783 if, for example, a 4100 backplane loses power and the tape
784 drive is in it. We assume that it's a fatal error of some
785 kind because we can't show that it wasn't. We will make it
786 look like selection timeout since that is the most common
787 reason for this to occur, and it's severe enough. */
788
789 cmd->result = DID_NO_CONNECT << 16;
790 }
791 break;
792 case CMD_DATA_UNDERRUN: /* let mid layer handle it. */
793 break;
794 case CMD_DATA_OVERRUN:
795 printk(KERN_WARNING "cciss: cp %p has"
796 " completed with data overrun "
797 "reported\n", cp);
798 break;
799 case CMD_INVALID: {
800 /* print_bytes(cp, sizeof(*cp), 1, 0);
801 print_cmd(cp); */
802 /* We get CMD_INVALID if you address a non-existent tape drive instead
803 of a selection timeout (no response). You will see this if you yank
804 out a tape drive, then try to access it. This is kind of a shame
805 because it means that any other CMD_INVALID (e.g. driver bug) will
806 get interpreted as a missing target. */
807 cmd->result = DID_NO_CONNECT << 16;
808 }
809 break;
810 case CMD_PROTOCOL_ERR:
811 printk(KERN_WARNING "cciss: cp %p has "
812 "protocol error \n", cp);
813 break;
814 case CMD_HARDWARE_ERR:
815 cmd->result = DID_ERROR << 16;
816 printk(KERN_WARNING "cciss: cp %p had "
817 " hardware error\n", cp);
818 break;
819 case CMD_CONNECTION_LOST:
820 cmd->result = DID_ERROR << 16;
821 printk(KERN_WARNING "cciss: cp %p had "
822 "connection lost\n", cp);
823 break;
824 case CMD_ABORTED:
825 cmd->result = DID_ABORT << 16;
826 printk(KERN_WARNING "cciss: cp %p was "
827 "aborted\n", cp);
828 break;
829 case CMD_ABORT_FAILED:
830 cmd->result = DID_ERROR << 16;
831 printk(KERN_WARNING "cciss: cp %p reports "
832 "abort failed\n", cp);
833 break;
834 case CMD_UNSOLICITED_ABORT:
835 cmd->result = DID_ABORT << 16;
836 printk(KERN_WARNING "cciss: cp %p aborted "
837 "do to an unsolicited abort\n", cp);
838 break;
839 case CMD_TIMEOUT:
840 cmd->result = DID_TIME_OUT << 16;
841 printk(KERN_WARNING "cciss: cp %p timedout\n",
842 cp);
843 break;
844 default:
845 cmd->result = DID_ERROR << 16;
846 printk(KERN_WARNING "cciss: cp %p returned "
847 "unknown status %x\n", cp,
848 ei->CommandStatus);
849 }
850 }
851 // printk("c:%p:c%db%dt%dl%d ", cmd, ctlr->ctlr, cmd->channel,
852 // cmd->target, cmd->lun);
853 cmd->scsi_done(cmd);
854 scsi_cmd_free(ctlr, cp);
855}
856
857static int
858cciss_scsi_detect(int ctlr)
859{
860 struct Scsi_Host *sh;
861 int error;
862
863 sh = scsi_host_alloc(&cciss_driver_template, sizeof(struct ctlr_info *));
864 if (sh == NULL)
865 goto fail;
866 sh->io_port = 0; // good enough? FIXME,
867 sh->n_io_port = 0; // I don't think we use these two...
868 sh->this_id = SELF_SCSI_ID;
869
870 ((struct cciss_scsi_adapter_data_t *)
871 hba[ctlr]->scsi_ctlr)->scsi_host = (void *) sh;
872 sh->hostdata[0] = (unsigned long) hba[ctlr];
Mike Millerfb86a352006-01-08 01:03:50 -0800873 sh->irq = hba[ctlr]->intr[SIMPLE_MODE_INT];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700874 sh->unique_id = sh->irq;
875 error = scsi_add_host(sh, &hba[ctlr]->pdev->dev);
876 if (error)
877 goto fail_host_put;
878 scsi_scan_host(sh);
879 return 1;
880
881 fail_host_put:
882 scsi_host_put(sh);
883 fail:
884 return 0;
885}
886
887static void
888cciss_unmap_one(struct pci_dev *pdev,
889 CommandList_struct *cp,
890 size_t buflen,
891 int data_direction)
892{
893 u64bit addr64;
894
895 addr64.val32.lower = cp->SG[0].Addr.lower;
896 addr64.val32.upper = cp->SG[0].Addr.upper;
897 pci_unmap_single(pdev, (dma_addr_t) addr64.val, buflen, data_direction);
898}
899
900static void
901cciss_map_one(struct pci_dev *pdev,
902 CommandList_struct *cp,
903 unsigned char *buf,
904 size_t buflen,
905 int data_direction)
906{
907 __u64 addr64;
908
909 addr64 = (__u64) pci_map_single(pdev, buf, buflen, data_direction);
910 cp->SG[0].Addr.lower =
911 (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
912 cp->SG[0].Addr.upper =
913 (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
914 cp->SG[0].Len = buflen;
915 cp->Header.SGList = (__u8) 1; /* no. SGs contig in this cmd */
916 cp->Header.SGTotal = (__u16) 1; /* total sgs in this cmd list */
917}
918
919static int
920cciss_scsi_do_simple_cmd(ctlr_info_t *c,
921 CommandList_struct *cp,
922 unsigned char *scsi3addr,
923 unsigned char *cdb,
924 unsigned char cdblen,
925 unsigned char *buf, int bufsize,
926 int direction)
927{
928 unsigned long flags;
Peter Zijlstra6e9a4732006-09-30 23:28:10 -0700929 DECLARE_COMPLETION_ONSTACK(wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700930
931 cp->cmd_type = CMD_IOCTL_PEND; // treat this like an ioctl
932 cp->scsi_cmd = NULL;
933 cp->Header.ReplyQueue = 0; // unused in simple mode
934 memcpy(&cp->Header.LUN, scsi3addr, sizeof(cp->Header.LUN));
935 cp->Header.Tag.lower = cp->busaddr; // Use k. address of cmd as tag
936 // Fill in the request block...
937
938 /* printk("Using scsi3addr 0x%02x%0x2%0x2%0x2%0x2%0x2%0x2%0x2\n",
939 scsi3addr[0], scsi3addr[1], scsi3addr[2], scsi3addr[3],
940 scsi3addr[4], scsi3addr[5], scsi3addr[6], scsi3addr[7]); */
941
942 memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB));
943 memcpy(cp->Request.CDB, cdb, cdblen);
944 cp->Request.Timeout = 0;
945 cp->Request.CDBLen = cdblen;
946 cp->Request.Type.Type = TYPE_CMD;
947 cp->Request.Type.Attribute = ATTR_SIMPLE;
948 cp->Request.Type.Direction = direction;
949
950 /* Fill in the SG list and do dma mapping */
951 cciss_map_one(c->pdev, cp, (unsigned char *) buf,
952 bufsize, DMA_FROM_DEVICE);
953
954 cp->waiting = &wait;
955
956 /* Put the request on the tail of the request queue */
957 spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
958 addQ(&c->reqQ, cp);
959 c->Qdepth++;
960 start_io(c);
961 spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
962
963 wait_for_completion(&wait);
964
965 /* undo the dma mapping */
966 cciss_unmap_one(c->pdev, cp, bufsize, DMA_FROM_DEVICE);
967 return(0);
968}
969
970static void
971cciss_scsi_interpret_error(CommandList_struct *cp)
972{
973 ErrorInfo_struct *ei;
974
975 ei = cp->err_info;
976 switch(ei->CommandStatus)
977 {
978 case CMD_TARGET_STATUS:
979 printk(KERN_WARNING "cciss: cmd %p has "
980 "completed with errors\n", cp);
981 printk(KERN_WARNING "cciss: cmd %p "
982 "has SCSI Status = %x\n",
983 cp,
984 ei->ScsiStatus);
985 if (ei->ScsiStatus == 0)
986 printk(KERN_WARNING
987 "cciss:SCSI status is abnormally zero. "
988 "(probably indicates selection timeout "
989 "reported incorrectly due to a known "
990 "firmware bug, circa July, 2001.)\n");
991 break;
992 case CMD_DATA_UNDERRUN: /* let mid layer handle it. */
993 printk("UNDERRUN\n");
994 break;
995 case CMD_DATA_OVERRUN:
996 printk(KERN_WARNING "cciss: cp %p has"
997 " completed with data overrun "
998 "reported\n", cp);
999 break;
1000 case CMD_INVALID: {
1001 /* controller unfortunately reports SCSI passthru's */
1002 /* to non-existent targets as invalid commands. */
1003 printk(KERN_WARNING "cciss: cp %p is "
1004 "reported invalid (probably means "
1005 "target device no longer present)\n",
1006 cp);
1007 /* print_bytes((unsigned char *) cp, sizeof(*cp), 1, 0);
1008 print_cmd(cp); */
1009 }
1010 break;
1011 case CMD_PROTOCOL_ERR:
1012 printk(KERN_WARNING "cciss: cp %p has "
1013 "protocol error \n", cp);
1014 break;
1015 case CMD_HARDWARE_ERR:
1016 /* cmd->result = DID_ERROR << 16; */
1017 printk(KERN_WARNING "cciss: cp %p had "
1018 " hardware error\n", cp);
1019 break;
1020 case CMD_CONNECTION_LOST:
1021 printk(KERN_WARNING "cciss: cp %p had "
1022 "connection lost\n", cp);
1023 break;
1024 case CMD_ABORTED:
1025 printk(KERN_WARNING "cciss: cp %p was "
1026 "aborted\n", cp);
1027 break;
1028 case CMD_ABORT_FAILED:
1029 printk(KERN_WARNING "cciss: cp %p reports "
1030 "abort failed\n", cp);
1031 break;
1032 case CMD_UNSOLICITED_ABORT:
1033 printk(KERN_WARNING "cciss: cp %p aborted "
1034 "do to an unsolicited abort\n", cp);
1035 break;
1036 case CMD_TIMEOUT:
1037 printk(KERN_WARNING "cciss: cp %p timedout\n",
1038 cp);
1039 break;
1040 default:
1041 printk(KERN_WARNING "cciss: cp %p returned "
1042 "unknown status %x\n", cp,
1043 ei->CommandStatus);
1044 }
1045}
1046
1047static int
1048cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr,
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001049 unsigned char page, unsigned char *buf,
1050 unsigned char bufsize)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001051{
1052 int rc;
1053 CommandList_struct *cp;
1054 char cdb[6];
1055 ErrorInfo_struct *ei;
1056 unsigned long flags;
1057
1058 spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
1059 cp = scsi_cmd_alloc(c);
1060 spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
1061
1062 if (cp == NULL) { /* trouble... */
1063 printk("cmd_alloc returned NULL!\n");
1064 return -1;
1065 }
1066
1067 ei = cp->err_info;
1068
1069 cdb[0] = CISS_INQUIRY;
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001070 cdb[1] = (page != 0);
1071 cdb[2] = page;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001072 cdb[3] = 0;
Mike Miller47922d02005-09-13 01:25:25 -07001073 cdb[4] = bufsize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001074 cdb[5] = 0;
1075 rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr, cdb,
Mike Miller47922d02005-09-13 01:25:25 -07001076 6, buf, bufsize, XFER_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001077
1078 if (rc != 0) return rc; /* something went wrong */
1079
1080 if (ei->CommandStatus != 0 &&
1081 ei->CommandStatus != CMD_DATA_UNDERRUN) {
1082 cciss_scsi_interpret_error(cp);
1083 rc = -1;
1084 }
1085 spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
1086 scsi_cmd_free(c, cp);
1087 spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
1088 return rc;
1089}
1090
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001091/* Get the device id from inquiry page 0x83 */
1092static int cciss_scsi_get_device_id(ctlr_info_t *c, unsigned char *scsi3addr,
1093 unsigned char *device_id, int buflen)
1094{
1095 int rc;
1096 unsigned char *buf;
1097
1098 if (buflen > 16)
1099 buflen = 16;
1100 buf = kzalloc(64, GFP_KERNEL);
1101 if (!buf)
1102 return -1;
1103 rc = cciss_scsi_do_inquiry(c, scsi3addr, 0x83, buf, 64);
1104 if (rc == 0)
1105 memcpy(device_id, &buf[8], buflen);
1106 kfree(buf);
1107 return rc != 0;
1108}
1109
Linus Torvalds1da177e2005-04-16 15:20:36 -07001110static int
1111cciss_scsi_do_report_phys_luns(ctlr_info_t *c,
1112 ReportLunData_struct *buf, int bufsize)
1113{
1114 int rc;
1115 CommandList_struct *cp;
1116 unsigned char cdb[12];
1117 unsigned char scsi3addr[8];
1118 ErrorInfo_struct *ei;
1119 unsigned long flags;
1120
1121 spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
1122 cp = scsi_cmd_alloc(c);
1123 spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
1124 if (cp == NULL) { /* trouble... */
1125 printk("cmd_alloc returned NULL!\n");
1126 return -1;
1127 }
1128
1129 memset(&scsi3addr[0], 0, 8); /* address the controller */
1130 cdb[0] = CISS_REPORT_PHYS;
1131 cdb[1] = 0;
1132 cdb[2] = 0;
1133 cdb[3] = 0;
1134 cdb[4] = 0;
1135 cdb[5] = 0;
1136 cdb[6] = (bufsize >> 24) & 0xFF; //MSB
1137 cdb[7] = (bufsize >> 16) & 0xFF;
1138 cdb[8] = (bufsize >> 8) & 0xFF;
1139 cdb[9] = bufsize & 0xFF;
1140 cdb[10] = 0;
1141 cdb[11] = 0;
1142
1143 rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr,
1144 cdb, 12,
1145 (unsigned char *) buf,
1146 bufsize, XFER_READ);
1147
1148 if (rc != 0) return rc; /* something went wrong */
1149
1150 ei = cp->err_info;
1151 if (ei->CommandStatus != 0 &&
1152 ei->CommandStatus != CMD_DATA_UNDERRUN) {
1153 cciss_scsi_interpret_error(cp);
1154 rc = -1;
1155 }
1156 spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
1157 scsi_cmd_free(c, cp);
1158 spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
1159 return rc;
1160}
1161
1162static void
1163cciss_update_non_disk_devices(int cntl_num, int hostno)
1164{
1165 /* the idea here is we could get notified from /proc
1166 that some devices have changed, so we do a report
1167 physical luns cmd, and adjust our list of devices
1168 accordingly. (We can't rely on the scsi-mid layer just
1169 doing inquiries, because the "busses" that the scsi
1170 mid-layer probes are totally fabricated by this driver,
1171 so new devices wouldn't show up.
1172
1173 the scsi3addr's of devices won't change so long as the
1174 adapter is not reset. That means we can rescan and
1175 tell which devices we already know about, vs. new
1176 devices, vs. disappearing devices.
1177
1178 Also, if you yank out a tape drive, then put in a disk
1179 in it's place, (say, a configured volume from another
1180 array controller for instance) _don't_ poke this driver
1181 (so it thinks it's still a tape, but _do_ poke the scsi
1182 mid layer, so it does an inquiry... the scsi mid layer
1183 will see the physical disk. This would be bad. Need to
1184 think about how to prevent that. One idea would be to
1185 snoop all scsi responses and if an inquiry repsonse comes
1186 back that reports a disk, chuck it an return selection
1187 timeout instead and adjust our table... Not sure i like
1188 that though.
1189
1190 */
Mike Miller47922d02005-09-13 01:25:25 -07001191#define OBDR_TAPE_INQ_SIZE 49
1192#define OBDR_TAPE_SIG "$DR-10"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001193 ReportLunData_struct *ld_buff;
Mike Miller47922d02005-09-13 01:25:25 -07001194 unsigned char *inq_buff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001195 unsigned char scsi3addr[8];
1196 ctlr_info_t *c;
1197 __u32 num_luns=0;
1198 unsigned char *ch;
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001199 struct cciss_scsi_dev_t *currentsd, *this_device;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001200 int ncurrent=0;
1201 int reportlunsize = sizeof(*ld_buff) + CISS_MAX_PHYS_LUN * 8;
1202 int i;
1203
1204 c = (ctlr_info_t *) hba[cntl_num];
Eric Sesterhenn06ff37f2006-03-08 11:21:52 +01001205 ld_buff = kzalloc(reportlunsize, GFP_KERNEL);
Mike Miller47922d02005-09-13 01:25:25 -07001206 inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001207 currentsd = kzalloc(sizeof(*currentsd) *
1208 (CCISS_MAX_SCSI_DEVS_PER_HBA+1), GFP_KERNEL);
1209 if (ld_buff == NULL || inq_buff == NULL || currentsd == NULL) {
1210 printk(KERN_ERR "cciss: out of memory\n");
1211 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001212 }
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001213 this_device = &currentsd[CCISS_MAX_SCSI_DEVS_PER_HBA];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001214 if (cciss_scsi_do_report_phys_luns(c, ld_buff, reportlunsize) == 0) {
1215 ch = &ld_buff->LUNListLength[0];
1216 num_luns = ((ch[0]<<24) | (ch[1]<<16) | (ch[2]<<8) | ch[3]) / 8;
1217 if (num_luns > CISS_MAX_PHYS_LUN) {
1218 printk(KERN_WARNING
1219 "cciss: Maximum physical LUNs (%d) exceeded. "
1220 "%d LUNs ignored.\n", CISS_MAX_PHYS_LUN,
1221 num_luns - CISS_MAX_PHYS_LUN);
1222 num_luns = CISS_MAX_PHYS_LUN;
1223 }
1224 }
1225 else {
1226 printk(KERN_ERR "cciss: Report physical LUNs failed.\n");
1227 goto out;
1228 }
1229
1230
1231 /* adjust our table of devices */
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001232 for (i = 0; i < num_luns; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001233 /* for each physical lun, do an inquiry */
1234 if (ld_buff->LUN[i][3] & 0xC0) continue;
Mike Miller47922d02005-09-13 01:25:25 -07001235 memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001236 memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8);
1237
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001238 if (cciss_scsi_do_inquiry(hba[cntl_num], scsi3addr, 0, inq_buff,
1239 (unsigned char) OBDR_TAPE_INQ_SIZE) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001240 /* Inquiry failed (msg printed already) */
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001241 continue; /* so we will skip this device. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001243 this_device->devtype = (inq_buff[0] & 0x1f);
1244 this_device->bus = -1;
1245 this_device->target = -1;
1246 this_device->lun = -1;
1247 memcpy(this_device->scsi3addr, scsi3addr, 8);
1248 memcpy(this_device->vendor, &inq_buff[8],
1249 sizeof(this_device->vendor));
1250 memcpy(this_device->model, &inq_buff[16],
1251 sizeof(this_device->model));
1252 memcpy(this_device->revision, &inq_buff[32],
1253 sizeof(this_device->revision));
1254 memset(this_device->device_id, 0,
1255 sizeof(this_device->device_id));
1256 cciss_scsi_get_device_id(hba[cntl_num], scsi3addr,
1257 this_device->device_id, sizeof(this_device->device_id));
1258
1259 switch (this_device->devtype)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001260 {
Mike Miller47922d02005-09-13 01:25:25 -07001261 case 0x05: /* CD-ROM */ {
1262
1263 /* We don't *really* support actual CD-ROM devices,
1264 * just this "One Button Disaster Recovery" tape drive
1265 * which temporarily pretends to be a CD-ROM drive.
1266 * So we check that the device is really an OBDR tape
1267 * device by checking for "$DR-10" in bytes 43-48 of
1268 * the inquiry data.
1269 */
1270 char obdr_sig[7];
1271
1272 strncpy(obdr_sig, &inq_buff[43], 6);
1273 obdr_sig[6] = '\0';
1274 if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0)
1275 /* Not OBDR device, ignore it. */
1276 break;
1277 }
1278 /* fall through . . . */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001279 case 0x01: /* sequential access, (tape) */
1280 case 0x08: /* medium changer */
1281 if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) {
1282 printk(KERN_INFO "cciss%d: %s ignored, "
1283 "too many devices.\n", cntl_num,
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001284 scsi_device_type(this_device->devtype));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001285 break;
1286 }
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001287 currentsd[ncurrent] = *this_device;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001288 ncurrent++;
1289 break;
1290 default:
1291 break;
1292 }
1293 }
1294
1295 adjust_cciss_scsi_table(cntl_num, hostno, currentsd, ncurrent);
1296out:
1297 kfree(inq_buff);
1298 kfree(ld_buff);
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001299 kfree(currentsd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001300 return;
1301}
1302
1303static int
1304is_keyword(char *ptr, int len, char *verb) // Thanks to ncr53c8xx.c
1305{
1306 int verb_len = strlen(verb);
1307 if (len >= verb_len && !memcmp(verb,ptr,verb_len))
1308 return verb_len;
1309 else
1310 return 0;
1311}
1312
1313static int
1314cciss_scsi_user_command(int ctlr, int hostno, char *buffer, int length)
1315{
1316 int arg_len;
1317
1318 if ((arg_len = is_keyword(buffer, length, "rescan")) != 0)
1319 cciss_update_non_disk_devices(ctlr, hostno);
1320 else
1321 return -EINVAL;
1322 return length;
1323}
1324
1325
1326static int
1327cciss_scsi_proc_info(struct Scsi_Host *sh,
1328 char *buffer, /* data buffer */
1329 char **start, /* where data in buffer starts */
1330 off_t offset, /* offset from start of imaginary file */
1331 int length, /* length of data in buffer */
1332 int func) /* 0 == read, 1 == write */
1333{
1334
1335 int buflen, datalen;
1336 ctlr_info_t *ci;
Mike Millerb9f0bd02005-09-13 01:25:26 -07001337 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001338 int cntl_num;
1339
1340
1341 ci = (ctlr_info_t *) sh->hostdata[0];
1342 if (ci == NULL) /* This really shouldn't ever happen. */
1343 return -EINVAL;
1344
1345 cntl_num = ci->ctlr; /* Get our index into the hba[] array */
1346
1347 if (func == 0) { /* User is reading from /proc/scsi/ciss*?/?* */
Mike Millerb9f0bd02005-09-13 01:25:26 -07001348 buflen = sprintf(buffer, "cciss%d: SCSI host: %d\n",
1349 cntl_num, sh->host_no);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001350
Mike Millerb9f0bd02005-09-13 01:25:26 -07001351 /* this information is needed by apps to know which cciss
1352 device corresponds to which scsi host number without
1353 having to open a scsi target device node. The device
1354 information is not a duplicate of /proc/scsi/scsi because
1355 the two may be out of sync due to scsi hotplug, rather
1356 this info is for an app to be able to use to know how to
1357 get them back in sync. */
1358
1359 for (i=0;i<ccissscsi[cntl_num].ndevices;i++) {
1360 struct cciss_scsi_dev_t *sd = &ccissscsi[cntl_num].dev[i];
1361 buflen += sprintf(&buffer[buflen], "c%db%dt%dl%d %02d "
1362 "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
1363 sh->host_no, sd->bus, sd->target, sd->lun,
1364 sd->devtype,
1365 sd->scsi3addr[0], sd->scsi3addr[1],
1366 sd->scsi3addr[2], sd->scsi3addr[3],
1367 sd->scsi3addr[4], sd->scsi3addr[5],
1368 sd->scsi3addr[6], sd->scsi3addr[7]);
1369 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001370 datalen = buflen - offset;
1371 if (datalen < 0) { /* they're reading past EOF. */
1372 datalen = 0;
1373 *start = buffer+buflen;
1374 } else
1375 *start = buffer + offset;
1376 return(datalen);
1377 } else /* User is writing to /proc/scsi/cciss*?/?* ... */
1378 return cciss_scsi_user_command(cntl_num, sh->host_no,
1379 buffer, length);
1380}
1381
1382/* cciss_scatter_gather takes a struct scsi_cmnd, (cmd), and does the pci
1383 dma mapping and fills in the scatter gather entries of the
1384 cciss command, cp. */
1385
1386static void
1387cciss_scatter_gather(struct pci_dev *pdev,
1388 CommandList_struct *cp,
1389 struct scsi_cmnd *cmd)
1390{
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001391 unsigned int len;
1392 struct scatterlist *sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393 __u64 addr64;
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001394 int use_sg, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001395
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001396 BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001397
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001398 use_sg = scsi_dma_map(cmd);
1399 if (use_sg) { /* not too many addrs? */
1400 scsi_for_each_sg(cmd, sg, use_sg, i) {
1401 addr64 = (__u64) sg_dma_address(sg);
1402 len = sg_dma_len(sg);
1403 cp->SG[i].Addr.lower =
1404 (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
1405 cp->SG[i].Addr.upper =
1406 (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
1407 cp->SG[i].Len = len;
1408 cp->SG[i].Ext = 0; // we are not chaining
Linus Torvalds1da177e2005-04-16 15:20:36 -07001409 }
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001410 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001411
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001412 cp->Header.SGList = (__u8) use_sg; /* no. SGs contig in this cmd */
1413 cp->Header.SGTotal = (__u16) use_sg; /* total sgs in this cmd list */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001414 return;
1415}
1416
1417
1418static int
1419cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
1420{
1421 ctlr_info_t **c;
1422 int ctlr, rc;
1423 unsigned char scsi3addr[8];
1424 CommandList_struct *cp;
1425 unsigned long flags;
1426
1427 // Get the ptr to our adapter structure (hba[i]) out of cmd->host.
1428 // We violate cmd->host privacy here. (Is there another way?)
1429 c = (ctlr_info_t **) &cmd->device->host->hostdata[0];
1430 ctlr = (*c)->ctlr;
1431
1432 rc = lookup_scsi3addr(ctlr, cmd->device->channel, cmd->device->id,
1433 cmd->device->lun, scsi3addr);
1434 if (rc != 0) {
1435 /* the scsi nexus does not match any that we presented... */
1436 /* pretend to mid layer that we got selection timeout */
1437 cmd->result = DID_NO_CONNECT << 16;
1438 done(cmd);
1439 /* we might want to think about registering controller itself
1440 as a processor device on the bus so sg binds to it. */
1441 return 0;
1442 }
1443
1444 /* printk("cciss_queue_command, p=%p, cmd=0x%02x, c%db%dt%dl%d\n",
1445 cmd, cmd->cmnd[0], ctlr, cmd->channel, cmd->target, cmd->lun);*/
1446 // printk("q:%p:c%db%dt%dl%d ", cmd, ctlr, cmd->channel,
1447 // cmd->target, cmd->lun);
1448
1449 /* Ok, we have a reasonable scsi nexus, so send the cmd down, and
1450 see what the device thinks of it. */
1451
1452 spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
1453 cp = scsi_cmd_alloc(*c);
1454 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
1455 if (cp == NULL) { /* trouble... */
1456 printk("scsi_cmd_alloc returned NULL!\n");
1457 /* FIXME: next 3 lines are -> BAD! <- */
1458 cmd->result = DID_NO_CONNECT << 16;
1459 done(cmd);
1460 return 0;
1461 }
1462
1463 // Fill in the command list header
1464
1465 cmd->scsi_done = done; // save this for use by completion code
1466
1467 // save cp in case we have to abort it
1468 cmd->host_scribble = (unsigned char *) cp;
1469
1470 cp->cmd_type = CMD_SCSI;
1471 cp->scsi_cmd = cmd;
1472 cp->Header.ReplyQueue = 0; // unused in simple mode
1473 memcpy(&cp->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8);
1474 cp->Header.Tag.lower = cp->busaddr; // Use k. address of cmd as tag
1475
1476 // Fill in the request block...
1477
1478 cp->Request.Timeout = 0;
1479 memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB));
Eric Sesterhenn089fe1b2006-03-24 18:50:27 +01001480 BUG_ON(cmd->cmd_len > sizeof(cp->Request.CDB));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001481 cp->Request.CDBLen = cmd->cmd_len;
1482 memcpy(cp->Request.CDB, cmd->cmnd, cmd->cmd_len);
1483 cp->Request.Type.Type = TYPE_CMD;
1484 cp->Request.Type.Attribute = ATTR_SIMPLE;
1485 switch(cmd->sc_data_direction)
1486 {
1487 case DMA_TO_DEVICE: cp->Request.Type.Direction = XFER_WRITE; break;
1488 case DMA_FROM_DEVICE: cp->Request.Type.Direction = XFER_READ; break;
1489 case DMA_NONE: cp->Request.Type.Direction = XFER_NONE; break;
1490 case DMA_BIDIRECTIONAL:
1491 // This can happen if a buggy application does a scsi passthru
1492 // and sets both inlen and outlen to non-zero. ( see
1493 // ../scsi/scsi_ioctl.c:scsi_ioctl_send_command() )
1494
1495 cp->Request.Type.Direction = XFER_RSVD;
1496 // This is technically wrong, and cciss controllers should
1497 // reject it with CMD_INVALID, which is the most correct
1498 // response, but non-fibre backends appear to let it
1499 // slide by, and give the same results as if this field
1500 // were set correctly. Either way is acceptable for
1501 // our purposes here.
1502
1503 break;
1504
1505 default:
1506 printk("cciss: unknown data direction: %d\n",
1507 cmd->sc_data_direction);
1508 BUG();
1509 break;
1510 }
1511
1512 cciss_scatter_gather((*c)->pdev, cp, cmd); // Fill the SG list
1513
1514 /* Put the request on the tail of the request queue */
1515
1516 spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
1517 addQ(&(*c)->reqQ, cp);
1518 (*c)->Qdepth++;
1519 start_io(*c);
1520 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
1521
1522 /* the cmd'll come back via intr handler in complete_scsi_command() */
1523 return 0;
1524}
1525
1526static void
1527cciss_unregister_scsi(int ctlr)
1528{
1529 struct cciss_scsi_adapter_data_t *sa;
1530 struct cciss_scsi_cmd_stack_t *stk;
1531 unsigned long flags;
1532
1533 /* we are being forcibly unloaded, and may not refuse. */
1534
1535 spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
1536 sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
1537 stk = &sa->cmd_stack;
1538
1539 /* if we weren't ever actually registered, don't unregister */
1540 if (sa->registered) {
1541 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
1542 scsi_remove_host(sa->scsi_host);
1543 scsi_host_put(sa->scsi_host);
1544 spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
1545 }
1546
1547 /* set scsi_host to NULL so our detect routine will
1548 find us on register */
1549 sa->scsi_host = NULL;
scameron@beardog.cca.cpqcorp.net61950572008-04-17 13:19:04 +02001550 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551 scsi_cmd_stack_free(ctlr);
1552 kfree(sa);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001553}
1554
1555static int
Linus Torvalds1da177e2005-04-16 15:20:36 -07001556cciss_engage_scsi(int ctlr)
1557{
1558 struct cciss_scsi_adapter_data_t *sa;
1559 struct cciss_scsi_cmd_stack_t *stk;
1560 unsigned long flags;
1561
1562 spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
1563 sa = (struct cciss_scsi_adapter_data_t *) hba[ctlr]->scsi_ctlr;
1564 stk = &sa->cmd_stack;
1565
Mike Millerf4a93bc2008-08-04 11:54:53 +02001566 if (sa->registered) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001567 printk("cciss%d: SCSI subsystem already engaged.\n", ctlr);
1568 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
1569 return ENXIO;
1570 }
Mike Millerf4a93bc2008-08-04 11:54:53 +02001571 sa->registered = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001572 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
1573 cciss_update_non_disk_devices(ctlr, -1);
Mike Millerf4a93bc2008-08-04 11:54:53 +02001574 cciss_scsi_detect(ctlr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001575 return 0;
1576}
1577
1578static void
Mike Miller89b6e742008-02-21 08:54:03 +01001579cciss_seq_tape_report(struct seq_file *seq, int ctlr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001580{
1581 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001582
1583 CPQ_TAPE_LOCK(ctlr, flags);
Mike Miller89b6e742008-02-21 08:54:03 +01001584 seq_printf(seq,
Mike Millerb9f0bd02005-09-13 01:25:26 -07001585 "Sequential access devices: %d\n\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001586 ccissscsi[ctlr].ndevices);
1587 CPQ_TAPE_UNLOCK(ctlr, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001588}
1589
Stephen M. Cameron88f627a2009-06-02 14:48:11 +02001590static int wait_for_device_to_become_ready(ctlr_info_t *h,
1591 unsigned char lunaddr[])
1592{
1593 int rc;
1594 int count = 0;
1595 int waittime = HZ;
1596 CommandList_struct *c;
1597
1598 c = cmd_alloc(h, 1);
1599 if (!c) {
1600 printk(KERN_WARNING "cciss%d: out of memory in "
1601 "wait_for_device_to_become_ready.\n", h->ctlr);
1602 return IO_ERROR;
1603 }
1604
1605 /* Send test unit ready until device ready, or give up. */
1606 while (count < 20) {
1607
1608 /* Wait for a bit. do this first, because if we send
1609 * the TUR right away, the reset will just abort it.
1610 */
1611 set_current_state(TASK_INTERRUPTIBLE);
1612 schedule_timeout(waittime);
1613 count++;
1614
1615 /* Increase wait time with each try, up to a point. */
1616 if (waittime < (HZ * 30))
1617 waittime = waittime * 2;
1618
1619 /* Send the Test Unit Ready */
1620 rc = fill_cmd(c, TEST_UNIT_READY, h->ctlr, NULL, 0, 0, 0, 0,
1621 lunaddr, TYPE_CMD);
1622 if (rc == 0) {
1623 rc = sendcmd_core(h, c);
1624 /* sendcmd turned off interrupts, turn 'em back on. */
1625 h->access.set_intr_mask(h, CCISS_INTR_ON);
1626 }
1627
1628 if (rc == 0 && c->err_info->CommandStatus == CMD_SUCCESS)
1629 break;
1630
1631 if (rc == 0 &&
1632 c->err_info->CommandStatus == CMD_TARGET_STATUS &&
1633 c->err_info->ScsiStatus == SAM_STAT_CHECK_CONDITION &&
1634 (c->err_info->SenseInfo[2] == NO_SENSE ||
1635 c->err_info->SenseInfo[2] == UNIT_ATTENTION))
1636 break;
1637
1638 printk(KERN_WARNING "cciss%d: Waiting %d secs "
1639 "for device to become ready.\n",
1640 h->ctlr, waittime / HZ);
1641 rc = 1; /* device not ready. */
1642 }
1643
1644 if (rc)
1645 printk("cciss%d: giving up on device.\n", h->ctlr);
1646 else
1647 printk(KERN_WARNING "cciss%d: device is ready.\n", h->ctlr);
1648
1649 cmd_free(h, c, 1);
1650 return rc;
1651}
Mike Miller89b6e742008-02-21 08:54:03 +01001652
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001653/* Need at least one of these error handlers to keep ../scsi/hosts.c from
1654 * complaining. Doing a host- or bus-reset can't do anything good here.
1655 * Despite what it might say in scsi_error.c, there may well be commands
1656 * on the controller, as the cciss driver registers twice, once as a block
1657 * device for the logical drives, and once as a scsi device, for any tape
1658 * drives. So we know there are no commands out on the tape drives, but we
1659 * don't know there are no commands on the controller, and it is likely
1660 * that there probably are, as the cciss block device is most commonly used
1661 * as a boot device (embedded controller on HP/Compaq systems.)
1662*/
1663
1664static int cciss_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
1665{
1666 int rc;
1667 CommandList_struct *cmd_in_trouble;
Stephen M. Cameron88f627a2009-06-02 14:48:11 +02001668 unsigned char lunaddr[8];
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001669 ctlr_info_t **c;
1670 int ctlr;
1671
1672 /* find the controller to which the command to be aborted was sent */
1673 c = (ctlr_info_t **) &scsicmd->device->host->hostdata[0];
1674 if (c == NULL) /* paranoia */
1675 return FAILED;
1676 ctlr = (*c)->ctlr;
1677 printk(KERN_WARNING "cciss%d: resetting tape drive or medium changer.\n", ctlr);
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001678 /* find the command that's giving us trouble */
1679 cmd_in_trouble = (CommandList_struct *) scsicmd->host_scribble;
Stephen M. Cameron88f627a2009-06-02 14:48:11 +02001680 if (cmd_in_trouble == NULL) /* paranoia */
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001681 return FAILED;
Stephen M. Cameron88f627a2009-06-02 14:48:11 +02001682 memcpy(lunaddr, &cmd_in_trouble->Header.LUN.LunAddrBytes[0], 8);
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001683 /* send a reset to the SCSI LUN which the command was sent to */
Stephen M. Cameron88f627a2009-06-02 14:48:11 +02001684 rc = sendcmd(CCISS_RESET_MSG, ctlr, NULL, 0, 2, 0, 0, lunaddr,
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001685 TYPE_MSG);
Joe Perchesf66083c2008-02-03 17:09:38 +02001686 /* sendcmd turned off interrupts on the board, turn 'em back on. */
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001687 (*c)->access.set_intr_mask(*c, CCISS_INTR_ON);
Stephen M. Cameron88f627a2009-06-02 14:48:11 +02001688 if (rc == 0 && wait_for_device_to_become_ready(*c, lunaddr) == 0)
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001689 return SUCCESS;
1690 printk(KERN_WARNING "cciss%d: resetting device failed.\n", ctlr);
1691 return FAILED;
1692}
1693
1694static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd)
1695{
1696 int rc;
1697 CommandList_struct *cmd_to_abort;
1698 ctlr_info_t **c;
1699 int ctlr;
1700
1701 /* find the controller to which the command to be aborted was sent */
1702 c = (ctlr_info_t **) &scsicmd->device->host->hostdata[0];
1703 if (c == NULL) /* paranoia */
1704 return FAILED;
1705 ctlr = (*c)->ctlr;
1706 printk(KERN_WARNING "cciss%d: aborting tardy SCSI cmd\n", ctlr);
1707
1708 /* find the command to be aborted */
1709 cmd_to_abort = (CommandList_struct *) scsicmd->host_scribble;
1710 if (cmd_to_abort == NULL) /* paranoia */
1711 return FAILED;
1712 rc = sendcmd(CCISS_ABORT_MSG, ctlr, &cmd_to_abort->Header.Tag,
1713 0, 2, 0, 0,
1714 (unsigned char *) &cmd_to_abort->Header.LUN.LunAddrBytes[0],
1715 TYPE_MSG);
Joe Perchesf66083c2008-02-03 17:09:38 +02001716 /* sendcmd turned off interrupts on the board, turn 'em back on. */
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001717 (*c)->access.set_intr_mask(*c, CCISS_INTR_ON);
1718 if (rc == 0)
1719 return SUCCESS;
1720 return FAILED;
1721
1722}
1723
Linus Torvalds1da177e2005-04-16 15:20:36 -07001724#else /* no CONFIG_CISS_SCSI_TAPE */
1725
1726/* If no tape support, then these become defined out of existence */
1727
1728#define cciss_scsi_setup(cntl_num)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001729
1730#endif /* CONFIG_CISS_SCSI_TAPE */