blob: c4582323a07d03c47cb498a18da839fa3ef89a8f [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
Stephen M. Cameron88f627a2009-06-02 14:48:11 +020047static int fill_cmd(CommandList_struct *c, __u8 cmd, int ctlr, void *buff,
48 size_t size,
scameron@beardog.cca.cpqcorp.netb57695f2009-06-08 16:02:17 -050049 __u8 page_code, unsigned char *scsi3addr,
Stephen M. Cameron88f627a2009-06-02 14:48:11 +020050 int cmd_type);
51
Stephen M. Cameron88f627a2009-06-02 14:48:11 +020052static CommandList_struct *cmd_alloc(ctlr_info_t *h, int get_from_pool);
53static void cmd_free(ctlr_info_t *h, CommandList_struct *c, int got_from_pool);
Linus Torvalds1da177e2005-04-16 15:20:36 -070054
55static int cciss_scsi_proc_info(
56 struct Scsi_Host *sh,
57 char *buffer, /* data buffer */
58 char **start, /* where data in buffer starts */
59 off_t offset, /* offset from start of imaginary file */
60 int length, /* length of data in buffer */
61 int func); /* 0 == read, 1 == write */
62
63static int cciss_scsi_queue_command (struct scsi_cmnd *cmd,
64 void (* done)(struct scsi_cmnd *));
mike.miller@hp.com3da8b712005-11-04 12:30:37 -060065static int cciss_eh_device_reset_handler(struct scsi_cmnd *);
66static int cciss_eh_abort_handler(struct scsi_cmnd *);
Linus Torvalds1da177e2005-04-16 15:20:36 -070067
68static struct cciss_scsi_hba_t ccissscsi[MAX_CTLR] = {
69 { .name = "cciss0", .ndevices = 0 },
70 { .name = "cciss1", .ndevices = 0 },
71 { .name = "cciss2", .ndevices = 0 },
72 { .name = "cciss3", .ndevices = 0 },
73 { .name = "cciss4", .ndevices = 0 },
74 { .name = "cciss5", .ndevices = 0 },
75 { .name = "cciss6", .ndevices = 0 },
76 { .name = "cciss7", .ndevices = 0 },
77};
78
79static struct scsi_host_template cciss_driver_template = {
80 .module = THIS_MODULE,
81 .name = "cciss",
82 .proc_name = "cciss",
83 .proc_info = cciss_scsi_proc_info,
84 .queuecommand = cciss_scsi_queue_command,
85 .can_queue = SCSI_CCISS_CAN_QUEUE,
86 .this_id = 7,
87 .sg_tablesize = MAXSGENTRIES,
88 .cmd_per_lun = 1,
89 .use_clustering = DISABLE_CLUSTERING,
mike.miller@hp.com3da8b712005-11-04 12:30:37 -060090 /* Can't have eh_bus_reset_handler or eh_host_reset_handler for cciss */
91 .eh_device_reset_handler= cciss_eh_device_reset_handler,
92 .eh_abort_handler = cciss_eh_abort_handler,
Linus Torvalds1da177e2005-04-16 15:20:36 -070093};
94
95#pragma pack(1)
Stephen M. Cameron1b7d0d22010-02-26 16:01:17 -060096
97#define SCSI_PAD_32 4
98#define SCSI_PAD_64 4
99
Linus Torvalds1da177e2005-04-16 15:20:36 -0700100struct cciss_scsi_cmd_stack_elem_t {
101 CommandList_struct cmd;
102 ErrorInfo_struct Err;
103 __u32 busaddr;
Stephen M. Cameron1b7d0d22010-02-26 16:01:17 -0600104 u8 pad[IS_32_BIT * SCSI_PAD_32 + IS_64_BIT * SCSI_PAD_64];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700105};
106
107#pragma pack()
108
109#define CMD_STACK_SIZE (SCSI_CCISS_CAN_QUEUE * \
110 CCISS_MAX_SCSI_DEVS_PER_HBA + 2)
111 // plus two for init time usage
112
113#pragma pack(1)
114struct cciss_scsi_cmd_stack_t {
115 struct cciss_scsi_cmd_stack_elem_t *pool;
116 struct cciss_scsi_cmd_stack_elem_t *elem[CMD_STACK_SIZE];
117 dma_addr_t cmd_pool_handle;
118 int top;
119};
120#pragma pack()
121
122struct cciss_scsi_adapter_data_t {
123 struct Scsi_Host *scsi_host;
124 struct cciss_scsi_cmd_stack_t cmd_stack;
125 int registered;
126 spinlock_t lock; // to protect ccissscsi[ctlr];
127};
128
129#define CPQ_TAPE_LOCK(ctlr, flags) spin_lock_irqsave( \
Stephen M. Cameronaad9fb62010-02-26 16:01:42 -0600130 &hba[ctlr]->scsi_ctlr->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700131#define CPQ_TAPE_UNLOCK(ctlr, flags) spin_unlock_irqrestore( \
Stephen M. Cameronaad9fb62010-02-26 16:01:42 -0600132 &hba[ctlr]->scsi_ctlr->lock, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700133
134static CommandList_struct *
135scsi_cmd_alloc(ctlr_info_t *h)
136{
137 /* assume only one process in here at a time, locking done by caller. */
138 /* use CCISS_LOCK(ctlr) */
139 /* might be better to rewrite how we allocate scsi commands in a way that */
140 /* needs no locking at all. */
141
142 /* take the top memory chunk off the stack and return it, if any. */
143 struct cciss_scsi_cmd_stack_elem_t *c;
144 struct cciss_scsi_adapter_data_t *sa;
145 struct cciss_scsi_cmd_stack_t *stk;
146 u64bit temp64;
147
Stephen M. Cameronaad9fb62010-02-26 16:01:42 -0600148 sa = h->scsi_ctlr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700149 stk = &sa->cmd_stack;
150
151 if (stk->top < 0)
152 return NULL;
153 c = stk->elem[stk->top];
154 /* memset(c, 0, sizeof(*c)); */
155 memset(&c->cmd, 0, sizeof(c->cmd));
156 memset(&c->Err, 0, sizeof(c->Err));
157 /* set physical addr of cmd and addr of scsi parameters */
158 c->cmd.busaddr = c->busaddr;
159 /* (__u32) (stk->cmd_pool_handle +
160 (sizeof(struct cciss_scsi_cmd_stack_elem_t)*stk->top)); */
161
162 temp64.val = (__u64) (c->busaddr + sizeof(CommandList_struct));
163 /* (__u64) (stk->cmd_pool_handle +
164 (sizeof(struct cciss_scsi_cmd_stack_elem_t)*stk->top) +
165 sizeof(CommandList_struct)); */
166 stk->top--;
167 c->cmd.ErrDesc.Addr.lower = temp64.val32.lower;
168 c->cmd.ErrDesc.Addr.upper = temp64.val32.upper;
169 c->cmd.ErrDesc.Len = sizeof(ErrorInfo_struct);
170
171 c->cmd.ctlr = h->ctlr;
172 c->cmd.err_info = &c->Err;
173
174 return (CommandList_struct *) c;
175}
176
177static void
178scsi_cmd_free(ctlr_info_t *h, CommandList_struct *cmd)
179{
180 /* assume only one process in here at a time, locking done by caller. */
181 /* use CCISS_LOCK(ctlr) */
182 /* drop the free memory chunk on top of the stack. */
183
184 struct cciss_scsi_adapter_data_t *sa;
185 struct cciss_scsi_cmd_stack_t *stk;
186
Stephen M. Cameronaad9fb62010-02-26 16:01:42 -0600187 sa = h->scsi_ctlr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700188 stk = &sa->cmd_stack;
189 if (stk->top >= CMD_STACK_SIZE) {
190 printk("cciss: scsi_cmd_free called too many times.\n");
191 BUG();
192 }
193 stk->top++;
194 stk->elem[stk->top] = (struct cciss_scsi_cmd_stack_elem_t *) cmd;
195}
196
197static int
198scsi_cmd_stack_setup(int ctlr, struct cciss_scsi_adapter_data_t *sa)
199{
200 int i;
201 struct cciss_scsi_cmd_stack_t *stk;
202 size_t size;
203
204 stk = &sa->cmd_stack;
205 size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;
206
Stephen M. Cameron1b7d0d22010-02-26 16:01:17 -0600207 /* Check alignment, see cciss_cmd.h near CommandList_struct def. */
208 BUILD_BUG_ON((sizeof(*stk->pool) % COMMANDLIST_ALIGNMENT) != 0);
209 /* pci_alloc_consistent guarantees 32-bit DMA address will be used */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700210 stk->pool = (struct cciss_scsi_cmd_stack_elem_t *)
211 pci_alloc_consistent(hba[ctlr]->pdev, size, &stk->cmd_pool_handle);
212
213 if (stk->pool == NULL) {
214 printk("stk->pool is null\n");
215 return -1;
216 }
217
218 for (i=0; i<CMD_STACK_SIZE; i++) {
219 stk->elem[i] = &stk->pool[i];
220 stk->elem[i]->busaddr = (__u32) (stk->cmd_pool_handle +
221 (sizeof(struct cciss_scsi_cmd_stack_elem_t) * i));
222 }
223 stk->top = CMD_STACK_SIZE-1;
224 return 0;
225}
226
227static void
228scsi_cmd_stack_free(int ctlr)
229{
230 struct cciss_scsi_adapter_data_t *sa;
231 struct cciss_scsi_cmd_stack_t *stk;
232 size_t size;
233
Stephen M. Cameronaad9fb62010-02-26 16:01:42 -0600234 sa = hba[ctlr]->scsi_ctlr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700235 stk = &sa->cmd_stack;
236 if (stk->top != CMD_STACK_SIZE-1) {
237 printk( "cciss: %d scsi commands are still outstanding.\n",
238 CMD_STACK_SIZE - stk->top);
239 // BUG();
240 printk("WE HAVE A BUG HERE!!! stk=0x%p\n", stk);
241 }
242 size = sizeof(struct cciss_scsi_cmd_stack_elem_t) * CMD_STACK_SIZE;
243
244 pci_free_consistent(hba[ctlr]->pdev, size, stk->pool, stk->cmd_pool_handle);
245 stk->pool = NULL;
246}
247
Grant Coady400bb232005-11-15 00:09:20 -0800248#if 0
Linus Torvalds1da177e2005-04-16 15:20:36 -0700249static int xmargin=8;
250static int amargin=60;
251
252static void
253print_bytes (unsigned char *c, int len, int hex, int ascii)
254{
255
256 int i;
257 unsigned char *x;
258
259 if (hex)
260 {
261 x = c;
262 for (i=0;i<len;i++)
263 {
264 if ((i % xmargin) == 0 && i>0) printk("\n");
265 if ((i % xmargin) == 0) printk("0x%04x:", i);
266 printk(" %02x", *x);
267 x++;
268 }
269 printk("\n");
270 }
271 if (ascii)
272 {
273 x = c;
274 for (i=0;i<len;i++)
275 {
276 if ((i % amargin) == 0 && i>0) printk("\n");
277 if ((i % amargin) == 0) printk("0x%04x:", i);
278 if (*x > 26 && *x < 128) printk("%c", *x);
279 else printk(".");
280 x++;
281 }
282 printk("\n");
283 }
284}
285
286static void
287print_cmd(CommandList_struct *cp)
288{
289 printk("queue:%d\n", cp->Header.ReplyQueue);
290 printk("sglist:%d\n", cp->Header.SGList);
291 printk("sgtot:%d\n", cp->Header.SGTotal);
292 printk("Tag:0x%08x/0x%08x\n", cp->Header.Tag.upper,
293 cp->Header.Tag.lower);
294 printk("LUN:0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
295 cp->Header.LUN.LunAddrBytes[0],
296 cp->Header.LUN.LunAddrBytes[1],
297 cp->Header.LUN.LunAddrBytes[2],
298 cp->Header.LUN.LunAddrBytes[3],
299 cp->Header.LUN.LunAddrBytes[4],
300 cp->Header.LUN.LunAddrBytes[5],
301 cp->Header.LUN.LunAddrBytes[6],
302 cp->Header.LUN.LunAddrBytes[7]);
303 printk("CDBLen:%d\n", cp->Request.CDBLen);
304 printk("Type:%d\n",cp->Request.Type.Type);
305 printk("Attr:%d\n",cp->Request.Type.Attribute);
306 printk(" Dir:%d\n",cp->Request.Type.Direction);
307 printk("Timeout:%d\n",cp->Request.Timeout);
308 printk( "CDB: %02x %02x %02x %02x %02x %02x %02x %02x"
309 " %02x %02x %02x %02x %02x %02x %02x %02x\n",
310 cp->Request.CDB[0], cp->Request.CDB[1],
311 cp->Request.CDB[2], cp->Request.CDB[3],
312 cp->Request.CDB[4], cp->Request.CDB[5],
313 cp->Request.CDB[6], cp->Request.CDB[7],
314 cp->Request.CDB[8], cp->Request.CDB[9],
315 cp->Request.CDB[10], cp->Request.CDB[11],
316 cp->Request.CDB[12], cp->Request.CDB[13],
317 cp->Request.CDB[14], cp->Request.CDB[15]),
318 printk("edesc.Addr: 0x%08x/0%08x, Len = %d\n",
319 cp->ErrDesc.Addr.upper, cp->ErrDesc.Addr.lower,
320 cp->ErrDesc.Len);
321 printk("sgs..........Errorinfo:\n");
322 printk("scsistatus:%d\n", cp->err_info->ScsiStatus);
323 printk("senselen:%d\n", cp->err_info->SenseLen);
324 printk("cmd status:%d\n", cp->err_info->CommandStatus);
325 printk("resid cnt:%d\n", cp->err_info->ResidualCnt);
326 printk("offense size:%d\n", cp->err_info->MoreErrInfo.Invalid_Cmd.offense_size);
327 printk("offense byte:%d\n", cp->err_info->MoreErrInfo.Invalid_Cmd.offense_num);
328 printk("offense value:%d\n", cp->err_info->MoreErrInfo.Invalid_Cmd.offense_value);
329
330}
331
332#endif
333
334static int
335find_bus_target_lun(int ctlr, int *bus, int *target, int *lun)
336{
337 /* finds an unused bus, target, lun for a new device */
338 /* assumes hba[ctlr]->scsi_ctlr->lock is held */
339 int i, found=0;
340 unsigned char target_taken[CCISS_MAX_SCSI_DEVS_PER_HBA];
341
342 memset(&target_taken[0], 0, CCISS_MAX_SCSI_DEVS_PER_HBA);
343
344 target_taken[SELF_SCSI_ID] = 1;
345 for (i=0;i<ccissscsi[ctlr].ndevices;i++)
346 target_taken[ccissscsi[ctlr].dev[i].target] = 1;
347
348 for (i=0;i<CCISS_MAX_SCSI_DEVS_PER_HBA;i++) {
349 if (!target_taken[i]) {
350 *bus = 0; *target=i; *lun = 0; found=1;
351 break;
352 }
353 }
354 return (!found);
355}
Mike Millerf4a93bc2008-08-04 11:54:53 +0200356struct scsi2map {
357 char scsi3addr[8];
358 int bus, target, lun;
359};
Linus Torvalds1da177e2005-04-16 15:20:36 -0700360
361static int
362cciss_scsi_add_entry(int ctlr, int hostno,
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700363 struct cciss_scsi_dev_t *device,
Mike Millerf4a93bc2008-08-04 11:54:53 +0200364 struct scsi2map *added, int *nadded)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700365{
366 /* assumes hba[ctlr]->scsi_ctlr->lock is held */
367 int n = ccissscsi[ctlr].ndevices;
368 struct cciss_scsi_dev_t *sd;
Mike Miller935dc8d2008-08-04 11:54:54 +0200369 int i, bus, target, lun;
370 unsigned char addr1[8], addr2[8];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700371
372 if (n >= CCISS_MAX_SCSI_DEVS_PER_HBA) {
373 printk("cciss%d: Too many devices, "
374 "some will be inaccessible.\n", ctlr);
375 return -1;
376 }
Mike Millerf4a93bc2008-08-04 11:54:53 +0200377
Mike Miller935dc8d2008-08-04 11:54:54 +0200378 bus = target = -1;
379 lun = 0;
380 /* Is this device a non-zero lun of a multi-lun device */
381 /* byte 4 of the 8-byte LUN addr will contain the logical unit no. */
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700382 if (device->scsi3addr[4] != 0) {
Mike Miller935dc8d2008-08-04 11:54:54 +0200383 /* Search through our list and find the device which */
384 /* has the same 8 byte LUN address, excepting byte 4. */
385 /* Assign the same bus and target for this new LUN. */
386 /* Use the logical unit number from the firmware. */
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700387 memcpy(addr1, device->scsi3addr, 8);
Mike Miller935dc8d2008-08-04 11:54:54 +0200388 addr1[4] = 0;
389 for (i = 0; i < n; i++) {
390 sd = &ccissscsi[ctlr].dev[i];
391 memcpy(addr2, sd->scsi3addr, 8);
392 addr2[4] = 0;
393 /* differ only in byte 4? */
394 if (memcmp(addr1, addr2, 8) == 0) {
395 bus = sd->bus;
396 target = sd->target;
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700397 lun = device->scsi3addr[4];
Mike Miller935dc8d2008-08-04 11:54:54 +0200398 break;
399 }
400 }
401 }
402
403 sd = &ccissscsi[ctlr].dev[n];
404 if (lun == 0) {
405 if (find_bus_target_lun(ctlr,
406 &sd->bus, &sd->target, &sd->lun) != 0)
407 return -1;
408 } else {
409 sd->bus = bus;
410 sd->target = target;
411 sd->lun = lun;
412 }
Mike Millerf4a93bc2008-08-04 11:54:53 +0200413 added[*nadded].bus = sd->bus;
414 added[*nadded].target = sd->target;
415 added[*nadded].lun = sd->lun;
416 (*nadded)++;
417
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700418 memcpy(sd->scsi3addr, device->scsi3addr, 8);
419 memcpy(sd->vendor, device->vendor, sizeof(sd->vendor));
420 memcpy(sd->revision, device->revision, sizeof(sd->revision));
421 memcpy(sd->device_id, device->device_id, sizeof(sd->device_id));
422 sd->devtype = device->devtype;
423
Linus Torvalds1da177e2005-04-16 15:20:36 -0700424 ccissscsi[ctlr].ndevices++;
425
426 /* initially, (before registering with scsi layer) we don't
427 know our hostno and we don't want to print anything first
428 time anyway (the scsi layer's inquiries will show that info) */
429 if (hostno != -1)
430 printk("cciss%d: %s device c%db%dt%dl%d added.\n",
Matthew Wilcox4ff36712006-07-04 12:15:20 -0600431 ctlr, scsi_device_type(sd->devtype), hostno,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700432 sd->bus, sd->target, sd->lun);
433 return 0;
434}
435
436static void
Mike Millerf4a93bc2008-08-04 11:54:53 +0200437cciss_scsi_remove_entry(int ctlr, int hostno, int entry,
438 struct scsi2map *removed, int *nremoved)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700439{
440 /* assumes hba[ctlr]->scsi_ctlr->lock is held */
441 int i;
442 struct cciss_scsi_dev_t sd;
443
444 if (entry < 0 || entry >= CCISS_MAX_SCSI_DEVS_PER_HBA) return;
445 sd = ccissscsi[ctlr].dev[entry];
Mike Millerf4a93bc2008-08-04 11:54:53 +0200446 removed[*nremoved].bus = sd.bus;
447 removed[*nremoved].target = sd.target;
448 removed[*nremoved].lun = sd.lun;
449 (*nremoved)++;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700450 for (i=entry;i<ccissscsi[ctlr].ndevices-1;i++)
451 ccissscsi[ctlr].dev[i] = ccissscsi[ctlr].dev[i+1];
452 ccissscsi[ctlr].ndevices--;
453 printk("cciss%d: %s device c%db%dt%dl%d removed.\n",
Matthew Wilcox4ff36712006-07-04 12:15:20 -0600454 ctlr, scsi_device_type(sd.devtype), hostno,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700455 sd.bus, sd.target, sd.lun);
456}
457
458
459#define SCSI3ADDR_EQ(a,b) ( \
460 (a)[7] == (b)[7] && \
461 (a)[6] == (b)[6] && \
462 (a)[5] == (b)[5] && \
463 (a)[4] == (b)[4] && \
464 (a)[3] == (b)[3] && \
465 (a)[2] == (b)[2] && \
466 (a)[1] == (b)[1] && \
467 (a)[0] == (b)[0])
468
Mike Millerf4a93bc2008-08-04 11:54:53 +0200469static void fixup_botched_add(int ctlr, char *scsi3addr)
470{
471 /* called when scsi_add_device fails in order to re-adjust */
472 /* ccissscsi[] to match the mid layer's view. */
473 unsigned long flags;
474 int i, j;
475 CPQ_TAPE_LOCK(ctlr, flags);
476 for (i = 0; i < ccissscsi[ctlr].ndevices; i++) {
477 if (memcmp(scsi3addr,
478 ccissscsi[ctlr].dev[i].scsi3addr, 8) == 0) {
479 for (j = i; j < ccissscsi[ctlr].ndevices-1; j++)
480 ccissscsi[ctlr].dev[j] =
481 ccissscsi[ctlr].dev[j+1];
482 ccissscsi[ctlr].ndevices--;
483 break;
484 }
485 }
486 CPQ_TAPE_UNLOCK(ctlr, flags);
487}
488
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700489static int device_is_the_same(struct cciss_scsi_dev_t *dev1,
490 struct cciss_scsi_dev_t *dev2)
491{
492 return dev1->devtype == dev2->devtype &&
493 memcmp(dev1->scsi3addr, dev2->scsi3addr,
494 sizeof(dev1->scsi3addr)) == 0 &&
495 memcmp(dev1->device_id, dev2->device_id,
496 sizeof(dev1->device_id)) == 0 &&
497 memcmp(dev1->vendor, dev2->vendor,
498 sizeof(dev1->vendor)) == 0 &&
499 memcmp(dev1->model, dev2->model,
500 sizeof(dev1->model)) == 0 &&
501 memcmp(dev1->revision, dev2->revision,
502 sizeof(dev1->revision)) == 0;
503}
504
Linus Torvalds1da177e2005-04-16 15:20:36 -0700505static int
506adjust_cciss_scsi_table(int ctlr, int hostno,
507 struct cciss_scsi_dev_t sd[], int nsds)
508{
509 /* sd contains scsi3 addresses and devtypes, but
510 bus target and lun are not filled in. This funciton
511 takes what's in sd to be the current and adjusts
512 ccissscsi[] to be in line with what's in sd. */
513
514 int i,j, found, changes=0;
515 struct cciss_scsi_dev_t *csd;
516 unsigned long flags;
Mike Millerf4a93bc2008-08-04 11:54:53 +0200517 struct scsi2map *added, *removed;
518 int nadded, nremoved;
519 struct Scsi_Host *sh = NULL;
520
521 added = kzalloc(sizeof(*added) * CCISS_MAX_SCSI_DEVS_PER_HBA,
522 GFP_KERNEL);
523 removed = kzalloc(sizeof(*removed) * CCISS_MAX_SCSI_DEVS_PER_HBA,
524 GFP_KERNEL);
525
526 if (!added || !removed) {
527 printk(KERN_WARNING "cciss%d: Out of memory in "
528 "adjust_cciss_scsi_table\n", ctlr);
529 goto free_and_out;
530 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700531
532 CPQ_TAPE_LOCK(ctlr, flags);
533
Mike Millerf4a93bc2008-08-04 11:54:53 +0200534 if (hostno != -1) /* if it's not the first time... */
Stephen M. Cameronaad9fb62010-02-26 16:01:42 -0600535 sh = hba[ctlr]->scsi_ctlr->scsi_host;
Mike Millerf4a93bc2008-08-04 11:54:53 +0200536
Linus Torvalds1da177e2005-04-16 15:20:36 -0700537 /* find any devices in ccissscsi[] that are not in
538 sd[] and remove them from ccissscsi[] */
539
540 i = 0;
Mike Millerf4a93bc2008-08-04 11:54:53 +0200541 nremoved = 0;
542 nadded = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700543 while(i<ccissscsi[ctlr].ndevices) {
544 csd = &ccissscsi[ctlr].dev[i];
545 found=0;
546 for (j=0;j<nsds;j++) {
547 if (SCSI3ADDR_EQ(sd[j].scsi3addr,
548 csd->scsi3addr)) {
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700549 if (device_is_the_same(&sd[j], csd))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700550 found=2;
551 else
552 found=1;
553 break;
554 }
555 }
556
557 if (found == 0) { /* device no longer present. */
558 changes++;
559 /* printk("cciss%d: %s device c%db%dt%dl%d removed.\n",
Matthew Wilcox4ff36712006-07-04 12:15:20 -0600560 ctlr, scsi_device_type(csd->devtype), hostno,
Linus Torvalds1da177e2005-04-16 15:20:36 -0700561 csd->bus, csd->target, csd->lun); */
Mike Millerf4a93bc2008-08-04 11:54:53 +0200562 cciss_scsi_remove_entry(ctlr, hostno, i,
563 removed, &nremoved);
564 /* remove ^^^, hence i not incremented */
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700565 } else if (found == 1) { /* device is different in some way */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700566 changes++;
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700567 printk("cciss%d: device c%db%dt%dl%d has changed.\n",
568 ctlr, hostno, csd->bus, csd->target, csd->lun);
Mike Millerf4a93bc2008-08-04 11:54:53 +0200569 cciss_scsi_remove_entry(ctlr, hostno, i,
570 removed, &nremoved);
571 /* remove ^^^, hence i not incremented */
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700572 if (cciss_scsi_add_entry(ctlr, hostno, &sd[j],
Mike Millerf4a93bc2008-08-04 11:54:53 +0200573 added, &nadded) != 0)
574 /* we just removed one, so add can't fail. */
575 BUG();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700576 csd->devtype = sd[j].devtype;
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700577 memcpy(csd->device_id, sd[j].device_id,
578 sizeof(csd->device_id));
579 memcpy(csd->vendor, sd[j].vendor,
580 sizeof(csd->vendor));
581 memcpy(csd->model, sd[j].model,
582 sizeof(csd->model));
583 memcpy(csd->revision, sd[j].revision,
584 sizeof(csd->revision));
Linus Torvalds1da177e2005-04-16 15:20:36 -0700585 } else /* device is same as it ever was, */
586 i++; /* so just move along. */
587 }
588
589 /* Now, make sure every device listed in sd[] is also
590 listed in ccissscsi[], adding them if they aren't found */
591
592 for (i=0;i<nsds;i++) {
593 found=0;
594 for (j=0;j<ccissscsi[ctlr].ndevices;j++) {
595 csd = &ccissscsi[ctlr].dev[j];
596 if (SCSI3ADDR_EQ(sd[i].scsi3addr,
597 csd->scsi3addr)) {
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700598 if (device_is_the_same(&sd[i], csd))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700599 found=2; /* found device */
600 else
601 found=1; /* found a bug. */
602 break;
603 }
604 }
605 if (!found) {
606 changes++;
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700607 if (cciss_scsi_add_entry(ctlr, hostno, &sd[i],
Mike Millerf4a93bc2008-08-04 11:54:53 +0200608 added, &nadded) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700609 break;
610 } else if (found == 1) {
611 /* should never happen... */
612 changes++;
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -0700613 printk(KERN_WARNING "cciss%d: device "
614 "unexpectedly changed\n", ctlr);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700615 /* but if it does happen, we just ignore that device */
616 }
617 }
618 CPQ_TAPE_UNLOCK(ctlr, flags);
619
Mike Millerf4a93bc2008-08-04 11:54:53 +0200620 /* Don't notify scsi mid layer of any changes the first time through */
621 /* (or if there are no changes) scsi_scan_host will do it later the */
622 /* first time through. */
623 if (hostno == -1 || !changes)
624 goto free_and_out;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700625
Mike Millerf4a93bc2008-08-04 11:54:53 +0200626 /* Notify scsi mid layer of any removed devices */
627 for (i = 0; i < nremoved; i++) {
628 struct scsi_device *sdev =
629 scsi_device_lookup(sh, removed[i].bus,
630 removed[i].target, removed[i].lun);
631 if (sdev != NULL) {
632 scsi_remove_device(sdev);
633 scsi_device_put(sdev);
634 } else {
635 /* We don't expect to get here. */
636 /* future cmds to this device will get selection */
637 /* timeout as if the device was gone. */
638 printk(KERN_WARNING "cciss%d: didn't find "
639 "c%db%dt%dl%d\n for removal.",
640 ctlr, hostno, removed[i].bus,
641 removed[i].target, removed[i].lun);
642 }
643 }
644
645 /* Notify scsi mid layer of any added devices */
646 for (i = 0; i < nadded; i++) {
647 int rc;
648 rc = scsi_add_device(sh, added[i].bus,
649 added[i].target, added[i].lun);
650 if (rc == 0)
651 continue;
652 printk(KERN_WARNING "cciss%d: scsi_add_device "
653 "c%db%dt%dl%d failed, device not added.\n",
654 ctlr, hostno,
655 added[i].bus, added[i].target, added[i].lun);
656 /* now we have to remove it from ccissscsi, */
657 /* since it didn't get added to scsi mid layer */
658 fixup_botched_add(ctlr, added[i].scsi3addr);
659 }
660
661free_and_out:
662 kfree(added);
663 kfree(removed);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700664 return 0;
665}
666
667static int
668lookup_scsi3addr(int ctlr, int bus, int target, int lun, char *scsi3addr)
669{
670 int i;
671 struct cciss_scsi_dev_t *sd;
672 unsigned long flags;
673
674 CPQ_TAPE_LOCK(ctlr, flags);
675 for (i=0;i<ccissscsi[ctlr].ndevices;i++) {
676 sd = &ccissscsi[ctlr].dev[i];
677 if (sd->bus == bus &&
678 sd->target == target &&
679 sd->lun == lun) {
680 memcpy(scsi3addr, &sd->scsi3addr[0], 8);
681 CPQ_TAPE_UNLOCK(ctlr, flags);
682 return 0;
683 }
684 }
685 CPQ_TAPE_UNLOCK(ctlr, flags);
686 return -1;
687}
688
689static void
690cciss_scsi_setup(int cntl_num)
691{
692 struct cciss_scsi_adapter_data_t * shba;
693
694 ccissscsi[cntl_num].ndevices = 0;
695 shba = (struct cciss_scsi_adapter_data_t *)
696 kmalloc(sizeof(*shba), GFP_KERNEL);
697 if (shba == NULL)
698 return;
699 shba->scsi_host = NULL;
700 spin_lock_init(&shba->lock);
701 shba->registered = 0;
702 if (scsi_cmd_stack_setup(cntl_num, shba) != 0) {
703 kfree(shba);
704 shba = NULL;
705 }
Stephen M. Cameronaad9fb62010-02-26 16:01:42 -0600706 hba[cntl_num]->scsi_ctlr = shba;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700707 return;
708}
709
710static void
711complete_scsi_command( CommandList_struct *cp, int timeout, __u32 tag)
712{
713 struct scsi_cmnd *cmd;
714 ctlr_info_t *ctlr;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 ErrorInfo_struct *ei;
716
717 ei = cp->err_info;
718
719 /* First, see if it was a message rather than a command */
720 if (cp->Request.Type.Type == TYPE_MSG) {
721 cp->cmd_type = CMD_MSG_DONE;
722 return;
723 }
724
725 cmd = (struct scsi_cmnd *) cp->scsi_cmd;
726 ctlr = hba[cp->ctlr];
727
FUJITA Tomonori41ce6392007-05-26 02:45:17 +0900728 scsi_dma_unmap(cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700729
730 cmd->result = (DID_OK << 16); /* host byte */
731 cmd->result |= (COMMAND_COMPLETE << 8); /* msg byte */
732 /* cmd->result |= (GOOD < 1); */ /* status byte */
733
734 cmd->result |= (ei->ScsiStatus);
735 /* printk("Scsistatus is 0x%02x\n", ei->ScsiStatus); */
736
737 /* copy the sense data whether we need to or not. */
738
739 memcpy(cmd->sense_buffer, ei->SenseInfo,
740 ei->SenseLen > SCSI_SENSE_BUFFERSIZE ?
741 SCSI_SENSE_BUFFERSIZE :
742 ei->SenseLen);
FUJITA Tomonori41ce6392007-05-26 02:45:17 +0900743 scsi_set_resid(cmd, ei->ResidualCnt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700744
745 if(ei->CommandStatus != 0)
746 { /* an error has occurred */
747 switch(ei->CommandStatus)
748 {
749 case CMD_TARGET_STATUS:
750 /* Pass it up to the upper layers... */
751 if( ei->ScsiStatus)
752 {
753#if 0
754 printk(KERN_WARNING "cciss: cmd %p "
755 "has SCSI Status = %x\n",
756 cp,
757 ei->ScsiStatus);
758#endif
Stephen M. Cameronb0e15f62009-11-12 12:49:45 -0600759 cmd->result |= (ei->ScsiStatus << 1);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700760 }
761 else { /* scsi status is zero??? How??? */
762
763 /* Ordinarily, this case should never happen, but there is a bug
764 in some released firmware revisions that allows it to happen
765 if, for example, a 4100 backplane loses power and the tape
766 drive is in it. We assume that it's a fatal error of some
767 kind because we can't show that it wasn't. We will make it
768 look like selection timeout since that is the most common
769 reason for this to occur, and it's severe enough. */
770
771 cmd->result = DID_NO_CONNECT << 16;
772 }
773 break;
774 case CMD_DATA_UNDERRUN: /* let mid layer handle it. */
775 break;
776 case CMD_DATA_OVERRUN:
777 printk(KERN_WARNING "cciss: cp %p has"
778 " completed with data overrun "
779 "reported\n", cp);
780 break;
781 case CMD_INVALID: {
782 /* print_bytes(cp, sizeof(*cp), 1, 0);
783 print_cmd(cp); */
784 /* We get CMD_INVALID if you address a non-existent tape drive instead
785 of a selection timeout (no response). You will see this if you yank
786 out a tape drive, then try to access it. This is kind of a shame
787 because it means that any other CMD_INVALID (e.g. driver bug) will
788 get interpreted as a missing target. */
789 cmd->result = DID_NO_CONNECT << 16;
790 }
791 break;
792 case CMD_PROTOCOL_ERR:
793 printk(KERN_WARNING "cciss: cp %p has "
794 "protocol error \n", cp);
795 break;
796 case CMD_HARDWARE_ERR:
797 cmd->result = DID_ERROR << 16;
798 printk(KERN_WARNING "cciss: cp %p had "
799 " hardware error\n", cp);
800 break;
801 case CMD_CONNECTION_LOST:
802 cmd->result = DID_ERROR << 16;
803 printk(KERN_WARNING "cciss: cp %p had "
804 "connection lost\n", cp);
805 break;
806 case CMD_ABORTED:
807 cmd->result = DID_ABORT << 16;
808 printk(KERN_WARNING "cciss: cp %p was "
809 "aborted\n", cp);
810 break;
811 case CMD_ABORT_FAILED:
812 cmd->result = DID_ERROR << 16;
813 printk(KERN_WARNING "cciss: cp %p reports "
814 "abort failed\n", cp);
815 break;
816 case CMD_UNSOLICITED_ABORT:
817 cmd->result = DID_ABORT << 16;
818 printk(KERN_WARNING "cciss: cp %p aborted "
819 "do to an unsolicited abort\n", cp);
820 break;
821 case CMD_TIMEOUT:
822 cmd->result = DID_TIME_OUT << 16;
823 printk(KERN_WARNING "cciss: cp %p timedout\n",
824 cp);
825 break;
826 default:
827 cmd->result = DID_ERROR << 16;
828 printk(KERN_WARNING "cciss: cp %p returned "
829 "unknown status %x\n", cp,
830 ei->CommandStatus);
831 }
832 }
833 // printk("c:%p:c%db%dt%dl%d ", cmd, ctlr->ctlr, cmd->channel,
834 // cmd->target, cmd->lun);
835 cmd->scsi_done(cmd);
836 scsi_cmd_free(ctlr, cp);
837}
838
839static int
840cciss_scsi_detect(int ctlr)
841{
842 struct Scsi_Host *sh;
843 int error;
844
845 sh = scsi_host_alloc(&cciss_driver_template, sizeof(struct ctlr_info *));
846 if (sh == NULL)
847 goto fail;
848 sh->io_port = 0; // good enough? FIXME,
849 sh->n_io_port = 0; // I don't think we use these two...
850 sh->this_id = SELF_SCSI_ID;
851
852 ((struct cciss_scsi_adapter_data_t *)
Stephen M. Cameronaad9fb62010-02-26 16:01:42 -0600853 hba[ctlr]->scsi_ctlr)->scsi_host = sh;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700854 sh->hostdata[0] = (unsigned long) hba[ctlr];
Mike Millerfb86a352006-01-08 01:03:50 -0800855 sh->irq = hba[ctlr]->intr[SIMPLE_MODE_INT];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700856 sh->unique_id = sh->irq;
857 error = scsi_add_host(sh, &hba[ctlr]->pdev->dev);
858 if (error)
859 goto fail_host_put;
860 scsi_scan_host(sh);
861 return 1;
862
863 fail_host_put:
864 scsi_host_put(sh);
865 fail:
866 return 0;
867}
868
869static void
870cciss_unmap_one(struct pci_dev *pdev,
871 CommandList_struct *cp,
872 size_t buflen,
873 int data_direction)
874{
875 u64bit addr64;
876
877 addr64.val32.lower = cp->SG[0].Addr.lower;
878 addr64.val32.upper = cp->SG[0].Addr.upper;
879 pci_unmap_single(pdev, (dma_addr_t) addr64.val, buflen, data_direction);
880}
881
882static void
883cciss_map_one(struct pci_dev *pdev,
884 CommandList_struct *cp,
885 unsigned char *buf,
886 size_t buflen,
887 int data_direction)
888{
889 __u64 addr64;
890
891 addr64 = (__u64) pci_map_single(pdev, buf, buflen, data_direction);
892 cp->SG[0].Addr.lower =
893 (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
894 cp->SG[0].Addr.upper =
895 (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
896 cp->SG[0].Len = buflen;
897 cp->Header.SGList = (__u8) 1; /* no. SGs contig in this cmd */
898 cp->Header.SGTotal = (__u16) 1; /* total sgs in this cmd list */
899}
900
901static int
902cciss_scsi_do_simple_cmd(ctlr_info_t *c,
903 CommandList_struct *cp,
904 unsigned char *scsi3addr,
905 unsigned char *cdb,
906 unsigned char cdblen,
907 unsigned char *buf, int bufsize,
908 int direction)
909{
910 unsigned long flags;
Peter Zijlstra6e9a4732006-09-30 23:28:10 -0700911 DECLARE_COMPLETION_ONSTACK(wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700912
913 cp->cmd_type = CMD_IOCTL_PEND; // treat this like an ioctl
914 cp->scsi_cmd = NULL;
915 cp->Header.ReplyQueue = 0; // unused in simple mode
916 memcpy(&cp->Header.LUN, scsi3addr, sizeof(cp->Header.LUN));
917 cp->Header.Tag.lower = cp->busaddr; // Use k. address of cmd as tag
918 // Fill in the request block...
919
920 /* printk("Using scsi3addr 0x%02x%0x2%0x2%0x2%0x2%0x2%0x2%0x2\n",
921 scsi3addr[0], scsi3addr[1], scsi3addr[2], scsi3addr[3],
922 scsi3addr[4], scsi3addr[5], scsi3addr[6], scsi3addr[7]); */
923
924 memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB));
925 memcpy(cp->Request.CDB, cdb, cdblen);
926 cp->Request.Timeout = 0;
927 cp->Request.CDBLen = cdblen;
928 cp->Request.Type.Type = TYPE_CMD;
929 cp->Request.Type.Attribute = ATTR_SIMPLE;
930 cp->Request.Type.Direction = direction;
931
932 /* Fill in the SG list and do dma mapping */
933 cciss_map_one(c->pdev, cp, (unsigned char *) buf,
934 bufsize, DMA_FROM_DEVICE);
935
936 cp->waiting = &wait;
937
938 /* Put the request on the tail of the request queue */
939 spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
940 addQ(&c->reqQ, cp);
941 c->Qdepth++;
942 start_io(c);
943 spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
944
945 wait_for_completion(&wait);
946
947 /* undo the dma mapping */
948 cciss_unmap_one(c->pdev, cp, bufsize, DMA_FROM_DEVICE);
949 return(0);
950}
951
952static void
953cciss_scsi_interpret_error(CommandList_struct *cp)
954{
955 ErrorInfo_struct *ei;
956
957 ei = cp->err_info;
958 switch(ei->CommandStatus)
959 {
960 case CMD_TARGET_STATUS:
961 printk(KERN_WARNING "cciss: cmd %p has "
962 "completed with errors\n", cp);
963 printk(KERN_WARNING "cciss: cmd %p "
964 "has SCSI Status = %x\n",
965 cp,
966 ei->ScsiStatus);
967 if (ei->ScsiStatus == 0)
968 printk(KERN_WARNING
969 "cciss:SCSI status is abnormally zero. "
970 "(probably indicates selection timeout "
971 "reported incorrectly due to a known "
972 "firmware bug, circa July, 2001.)\n");
973 break;
974 case CMD_DATA_UNDERRUN: /* let mid layer handle it. */
975 printk("UNDERRUN\n");
976 break;
977 case CMD_DATA_OVERRUN:
978 printk(KERN_WARNING "cciss: cp %p has"
979 " completed with data overrun "
980 "reported\n", cp);
981 break;
982 case CMD_INVALID: {
983 /* controller unfortunately reports SCSI passthru's */
984 /* to non-existent targets as invalid commands. */
985 printk(KERN_WARNING "cciss: cp %p is "
986 "reported invalid (probably means "
987 "target device no longer present)\n",
988 cp);
989 /* print_bytes((unsigned char *) cp, sizeof(*cp), 1, 0);
990 print_cmd(cp); */
991 }
992 break;
993 case CMD_PROTOCOL_ERR:
994 printk(KERN_WARNING "cciss: cp %p has "
995 "protocol error \n", cp);
996 break;
997 case CMD_HARDWARE_ERR:
998 /* cmd->result = DID_ERROR << 16; */
999 printk(KERN_WARNING "cciss: cp %p had "
1000 " hardware error\n", cp);
1001 break;
1002 case CMD_CONNECTION_LOST:
1003 printk(KERN_WARNING "cciss: cp %p had "
1004 "connection lost\n", cp);
1005 break;
1006 case CMD_ABORTED:
1007 printk(KERN_WARNING "cciss: cp %p was "
1008 "aborted\n", cp);
1009 break;
1010 case CMD_ABORT_FAILED:
1011 printk(KERN_WARNING "cciss: cp %p reports "
1012 "abort failed\n", cp);
1013 break;
1014 case CMD_UNSOLICITED_ABORT:
1015 printk(KERN_WARNING "cciss: cp %p aborted "
1016 "do to an unsolicited abort\n", cp);
1017 break;
1018 case CMD_TIMEOUT:
1019 printk(KERN_WARNING "cciss: cp %p timedout\n",
1020 cp);
1021 break;
1022 default:
1023 printk(KERN_WARNING "cciss: cp %p returned "
1024 "unknown status %x\n", cp,
1025 ei->CommandStatus);
1026 }
1027}
1028
1029static int
1030cciss_scsi_do_inquiry(ctlr_info_t *c, unsigned char *scsi3addr,
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001031 unsigned char page, unsigned char *buf,
1032 unsigned char bufsize)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033{
1034 int rc;
1035 CommandList_struct *cp;
1036 char cdb[6];
1037 ErrorInfo_struct *ei;
1038 unsigned long flags;
1039
1040 spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
1041 cp = scsi_cmd_alloc(c);
1042 spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
1043
1044 if (cp == NULL) { /* trouble... */
1045 printk("cmd_alloc returned NULL!\n");
1046 return -1;
1047 }
1048
1049 ei = cp->err_info;
1050
1051 cdb[0] = CISS_INQUIRY;
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001052 cdb[1] = (page != 0);
1053 cdb[2] = page;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001054 cdb[3] = 0;
Mike Miller47922d02005-09-13 01:25:25 -07001055 cdb[4] = bufsize;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001056 cdb[5] = 0;
1057 rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr, cdb,
Mike Miller47922d02005-09-13 01:25:25 -07001058 6, buf, bufsize, XFER_READ);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001059
1060 if (rc != 0) return rc; /* something went wrong */
1061
1062 if (ei->CommandStatus != 0 &&
1063 ei->CommandStatus != CMD_DATA_UNDERRUN) {
1064 cciss_scsi_interpret_error(cp);
1065 rc = -1;
1066 }
1067 spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
1068 scsi_cmd_free(c, cp);
1069 spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
1070 return rc;
1071}
1072
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001073/* Get the device id from inquiry page 0x83 */
1074static int cciss_scsi_get_device_id(ctlr_info_t *c, unsigned char *scsi3addr,
1075 unsigned char *device_id, int buflen)
1076{
1077 int rc;
1078 unsigned char *buf;
1079
1080 if (buflen > 16)
1081 buflen = 16;
1082 buf = kzalloc(64, GFP_KERNEL);
1083 if (!buf)
1084 return -1;
1085 rc = cciss_scsi_do_inquiry(c, scsi3addr, 0x83, buf, 64);
1086 if (rc == 0)
1087 memcpy(device_id, &buf[8], buflen);
1088 kfree(buf);
1089 return rc != 0;
1090}
1091
Linus Torvalds1da177e2005-04-16 15:20:36 -07001092static int
1093cciss_scsi_do_report_phys_luns(ctlr_info_t *c,
1094 ReportLunData_struct *buf, int bufsize)
1095{
1096 int rc;
1097 CommandList_struct *cp;
1098 unsigned char cdb[12];
1099 unsigned char scsi3addr[8];
1100 ErrorInfo_struct *ei;
1101 unsigned long flags;
1102
1103 spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
1104 cp = scsi_cmd_alloc(c);
1105 spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
1106 if (cp == NULL) { /* trouble... */
1107 printk("cmd_alloc returned NULL!\n");
1108 return -1;
1109 }
1110
1111 memset(&scsi3addr[0], 0, 8); /* address the controller */
1112 cdb[0] = CISS_REPORT_PHYS;
1113 cdb[1] = 0;
1114 cdb[2] = 0;
1115 cdb[3] = 0;
1116 cdb[4] = 0;
1117 cdb[5] = 0;
1118 cdb[6] = (bufsize >> 24) & 0xFF; //MSB
1119 cdb[7] = (bufsize >> 16) & 0xFF;
1120 cdb[8] = (bufsize >> 8) & 0xFF;
1121 cdb[9] = bufsize & 0xFF;
1122 cdb[10] = 0;
1123 cdb[11] = 0;
1124
1125 rc = cciss_scsi_do_simple_cmd(c, cp, scsi3addr,
1126 cdb, 12,
1127 (unsigned char *) buf,
1128 bufsize, XFER_READ);
1129
1130 if (rc != 0) return rc; /* something went wrong */
1131
1132 ei = cp->err_info;
1133 if (ei->CommandStatus != 0 &&
1134 ei->CommandStatus != CMD_DATA_UNDERRUN) {
1135 cciss_scsi_interpret_error(cp);
1136 rc = -1;
1137 }
1138 spin_lock_irqsave(CCISS_LOCK(c->ctlr), flags);
1139 scsi_cmd_free(c, cp);
1140 spin_unlock_irqrestore(CCISS_LOCK(c->ctlr), flags);
1141 return rc;
1142}
1143
1144static void
1145cciss_update_non_disk_devices(int cntl_num, int hostno)
1146{
1147 /* the idea here is we could get notified from /proc
1148 that some devices have changed, so we do a report
1149 physical luns cmd, and adjust our list of devices
1150 accordingly. (We can't rely on the scsi-mid layer just
1151 doing inquiries, because the "busses" that the scsi
1152 mid-layer probes are totally fabricated by this driver,
1153 so new devices wouldn't show up.
1154
1155 the scsi3addr's of devices won't change so long as the
1156 adapter is not reset. That means we can rescan and
1157 tell which devices we already know about, vs. new
1158 devices, vs. disappearing devices.
1159
1160 Also, if you yank out a tape drive, then put in a disk
1161 in it's place, (say, a configured volume from another
1162 array controller for instance) _don't_ poke this driver
1163 (so it thinks it's still a tape, but _do_ poke the scsi
1164 mid layer, so it does an inquiry... the scsi mid layer
1165 will see the physical disk. This would be bad. Need to
1166 think about how to prevent that. One idea would be to
1167 snoop all scsi responses and if an inquiry repsonse comes
1168 back that reports a disk, chuck it an return selection
1169 timeout instead and adjust our table... Not sure i like
1170 that though.
1171
1172 */
Mike Miller47922d02005-09-13 01:25:25 -07001173#define OBDR_TAPE_INQ_SIZE 49
1174#define OBDR_TAPE_SIG "$DR-10"
Linus Torvalds1da177e2005-04-16 15:20:36 -07001175 ReportLunData_struct *ld_buff;
Mike Miller47922d02005-09-13 01:25:25 -07001176 unsigned char *inq_buff;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001177 unsigned char scsi3addr[8];
1178 ctlr_info_t *c;
1179 __u32 num_luns=0;
1180 unsigned char *ch;
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001181 struct cciss_scsi_dev_t *currentsd, *this_device;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001182 int ncurrent=0;
1183 int reportlunsize = sizeof(*ld_buff) + CISS_MAX_PHYS_LUN * 8;
1184 int i;
1185
1186 c = (ctlr_info_t *) hba[cntl_num];
Eric Sesterhenn06ff37f2006-03-08 11:21:52 +01001187 ld_buff = kzalloc(reportlunsize, GFP_KERNEL);
Mike Miller47922d02005-09-13 01:25:25 -07001188 inq_buff = kmalloc(OBDR_TAPE_INQ_SIZE, GFP_KERNEL);
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001189 currentsd = kzalloc(sizeof(*currentsd) *
1190 (CCISS_MAX_SCSI_DEVS_PER_HBA+1), GFP_KERNEL);
1191 if (ld_buff == NULL || inq_buff == NULL || currentsd == NULL) {
1192 printk(KERN_ERR "cciss: out of memory\n");
1193 goto out;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001194 }
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001195 this_device = &currentsd[CCISS_MAX_SCSI_DEVS_PER_HBA];
Linus Torvalds1da177e2005-04-16 15:20:36 -07001196 if (cciss_scsi_do_report_phys_luns(c, ld_buff, reportlunsize) == 0) {
1197 ch = &ld_buff->LUNListLength[0];
1198 num_luns = ((ch[0]<<24) | (ch[1]<<16) | (ch[2]<<8) | ch[3]) / 8;
1199 if (num_luns > CISS_MAX_PHYS_LUN) {
1200 printk(KERN_WARNING
1201 "cciss: Maximum physical LUNs (%d) exceeded. "
1202 "%d LUNs ignored.\n", CISS_MAX_PHYS_LUN,
1203 num_luns - CISS_MAX_PHYS_LUN);
1204 num_luns = CISS_MAX_PHYS_LUN;
1205 }
1206 }
1207 else {
1208 printk(KERN_ERR "cciss: Report physical LUNs failed.\n");
1209 goto out;
1210 }
1211
1212
1213 /* adjust our table of devices */
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001214 for (i = 0; i < num_luns; i++) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001215 /* for each physical lun, do an inquiry */
1216 if (ld_buff->LUN[i][3] & 0xC0) continue;
Mike Miller47922d02005-09-13 01:25:25 -07001217 memset(inq_buff, 0, OBDR_TAPE_INQ_SIZE);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001218 memcpy(&scsi3addr[0], &ld_buff->LUN[i][0], 8);
1219
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001220 if (cciss_scsi_do_inquiry(hba[cntl_num], scsi3addr, 0, inq_buff,
1221 (unsigned char) OBDR_TAPE_INQ_SIZE) != 0)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001222 /* Inquiry failed (msg printed already) */
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001223 continue; /* so we will skip this device. */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001224
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001225 this_device->devtype = (inq_buff[0] & 0x1f);
1226 this_device->bus = -1;
1227 this_device->target = -1;
1228 this_device->lun = -1;
1229 memcpy(this_device->scsi3addr, scsi3addr, 8);
1230 memcpy(this_device->vendor, &inq_buff[8],
1231 sizeof(this_device->vendor));
1232 memcpy(this_device->model, &inq_buff[16],
1233 sizeof(this_device->model));
1234 memcpy(this_device->revision, &inq_buff[32],
1235 sizeof(this_device->revision));
1236 memset(this_device->device_id, 0,
1237 sizeof(this_device->device_id));
1238 cciss_scsi_get_device_id(hba[cntl_num], scsi3addr,
1239 this_device->device_id, sizeof(this_device->device_id));
1240
1241 switch (this_device->devtype)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001242 {
Mike Miller47922d02005-09-13 01:25:25 -07001243 case 0x05: /* CD-ROM */ {
1244
1245 /* We don't *really* support actual CD-ROM devices,
1246 * just this "One Button Disaster Recovery" tape drive
1247 * which temporarily pretends to be a CD-ROM drive.
1248 * So we check that the device is really an OBDR tape
1249 * device by checking for "$DR-10" in bytes 43-48 of
1250 * the inquiry data.
1251 */
1252 char obdr_sig[7];
1253
1254 strncpy(obdr_sig, &inq_buff[43], 6);
1255 obdr_sig[6] = '\0';
1256 if (strncmp(obdr_sig, OBDR_TAPE_SIG, 6) != 0)
1257 /* Not OBDR device, ignore it. */
1258 break;
1259 }
1260 /* fall through . . . */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001261 case 0x01: /* sequential access, (tape) */
1262 case 0x08: /* medium changer */
1263 if (ncurrent >= CCISS_MAX_SCSI_DEVS_PER_HBA) {
1264 printk(KERN_INFO "cciss%d: %s ignored, "
1265 "too many devices.\n", cntl_num,
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001266 scsi_device_type(this_device->devtype));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001267 break;
1268 }
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001269 currentsd[ncurrent] = *this_device;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001270 ncurrent++;
1271 break;
1272 default:
1273 break;
1274 }
1275 }
1276
1277 adjust_cciss_scsi_table(cntl_num, hostno, currentsd, ncurrent);
1278out:
1279 kfree(inq_buff);
1280 kfree(ld_buff);
scameron@beardog.cca.cpqcorp.net905bd782008-09-19 18:27:47 -07001281 kfree(currentsd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001282 return;
1283}
1284
1285static int
1286is_keyword(char *ptr, int len, char *verb) // Thanks to ncr53c8xx.c
1287{
1288 int verb_len = strlen(verb);
1289 if (len >= verb_len && !memcmp(verb,ptr,verb_len))
1290 return verb_len;
1291 else
1292 return 0;
1293}
1294
1295static int
1296cciss_scsi_user_command(int ctlr, int hostno, char *buffer, int length)
1297{
1298 int arg_len;
1299
1300 if ((arg_len = is_keyword(buffer, length, "rescan")) != 0)
1301 cciss_update_non_disk_devices(ctlr, hostno);
1302 else
1303 return -EINVAL;
1304 return length;
1305}
1306
1307
1308static int
1309cciss_scsi_proc_info(struct Scsi_Host *sh,
1310 char *buffer, /* data buffer */
1311 char **start, /* where data in buffer starts */
1312 off_t offset, /* offset from start of imaginary file */
1313 int length, /* length of data in buffer */
1314 int func) /* 0 == read, 1 == write */
1315{
1316
1317 int buflen, datalen;
1318 ctlr_info_t *ci;
Mike Millerb9f0bd02005-09-13 01:25:26 -07001319 int i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001320 int cntl_num;
1321
1322
1323 ci = (ctlr_info_t *) sh->hostdata[0];
1324 if (ci == NULL) /* This really shouldn't ever happen. */
1325 return -EINVAL;
1326
1327 cntl_num = ci->ctlr; /* Get our index into the hba[] array */
1328
1329 if (func == 0) { /* User is reading from /proc/scsi/ciss*?/?* */
Mike Millerb9f0bd02005-09-13 01:25:26 -07001330 buflen = sprintf(buffer, "cciss%d: SCSI host: %d\n",
1331 cntl_num, sh->host_no);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001332
Mike Millerb9f0bd02005-09-13 01:25:26 -07001333 /* this information is needed by apps to know which cciss
1334 device corresponds to which scsi host number without
1335 having to open a scsi target device node. The device
1336 information is not a duplicate of /proc/scsi/scsi because
1337 the two may be out of sync due to scsi hotplug, rather
1338 this info is for an app to be able to use to know how to
1339 get them back in sync. */
1340
1341 for (i=0;i<ccissscsi[cntl_num].ndevices;i++) {
1342 struct cciss_scsi_dev_t *sd = &ccissscsi[cntl_num].dev[i];
1343 buflen += sprintf(&buffer[buflen], "c%db%dt%dl%d %02d "
1344 "0x%02x%02x%02x%02x%02x%02x%02x%02x\n",
1345 sh->host_no, sd->bus, sd->target, sd->lun,
1346 sd->devtype,
1347 sd->scsi3addr[0], sd->scsi3addr[1],
1348 sd->scsi3addr[2], sd->scsi3addr[3],
1349 sd->scsi3addr[4], sd->scsi3addr[5],
1350 sd->scsi3addr[6], sd->scsi3addr[7]);
1351 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001352 datalen = buflen - offset;
1353 if (datalen < 0) { /* they're reading past EOF. */
1354 datalen = 0;
1355 *start = buffer+buflen;
1356 } else
1357 *start = buffer + offset;
1358 return(datalen);
1359 } else /* User is writing to /proc/scsi/cciss*?/?* ... */
1360 return cciss_scsi_user_command(cntl_num, sh->host_no,
1361 buffer, length);
1362}
1363
1364/* cciss_scatter_gather takes a struct scsi_cmnd, (cmd), and does the pci
1365 dma mapping and fills in the scatter gather entries of the
1366 cciss command, cp. */
1367
1368static void
1369cciss_scatter_gather(struct pci_dev *pdev,
1370 CommandList_struct *cp,
1371 struct scsi_cmnd *cmd)
1372{
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001373 unsigned int len;
1374 struct scatterlist *sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001375 __u64 addr64;
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001376 int use_sg, i;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001377
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001378 BUG_ON(scsi_sg_count(cmd) > MAXSGENTRIES);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001379
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001380 use_sg = scsi_dma_map(cmd);
1381 if (use_sg) { /* not too many addrs? */
1382 scsi_for_each_sg(cmd, sg, use_sg, i) {
1383 addr64 = (__u64) sg_dma_address(sg);
1384 len = sg_dma_len(sg);
1385 cp->SG[i].Addr.lower =
1386 (__u32) (addr64 & (__u64) 0x00000000FFFFFFFF);
1387 cp->SG[i].Addr.upper =
1388 (__u32) ((addr64 >> 32) & (__u64) 0x00000000FFFFFFFF);
1389 cp->SG[i].Len = len;
1390 cp->SG[i].Ext = 0; // we are not chaining
Linus Torvalds1da177e2005-04-16 15:20:36 -07001391 }
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001392 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001393
FUJITA Tomonori41ce6392007-05-26 02:45:17 +09001394 cp->Header.SGList = (__u8) use_sg; /* no. SGs contig in this cmd */
1395 cp->Header.SGTotal = (__u16) use_sg; /* total sgs in this cmd list */
Linus Torvalds1da177e2005-04-16 15:20:36 -07001396 return;
1397}
1398
1399
1400static int
1401cciss_scsi_queue_command (struct scsi_cmnd *cmd, void (* done)(struct scsi_cmnd *))
1402{
1403 ctlr_info_t **c;
1404 int ctlr, rc;
1405 unsigned char scsi3addr[8];
1406 CommandList_struct *cp;
1407 unsigned long flags;
1408
1409 // Get the ptr to our adapter structure (hba[i]) out of cmd->host.
1410 // We violate cmd->host privacy here. (Is there another way?)
1411 c = (ctlr_info_t **) &cmd->device->host->hostdata[0];
1412 ctlr = (*c)->ctlr;
1413
1414 rc = lookup_scsi3addr(ctlr, cmd->device->channel, cmd->device->id,
1415 cmd->device->lun, scsi3addr);
1416 if (rc != 0) {
1417 /* the scsi nexus does not match any that we presented... */
1418 /* pretend to mid layer that we got selection timeout */
1419 cmd->result = DID_NO_CONNECT << 16;
1420 done(cmd);
1421 /* we might want to think about registering controller itself
1422 as a processor device on the bus so sg binds to it. */
1423 return 0;
1424 }
1425
1426 /* printk("cciss_queue_command, p=%p, cmd=0x%02x, c%db%dt%dl%d\n",
1427 cmd, cmd->cmnd[0], ctlr, cmd->channel, cmd->target, cmd->lun);*/
1428 // printk("q:%p:c%db%dt%dl%d ", cmd, ctlr, cmd->channel,
1429 // cmd->target, cmd->lun);
1430
1431 /* Ok, we have a reasonable scsi nexus, so send the cmd down, and
1432 see what the device thinks of it. */
1433
1434 spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
1435 cp = scsi_cmd_alloc(*c);
1436 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
1437 if (cp == NULL) { /* trouble... */
1438 printk("scsi_cmd_alloc returned NULL!\n");
1439 /* FIXME: next 3 lines are -> BAD! <- */
1440 cmd->result = DID_NO_CONNECT << 16;
1441 done(cmd);
1442 return 0;
1443 }
1444
1445 // Fill in the command list header
1446
1447 cmd->scsi_done = done; // save this for use by completion code
1448
1449 // save cp in case we have to abort it
1450 cmd->host_scribble = (unsigned char *) cp;
1451
1452 cp->cmd_type = CMD_SCSI;
1453 cp->scsi_cmd = cmd;
1454 cp->Header.ReplyQueue = 0; // unused in simple mode
1455 memcpy(&cp->Header.LUN.LunAddrBytes[0], &scsi3addr[0], 8);
1456 cp->Header.Tag.lower = cp->busaddr; // Use k. address of cmd as tag
1457
1458 // Fill in the request block...
1459
1460 cp->Request.Timeout = 0;
1461 memset(cp->Request.CDB, 0, sizeof(cp->Request.CDB));
Eric Sesterhenn089fe1b2006-03-24 18:50:27 +01001462 BUG_ON(cmd->cmd_len > sizeof(cp->Request.CDB));
Linus Torvalds1da177e2005-04-16 15:20:36 -07001463 cp->Request.CDBLen = cmd->cmd_len;
1464 memcpy(cp->Request.CDB, cmd->cmnd, cmd->cmd_len);
1465 cp->Request.Type.Type = TYPE_CMD;
1466 cp->Request.Type.Attribute = ATTR_SIMPLE;
1467 switch(cmd->sc_data_direction)
1468 {
1469 case DMA_TO_DEVICE: cp->Request.Type.Direction = XFER_WRITE; break;
1470 case DMA_FROM_DEVICE: cp->Request.Type.Direction = XFER_READ; break;
1471 case DMA_NONE: cp->Request.Type.Direction = XFER_NONE; break;
1472 case DMA_BIDIRECTIONAL:
1473 // This can happen if a buggy application does a scsi passthru
1474 // and sets both inlen and outlen to non-zero. ( see
1475 // ../scsi/scsi_ioctl.c:scsi_ioctl_send_command() )
1476
1477 cp->Request.Type.Direction = XFER_RSVD;
1478 // This is technically wrong, and cciss controllers should
1479 // reject it with CMD_INVALID, which is the most correct
1480 // response, but non-fibre backends appear to let it
1481 // slide by, and give the same results as if this field
1482 // were set correctly. Either way is acceptable for
1483 // our purposes here.
1484
1485 break;
1486
1487 default:
1488 printk("cciss: unknown data direction: %d\n",
1489 cmd->sc_data_direction);
1490 BUG();
1491 break;
1492 }
1493
1494 cciss_scatter_gather((*c)->pdev, cp, cmd); // Fill the SG list
1495
1496 /* Put the request on the tail of the request queue */
1497
1498 spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
1499 addQ(&(*c)->reqQ, cp);
1500 (*c)->Qdepth++;
1501 start_io(*c);
1502 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
1503
1504 /* the cmd'll come back via intr handler in complete_scsi_command() */
1505 return 0;
1506}
1507
1508static void
1509cciss_unregister_scsi(int ctlr)
1510{
1511 struct cciss_scsi_adapter_data_t *sa;
1512 struct cciss_scsi_cmd_stack_t *stk;
1513 unsigned long flags;
1514
1515 /* we are being forcibly unloaded, and may not refuse. */
1516
1517 spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
Stephen M. Cameronaad9fb62010-02-26 16:01:42 -06001518 sa = hba[ctlr]->scsi_ctlr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001519 stk = &sa->cmd_stack;
1520
1521 /* if we weren't ever actually registered, don't unregister */
1522 if (sa->registered) {
1523 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
1524 scsi_remove_host(sa->scsi_host);
1525 scsi_host_put(sa->scsi_host);
1526 spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
1527 }
1528
1529 /* set scsi_host to NULL so our detect routine will
1530 find us on register */
1531 sa->scsi_host = NULL;
scameron@beardog.cca.cpqcorp.net61950572008-04-17 13:19:04 +02001532 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001533 scsi_cmd_stack_free(ctlr);
1534 kfree(sa);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001535}
1536
1537static int
Linus Torvalds1da177e2005-04-16 15:20:36 -07001538cciss_engage_scsi(int ctlr)
1539{
1540 struct cciss_scsi_adapter_data_t *sa;
1541 struct cciss_scsi_cmd_stack_t *stk;
1542 unsigned long flags;
1543
1544 spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
Stephen M. Cameronaad9fb62010-02-26 16:01:42 -06001545 sa = hba[ctlr]->scsi_ctlr;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001546 stk = &sa->cmd_stack;
1547
Mike Millerf4a93bc2008-08-04 11:54:53 +02001548 if (sa->registered) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001549 printk("cciss%d: SCSI subsystem already engaged.\n", ctlr);
1550 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
Stephen M. Cameron8721c812009-11-12 12:50:06 -06001551 return -ENXIO;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001552 }
Mike Millerf4a93bc2008-08-04 11:54:53 +02001553 sa->registered = 1;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001554 spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
1555 cciss_update_non_disk_devices(ctlr, -1);
Mike Millerf4a93bc2008-08-04 11:54:53 +02001556 cciss_scsi_detect(ctlr);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001557 return 0;
1558}
1559
1560static void
Mike Miller89b6e742008-02-21 08:54:03 +01001561cciss_seq_tape_report(struct seq_file *seq, int ctlr)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562{
1563 unsigned long flags;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001564
1565 CPQ_TAPE_LOCK(ctlr, flags);
Mike Miller89b6e742008-02-21 08:54:03 +01001566 seq_printf(seq,
Mike Millerb9f0bd02005-09-13 01:25:26 -07001567 "Sequential access devices: %d\n\n",
Linus Torvalds1da177e2005-04-16 15:20:36 -07001568 ccissscsi[ctlr].ndevices);
1569 CPQ_TAPE_UNLOCK(ctlr, flags);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001570}
1571
Stephen M. Cameron88f627a2009-06-02 14:48:11 +02001572static int wait_for_device_to_become_ready(ctlr_info_t *h,
1573 unsigned char lunaddr[])
1574{
1575 int rc;
1576 int count = 0;
1577 int waittime = HZ;
1578 CommandList_struct *c;
1579
1580 c = cmd_alloc(h, 1);
1581 if (!c) {
1582 printk(KERN_WARNING "cciss%d: out of memory in "
1583 "wait_for_device_to_become_ready.\n", h->ctlr);
1584 return IO_ERROR;
1585 }
1586
1587 /* Send test unit ready until device ready, or give up. */
1588 while (count < 20) {
1589
1590 /* Wait for a bit. do this first, because if we send
1591 * the TUR right away, the reset will just abort it.
1592 */
scameron@beardog.cca.cpqcorp.net40df6ae2009-06-08 15:59:38 -05001593 schedule_timeout_uninterruptible(waittime);
Stephen M. Cameron88f627a2009-06-02 14:48:11 +02001594 count++;
1595
1596 /* Increase wait time with each try, up to a point. */
1597 if (waittime < (HZ * 30))
1598 waittime = waittime * 2;
1599
1600 /* Send the Test Unit Ready */
scameron@beardog.cca.cpqcorp.netb57695f2009-06-08 16:02:17 -05001601 rc = fill_cmd(c, TEST_UNIT_READY, h->ctlr, NULL, 0, 0,
Stephen M. Cameron88f627a2009-06-02 14:48:11 +02001602 lunaddr, TYPE_CMD);
scameron@beardog.cca.cpqcorp.net85cc61a2009-06-08 16:07:45 -05001603 if (rc == 0)
1604 rc = sendcmd_withirq_core(h, c, 0);
1605
1606 (void) process_sendcmd_error(h, c);
Stephen M. Cameron88f627a2009-06-02 14:48:11 +02001607
scameron@beardog.cca.cpqcorp.net39692512009-06-08 16:10:57 -05001608 if (rc != 0)
1609 goto retry_tur;
1610
1611 if (c->err_info->CommandStatus == CMD_SUCCESS)
Stephen M. Cameron88f627a2009-06-02 14:48:11 +02001612 break;
1613
scameron@beardog.cca.cpqcorp.net39692512009-06-08 16:10:57 -05001614 if (c->err_info->CommandStatus == CMD_TARGET_STATUS &&
1615 c->err_info->ScsiStatus == SAM_STAT_CHECK_CONDITION) {
1616 if (c->err_info->SenseInfo[2] == NO_SENSE)
1617 break;
1618 if (c->err_info->SenseInfo[2] == UNIT_ATTENTION) {
1619 unsigned char asc;
1620 asc = c->err_info->SenseInfo[12];
1621 check_for_unit_attention(h, c);
1622 if (asc == POWER_OR_RESET)
1623 break;
1624 }
1625 }
1626retry_tur:
Stephen M. Cameron88f627a2009-06-02 14:48:11 +02001627 printk(KERN_WARNING "cciss%d: Waiting %d secs "
1628 "for device to become ready.\n",
1629 h->ctlr, waittime / HZ);
1630 rc = 1; /* device not ready. */
1631 }
1632
1633 if (rc)
1634 printk("cciss%d: giving up on device.\n", h->ctlr);
1635 else
1636 printk(KERN_WARNING "cciss%d: device is ready.\n", h->ctlr);
1637
1638 cmd_free(h, c, 1);
1639 return rc;
1640}
Mike Miller89b6e742008-02-21 08:54:03 +01001641
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001642/* Need at least one of these error handlers to keep ../scsi/hosts.c from
1643 * complaining. Doing a host- or bus-reset can't do anything good here.
1644 * Despite what it might say in scsi_error.c, there may well be commands
1645 * on the controller, as the cciss driver registers twice, once as a block
1646 * device for the logical drives, and once as a scsi device, for any tape
1647 * drives. So we know there are no commands out on the tape drives, but we
1648 * don't know there are no commands on the controller, and it is likely
1649 * that there probably are, as the cciss block device is most commonly used
1650 * as a boot device (embedded controller on HP/Compaq systems.)
1651*/
1652
1653static int cciss_eh_device_reset_handler(struct scsi_cmnd *scsicmd)
1654{
1655 int rc;
1656 CommandList_struct *cmd_in_trouble;
Stephen M. Cameron88f627a2009-06-02 14:48:11 +02001657 unsigned char lunaddr[8];
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001658 ctlr_info_t **c;
1659 int ctlr;
1660
1661 /* find the controller to which the command to be aborted was sent */
1662 c = (ctlr_info_t **) &scsicmd->device->host->hostdata[0];
1663 if (c == NULL) /* paranoia */
1664 return FAILED;
1665 ctlr = (*c)->ctlr;
1666 printk(KERN_WARNING "cciss%d: resetting tape drive or medium changer.\n", ctlr);
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001667 /* find the command that's giving us trouble */
1668 cmd_in_trouble = (CommandList_struct *) scsicmd->host_scribble;
Stephen M. Cameron88f627a2009-06-02 14:48:11 +02001669 if (cmd_in_trouble == NULL) /* paranoia */
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001670 return FAILED;
Stephen M. Cameron88f627a2009-06-02 14:48:11 +02001671 memcpy(lunaddr, &cmd_in_trouble->Header.LUN.LunAddrBytes[0], 8);
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001672 /* send a reset to the SCSI LUN which the command was sent to */
scameron@beardog.cca.cpqcorp.net85cc61a2009-06-08 16:07:45 -05001673 rc = sendcmd_withirq(CCISS_RESET_MSG, ctlr, NULL, 0, 0, lunaddr,
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001674 TYPE_MSG);
Stephen M. Cameron88f627a2009-06-02 14:48:11 +02001675 if (rc == 0 && wait_for_device_to_become_ready(*c, lunaddr) == 0)
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001676 return SUCCESS;
1677 printk(KERN_WARNING "cciss%d: resetting device failed.\n", ctlr);
1678 return FAILED;
1679}
1680
1681static int cciss_eh_abort_handler(struct scsi_cmnd *scsicmd)
1682{
1683 int rc;
1684 CommandList_struct *cmd_to_abort;
scameron@beardog.cca.cpqcorp.net85cc61a2009-06-08 16:07:45 -05001685 unsigned char lunaddr[8];
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001686 ctlr_info_t **c;
1687 int ctlr;
1688
1689 /* find the controller to which the command to be aborted was sent */
1690 c = (ctlr_info_t **) &scsicmd->device->host->hostdata[0];
1691 if (c == NULL) /* paranoia */
1692 return FAILED;
1693 ctlr = (*c)->ctlr;
1694 printk(KERN_WARNING "cciss%d: aborting tardy SCSI cmd\n", ctlr);
1695
1696 /* find the command to be aborted */
1697 cmd_to_abort = (CommandList_struct *) scsicmd->host_scribble;
1698 if (cmd_to_abort == NULL) /* paranoia */
1699 return FAILED;
scameron@beardog.cca.cpqcorp.net85cc61a2009-06-08 16:07:45 -05001700 memcpy(lunaddr, &cmd_to_abort->Header.LUN.LunAddrBytes[0], 8);
1701 rc = sendcmd_withirq(CCISS_ABORT_MSG, ctlr, &cmd_to_abort->Header.Tag,
1702 0, 0, lunaddr, TYPE_MSG);
mike.miller@hp.com3da8b712005-11-04 12:30:37 -06001703 if (rc == 0)
1704 return SUCCESS;
1705 return FAILED;
1706
1707}
1708
Linus Torvalds1da177e2005-04-16 15:20:36 -07001709#else /* no CONFIG_CISS_SCSI_TAPE */
1710
1711/* If no tape support, then these become defined out of existence */
1712
1713#define cciss_scsi_setup(cntl_num)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001714
1715#endif /* CONFIG_CISS_SCSI_TAPE */