blob: ac92ac143b46783bc9df6323bcfee84680189e8f [file] [log] [blame]
Linus Torvalds1da177e2005-04-16 15:20:36 -07001/***************************************************************************
2 dpti.c - description
3 -------------------
4 begin : Thu Sep 7 2000
5 copyright : (C) 2000 by Adaptec
6
7 July 30, 2001 First version being submitted
8 for inclusion in the kernel. V2.4
9
10 See Documentation/scsi/dpti.txt for history, notes, license info
11 and credits
12 ***************************************************************************/
13
14/***************************************************************************
15 * *
16 * This program is free software; you can redistribute it and/or modify *
17 * it under the terms of the GNU General Public License as published by *
18 * the Free Software Foundation; either version 2 of the License, or *
19 * (at your option) any later version. *
20 * *
21 ***************************************************************************/
22/***************************************************************************
23 * Sat Dec 20 2003 Go Taniguchi <go@turbolinux.co.jp>
24 - Support 2.6 kernel and DMA-mapping
25 - ioctl fix for raid tools
26 - use schedule_timeout in long long loop
27 **************************************************************************/
28
29/*#define DEBUG 1 */
30/*#define UARTDELAY 1 */
31
32/* On the real kernel ADDR32 should always be zero for 2.4. GFP_HIGH allocates
33 high pages. Keep the macro around because of the broken unmerged ia64 tree */
34
35#define ADDR32 (0)
36
Linus Torvalds1da177e2005-04-16 15:20:36 -070037#include <linux/module.h>
38
39MODULE_AUTHOR("Deanna Bonds, with _lots_ of help from Mark Salyzyn");
40MODULE_DESCRIPTION("Adaptec I2O RAID Driver");
41
42////////////////////////////////////////////////////////////////
43
44#include <linux/ioctl.h> /* For SCSI-Passthrough */
45#include <asm/uaccess.h>
46
47#include <linux/stat.h>
48#include <linux/slab.h> /* for kmalloc() */
Linus Torvalds1da177e2005-04-16 15:20:36 -070049#include <linux/pci.h> /* for PCI support */
50#include <linux/proc_fs.h>
51#include <linux/blkdev.h>
52#include <linux/delay.h> /* for udelay */
53#include <linux/interrupt.h>
54#include <linux/kernel.h> /* for printk */
55#include <linux/sched.h>
56#include <linux/reboot.h>
57#include <linux/spinlock.h>
Matthias Gehre910638a2006-03-28 01:56:48 -080058#include <linux/dma-mapping.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070059
60#include <linux/timer.h>
61#include <linux/string.h>
62#include <linux/ioport.h>
Arjan van de Ven0b950672006-01-11 13:16:10 +010063#include <linux/mutex.h>
Linus Torvalds1da177e2005-04-16 15:20:36 -070064
65#include <asm/processor.h> /* for boot_cpu_data */
66#include <asm/pgtable.h>
67#include <asm/io.h> /* for virt_to_bus, etc. */
68
69#include <scsi/scsi.h>
70#include <scsi/scsi_cmnd.h>
71#include <scsi/scsi_device.h>
72#include <scsi/scsi_host.h>
73#include <scsi/scsi_tcq.h>
74
75#include "dpt/dptsig.h"
76#include "dpti.h"
77
78/*============================================================================
79 * Create a binary signature - this is read by dptsig
80 * Needed for our management apps
81 *============================================================================
82 */
83static dpt_sig_S DPTI_sig = {
84 {'d', 'P', 't', 'S', 'i', 'G'}, SIG_VERSION,
85#ifdef __i386__
86 PROC_INTEL, PROC_386 | PROC_486 | PROC_PENTIUM | PROC_SEXIUM,
87#elif defined(__ia64__)
88 PROC_INTEL, PROC_IA64,
89#elif defined(__sparc__)
90 PROC_ULTRASPARC, PROC_ULTRASPARC,
91#elif defined(__alpha__)
92 PROC_ALPHA, PROC_ALPHA,
93#else
94 (-1),(-1),
95#endif
96 FT_HBADRVR, 0, OEM_DPT, OS_LINUX, CAP_OVERLAP, DEV_ALL,
97 ADF_ALL_SC5, 0, 0, DPT_VERSION, DPT_REVISION, DPT_SUBREVISION,
98 DPT_MONTH, DPT_DAY, DPT_YEAR, "Adaptec Linux I2O RAID Driver"
99};
100
101
102
103
104/*============================================================================
105 * Globals
106 *============================================================================
107 */
108
Arjan van de Ven0b950672006-01-11 13:16:10 +0100109static DEFINE_MUTEX(adpt_configuration_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700110
111static struct i2o_sys_tbl *sys_tbl = NULL;
112static int sys_tbl_ind = 0;
113static int sys_tbl_len = 0;
114
Linus Torvalds1da177e2005-04-16 15:20:36 -0700115static adpt_hba* hba_chain = NULL;
116static int hba_count = 0;
117
Arjan van de Ven00977a52007-02-12 00:55:34 -0800118static const struct file_operations adpt_fops = {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700119 .ioctl = adpt_ioctl,
120 .open = adpt_open,
121 .release = adpt_close
122};
123
124#ifdef REBOOT_NOTIFIER
125static struct notifier_block adpt_reboot_notifier =
126{
127 adpt_reboot_event,
128 NULL,
129 0
130};
131#endif
132
133/* Structures and definitions for synchronous message posting.
134 * See adpt_i2o_post_wait() for description
135 * */
136struct adpt_i2o_post_wait_data
137{
138 int status;
139 u32 id;
140 adpt_wait_queue_head_t *wq;
141 struct adpt_i2o_post_wait_data *next;
142};
143
144static struct adpt_i2o_post_wait_data *adpt_post_wait_queue = NULL;
145static u32 adpt_post_wait_id = 0;
146static DEFINE_SPINLOCK(adpt_post_wait_lock);
147
148
149/*============================================================================
150 * Functions
151 *============================================================================
152 */
153
154static u8 adpt_read_blink_led(adpt_hba* host)
155{
Harvey Harrison172c1222008-04-28 16:50:03 -0700156 if (host->FwDebugBLEDflag_P) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700157 if( readb(host->FwDebugBLEDflag_P) == 0xbc ){
158 return readb(host->FwDebugBLEDvalue_P);
159 }
160 }
161 return 0;
162}
163
164/*============================================================================
165 * Scsi host template interface functions
166 *============================================================================
167 */
168
169static struct pci_device_id dptids[] = {
170 { PCI_DPT_VENDOR_ID, PCI_DPT_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
171 { PCI_DPT_VENDOR_ID, PCI_DPT_RAPTOR_DEVICE_ID, PCI_ANY_ID, PCI_ANY_ID,},
172 { 0, }
173};
174MODULE_DEVICE_TABLE(pci,dptids);
175
Andrew Morton24601bb2007-12-10 15:49:20 -0800176static int adpt_detect(struct scsi_host_template* sht)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700177{
178 struct pci_dev *pDev = NULL;
179 adpt_hba* pHba;
180
Andrew Morton24601bb2007-12-10 15:49:20 -0800181 adpt_init();
182
Linus Torvalds1da177e2005-04-16 15:20:36 -0700183 PINFO("Detecting Adaptec I2O RAID controllers...\n");
184
185 /* search for all Adatpec I2O RAID cards */
Alan Coxa07f3532006-09-15 15:34:32 +0100186 while ((pDev = pci_get_device( PCI_DPT_VENDOR_ID, PCI_ANY_ID, pDev))) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700187 if(pDev->device == PCI_DPT_DEVICE_ID ||
188 pDev->device == PCI_DPT_RAPTOR_DEVICE_ID){
Andrew Morton24601bb2007-12-10 15:49:20 -0800189 if(adpt_install_hba(sht, pDev) ){
Linus Torvalds1da177e2005-04-16 15:20:36 -0700190 PERROR("Could not Init an I2O RAID device\n");
191 PERROR("Will not try to detect others.\n");
192 return hba_count-1;
193 }
Alan Coxa07f3532006-09-15 15:34:32 +0100194 pci_dev_get(pDev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700195 }
196 }
197
198 /* In INIT state, Activate IOPs */
199 for (pHba = hba_chain; pHba; pHba = pHba->next) {
200 // Activate does get status , init outbound, and get hrt
201 if (adpt_i2o_activate_hba(pHba) < 0) {
202 adpt_i2o_delete_hba(pHba);
203 }
204 }
205
206
207 /* Active IOPs in HOLD state */
208
209rebuild_sys_tab:
210 if (hba_chain == NULL)
211 return 0;
212
213 /*
214 * If build_sys_table fails, we kill everything and bail
215 * as we can't init the IOPs w/o a system table
216 */
217 if (adpt_i2o_build_sys_table() < 0) {
218 adpt_i2o_sys_shutdown();
219 return 0;
220 }
221
222 PDEBUG("HBA's in HOLD state\n");
223
224 /* If IOP don't get online, we need to rebuild the System table */
225 for (pHba = hba_chain; pHba; pHba = pHba->next) {
226 if (adpt_i2o_online_hba(pHba) < 0) {
227 adpt_i2o_delete_hba(pHba);
228 goto rebuild_sys_tab;
229 }
230 }
231
232 /* Active IOPs now in OPERATIONAL state */
233 PDEBUG("HBA's in OPERATIONAL state\n");
234
235 printk("dpti: If you have a lot of devices this could take a few minutes.\n");
236 for (pHba = hba_chain; pHba; pHba = pHba->next) {
237 printk(KERN_INFO"%s: Reading the hardware resource table.\n", pHba->name);
238 if (adpt_i2o_lct_get(pHba) < 0){
239 adpt_i2o_delete_hba(pHba);
240 continue;
241 }
242
243 if (adpt_i2o_parse_lct(pHba) < 0){
244 adpt_i2o_delete_hba(pHba);
245 continue;
246 }
247 adpt_inquiry(pHba);
248 }
249
250 for (pHba = hba_chain; pHba; pHba = pHba->next) {
Andrew Morton24601bb2007-12-10 15:49:20 -0800251 if( adpt_scsi_register(pHba,sht) < 0){
Linus Torvalds1da177e2005-04-16 15:20:36 -0700252 adpt_i2o_delete_hba(pHba);
253 continue;
254 }
255 pHba->initialized = TRUE;
256 pHba->state &= ~DPTI_STATE_RESET;
257 }
258
259 // Register our control device node
260 // nodes will need to be created in /dev to access this
261 // the nodes can not be created from within the driver
262 if (hba_count && register_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER, &adpt_fops)) {
Andrew Morton24601bb2007-12-10 15:49:20 -0800263 adpt_i2o_sys_shutdown();
Linus Torvalds1da177e2005-04-16 15:20:36 -0700264 return 0;
265 }
266 return hba_count;
267}
268
269
Andrew Morton24601bb2007-12-10 15:49:20 -0800270/*
271 * scsi_unregister will be called AFTER we return.
272 */
273static int adpt_release(struct Scsi_Host *host)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700274{
Andrew Morton24601bb2007-12-10 15:49:20 -0800275 adpt_hba* pHba = (adpt_hba*) host->hostdata[0];
Linus Torvalds1da177e2005-04-16 15:20:36 -0700276// adpt_i2o_quiesce_hba(pHba);
277 adpt_i2o_delete_hba(pHba);
Andrew Morton24601bb2007-12-10 15:49:20 -0800278 scsi_unregister(host);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700279 return 0;
280}
281
282
283static void adpt_inquiry(adpt_hba* pHba)
284{
285 u32 msg[14];
286 u32 *mptr;
287 u32 *lenptr;
288 int direction;
289 int scsidir;
290 u32 len;
291 u32 reqlen;
292 u8* buf;
293 u8 scb[16];
294 s32 rcode;
295
296 memset(msg, 0, sizeof(msg));
Robert P. J. Day5cbded52006-12-13 00:35:56 -0800297 buf = kmalloc(80,GFP_KERNEL|ADDR32);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700298 if(!buf){
299 printk(KERN_ERR"%s: Could not allocate buffer\n",pHba->name);
300 return;
301 }
302 memset((void*)buf, 0, 36);
303
304 len = 36;
305 direction = 0x00000000;
306 scsidir =0x40000000; // DATA IN (iop<--dev)
307
308 reqlen = 14; // SINGLE SGE
309 /* Stick the headers on */
310 msg[0] = reqlen<<16 | SGL_OFFSET_12;
311 msg[1] = (0xff<<24|HOST_TID<<12|ADAPTER_TID);
312 msg[2] = 0;
313 msg[3] = 0;
314 // Adaptec/DPT Private stuff
315 msg[4] = I2O_CMD_SCSI_EXEC|DPT_ORGANIZATION_ID<<16;
316 msg[5] = ADAPTER_TID | 1<<16 /* Interpret*/;
317 /* Direction, disconnect ok | sense data | simple queue , CDBLen */
318 // I2O_SCB_FLAG_ENABLE_DISCONNECT |
319 // I2O_SCB_FLAG_SIMPLE_QUEUE_TAG |
320 // I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE;
321 msg[6] = scsidir|0x20a00000| 6 /* cmd len*/;
322
323 mptr=msg+7;
324
325 memset(scb, 0, sizeof(scb));
326 // Write SCSI command into the message - always 16 byte block
327 scb[0] = INQUIRY;
328 scb[1] = 0;
329 scb[2] = 0;
330 scb[3] = 0;
331 scb[4] = 36;
332 scb[5] = 0;
333 // Don't care about the rest of scb
334
335 memcpy(mptr, scb, sizeof(scb));
336 mptr+=4;
337 lenptr=mptr++; /* Remember me - fill in when we know */
338
339 /* Now fill in the SGList and command */
340 *lenptr = len;
341 *mptr++ = 0xD0000000|direction|len;
342 *mptr++ = virt_to_bus(buf);
343
344 // Send it on it's way
345 rcode = adpt_i2o_post_wait(pHba, msg, reqlen<<2, 120);
346 if (rcode != 0) {
347 sprintf(pHba->detail, "Adaptec I2O RAID");
348 printk(KERN_INFO "%s: Inquiry Error (%d)\n",pHba->name,rcode);
349 if (rcode != -ETIME && rcode != -EINTR)
350 kfree(buf);
351 } else {
352 memset(pHba->detail, 0, sizeof(pHba->detail));
353 memcpy(&(pHba->detail), "Vendor: Adaptec ", 16);
354 memcpy(&(pHba->detail[16]), " Model: ", 8);
355 memcpy(&(pHba->detail[24]), (u8*) &buf[16], 16);
356 memcpy(&(pHba->detail[40]), " FW: ", 4);
357 memcpy(&(pHba->detail[44]), (u8*) &buf[32], 4);
358 pHba->detail[48] = '\0'; /* precautionary */
359 kfree(buf);
360 }
361 adpt_i2o_status_get(pHba);
362 return ;
363}
364
365
366static int adpt_slave_configure(struct scsi_device * device)
367{
368 struct Scsi_Host *host = device->host;
369 adpt_hba* pHba;
370
371 pHba = (adpt_hba *) host->hostdata[0];
372
373 if (host->can_queue && device->tagged_supported) {
374 scsi_adjust_queue_depth(device, MSG_SIMPLE_TAG,
375 host->can_queue - 1);
376 } else {
377 scsi_adjust_queue_depth(device, 0, 1);
378 }
379 return 0;
380}
381
382static int adpt_queue(struct scsi_cmnd * cmd, void (*done) (struct scsi_cmnd *))
383{
384 adpt_hba* pHba = NULL;
385 struct adpt_device* pDev = NULL; /* dpt per device information */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700386
387 cmd->scsi_done = done;
388 /*
389 * SCSI REQUEST_SENSE commands will be executed automatically by the
390 * Host Adapter for any errors, so they should not be executed
391 * explicitly unless the Sense Data is zero indicating that no error
392 * occurred.
393 */
394
395 if ((cmd->cmnd[0] == REQUEST_SENSE) && (cmd->sense_buffer[0] != 0)) {
396 cmd->result = (DID_OK << 16);
397 cmd->scsi_done(cmd);
398 return 0;
399 }
400
401 pHba = (adpt_hba*)cmd->device->host->hostdata[0];
402 if (!pHba) {
403 return FAILED;
404 }
405
406 rmb();
407 /*
408 * TODO: I need to block here if I am processing ioctl cmds
409 * but if the outstanding cmds all finish before the ioctl,
410 * the scsi-core will not know to start sending cmds to me again.
411 * I need to a way to restart the scsi-cores queues or should I block
412 * calling scsi_done on the outstanding cmds instead
413 * for now we don't set the IOCTL state
414 */
415 if(((pHba->state) & DPTI_STATE_IOCTL) || ((pHba->state) & DPTI_STATE_RESET)) {
416 pHba->host->last_reset = jiffies;
417 pHba->host->resetting = 1;
418 return 1;
419 }
420
Linus Torvalds1da177e2005-04-16 15:20:36 -0700421 // TODO if the cmd->device if offline then I may need to issue a bus rescan
422 // followed by a get_lct to see if the device is there anymore
423 if((pDev = (struct adpt_device*) (cmd->device->hostdata)) == NULL) {
424 /*
425 * First command request for this device. Set up a pointer
426 * to the device structure. This should be a TEST_UNIT_READY
427 * command from scan_scsis_single.
428 */
429 if ((pDev = adpt_find_device(pHba, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun)) == NULL) {
430 // TODO: if any luns are at this bus, scsi id then fake a TEST_UNIT_READY and INQUIRY response
431 // with type 7F (for all luns less than the max for this bus,id) so the lun scan will continue.
432 cmd->result = (DID_NO_CONNECT << 16);
433 cmd->scsi_done(cmd);
434 return 0;
435 }
436 cmd->device->hostdata = pDev;
437 }
438 pDev->pScsi_dev = cmd->device;
439
440 /*
441 * If we are being called from when the device is being reset,
442 * delay processing of the command until later.
443 */
444 if (pDev->state & DPTI_DEV_RESET ) {
445 return FAILED;
446 }
447 return adpt_scsi_to_i2o(pHba, cmd, pDev);
448}
449
450static int adpt_bios_param(struct scsi_device *sdev, struct block_device *dev,
451 sector_t capacity, int geom[])
452{
453 int heads=-1;
454 int sectors=-1;
455 int cylinders=-1;
456
457 // *** First lets set the default geometry ****
458
459 // If the capacity is less than ox2000
460 if (capacity < 0x2000 ) { // floppy
461 heads = 18;
462 sectors = 2;
463 }
464 // else if between 0x2000 and 0x20000
465 else if (capacity < 0x20000) {
466 heads = 64;
467 sectors = 32;
468 }
469 // else if between 0x20000 and 0x40000
470 else if (capacity < 0x40000) {
471 heads = 65;
472 sectors = 63;
473 }
474 // else if between 0x4000 and 0x80000
475 else if (capacity < 0x80000) {
476 heads = 128;
477 sectors = 63;
478 }
479 // else if greater than 0x80000
480 else {
481 heads = 255;
482 sectors = 63;
483 }
484 cylinders = sector_div(capacity, heads * sectors);
485
486 // Special case if CDROM
487 if(sdev->type == 5) { // CDROM
488 heads = 252;
489 sectors = 63;
490 cylinders = 1111;
491 }
492
493 geom[0] = heads;
494 geom[1] = sectors;
495 geom[2] = cylinders;
496
497 PDEBUG("adpt_bios_param: exit\n");
498 return 0;
499}
500
501
502static const char *adpt_info(struct Scsi_Host *host)
503{
504 adpt_hba* pHba;
505
506 pHba = (adpt_hba *) host->hostdata[0];
507 return (char *) (pHba->detail);
508}
509
510static int adpt_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
511 int length, int inout)
512{
513 struct adpt_device* d;
514 int id;
515 int chan;
516 int len = 0;
517 int begin = 0;
518 int pos = 0;
519 adpt_hba* pHba;
520 int unit;
521
522 *start = buffer;
523 if (inout == TRUE) {
524 /*
525 * The user has done a write and wants us to take the
526 * data in the buffer and do something with it.
527 * proc_scsiwrite calls us with inout = 1
528 *
529 * Read data from buffer (writing to us) - NOT SUPPORTED
530 */
531 return -EINVAL;
532 }
533
534 /*
535 * inout = 0 means the user has done a read and wants information
536 * returned, so we write information about the cards into the buffer
537 * proc_scsiread() calls us with inout = 0
538 */
539
540 // Find HBA (host bus adapter) we are looking for
Arjan van de Ven0b950672006-01-11 13:16:10 +0100541 mutex_lock(&adpt_configuration_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700542 for (pHba = hba_chain; pHba; pHba = pHba->next) {
543 if (pHba->host == host) {
544 break; /* found adapter */
545 }
546 }
Arjan van de Ven0b950672006-01-11 13:16:10 +0100547 mutex_unlock(&adpt_configuration_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700548 if (pHba == NULL) {
549 return 0;
550 }
551 host = pHba->host;
552
553 len = sprintf(buffer , "Adaptec I2O RAID Driver Version: %s\n\n", DPT_I2O_VERSION);
554 len += sprintf(buffer+len, "%s\n", pHba->detail);
555 len += sprintf(buffer+len, "SCSI Host=scsi%d Control Node=/dev/%s irq=%d\n",
556 pHba->host->host_no, pHba->name, host->irq);
557 len += sprintf(buffer+len, "\tpost fifo size = %d\n\treply fifo size = %d\n\tsg table size = %d\n\n",
558 host->can_queue, (int) pHba->reply_fifo_size , host->sg_tablesize);
559
560 pos = begin + len;
561
562 /* CHECKPOINT */
563 if(pos > offset + length) {
564 goto stop_output;
565 }
566 if(pos <= offset) {
567 /*
568 * If we haven't even written to where we last left
569 * off (the last time we were called), reset the
570 * beginning pointer.
571 */
572 len = 0;
573 begin = pos;
574 }
575 len += sprintf(buffer+len, "Devices:\n");
576 for(chan = 0; chan < MAX_CHANNEL; chan++) {
577 for(id = 0; id < MAX_ID; id++) {
578 d = pHba->channel[chan].device[id];
579 while(d){
580 len += sprintf(buffer+len,"\t%-24.24s", d->pScsi_dev->vendor);
581 len += sprintf(buffer+len," Rev: %-8.8s\n", d->pScsi_dev->rev);
582 pos = begin + len;
583
584
585 /* CHECKPOINT */
586 if(pos > offset + length) {
587 goto stop_output;
588 }
589 if(pos <= offset) {
590 len = 0;
591 begin = pos;
592 }
593
594 unit = d->pI2o_dev->lct_data.tid;
595 len += sprintf(buffer+len, "\tTID=%d, (Channel=%d, Target=%d, Lun=%d) (%s)\n\n",
596 unit, (int)d->scsi_channel, (int)d->scsi_id, (int)d->scsi_lun,
597 scsi_device_online(d->pScsi_dev)? "online":"offline");
598 pos = begin + len;
599
600 /* CHECKPOINT */
601 if(pos > offset + length) {
602 goto stop_output;
603 }
604 if(pos <= offset) {
605 len = 0;
606 begin = pos;
607 }
608
609 d = d->next_lun;
610 }
611 }
612 }
613
614 /*
615 * begin is where we last checked our position with regards to offset
616 * begin is always less than offset. len is relative to begin. It
617 * is the number of bytes written past begin
618 *
619 */
620stop_output:
621 /* stop the output and calculate the correct length */
622 *(buffer + len) = '\0';
623
624 *start = buffer + (offset - begin); /* Start of wanted data */
625 len -= (offset - begin);
626 if(len > length) {
627 len = length;
628 } else if(len < 0){
629 len = 0;
630 **start = '\0';
631 }
632 return len;
633}
634
635
636/*===========================================================================
637 * Error Handling routines
638 *===========================================================================
639 */
640
641static int adpt_abort(struct scsi_cmnd * cmd)
642{
643 adpt_hba* pHba = NULL; /* host bus adapter structure */
644 struct adpt_device* dptdevice; /* dpt per device information */
645 u32 msg[5];
646 int rcode;
647
648 if(cmd->serial_number == 0){
649 return FAILED;
650 }
651 pHba = (adpt_hba*) cmd->device->host->hostdata[0];
652 printk(KERN_INFO"%s: Trying to Abort cmd=%ld\n",pHba->name, cmd->serial_number);
653 if ((dptdevice = (void*) (cmd->device->hostdata)) == NULL) {
654 printk(KERN_ERR "%s: Unable to abort: No device in cmnd\n",pHba->name);
655 return FAILED;
656 }
657
658 memset(msg, 0, sizeof(msg));
659 msg[0] = FIVE_WORD_MSG_SIZE|SGL_OFFSET_0;
660 msg[1] = I2O_CMD_SCSI_ABORT<<24|HOST_TID<<12|dptdevice->tid;
661 msg[2] = 0;
662 msg[3]= 0;
663 msg[4] = (u32)cmd;
Salyzyn, Marke5508c12005-12-17 19:26:30 -0800664 if (pHba->host)
665 spin_lock_irq(pHba->host->host_lock);
666 rcode = adpt_i2o_post_wait(pHba, msg, sizeof(msg), FOREVER);
667 if (pHba->host)
668 spin_unlock_irq(pHba->host->host_lock);
669 if (rcode != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700670 if(rcode == -EOPNOTSUPP ){
671 printk(KERN_INFO"%s: Abort cmd not supported\n",pHba->name);
672 return FAILED;
673 }
674 printk(KERN_INFO"%s: Abort cmd=%ld failed.\n",pHba->name, cmd->serial_number);
675 return FAILED;
676 }
677 printk(KERN_INFO"%s: Abort cmd=%ld complete.\n",pHba->name, cmd->serial_number);
678 return SUCCESS;
679}
680
681
682#define I2O_DEVICE_RESET 0x27
683// This is the same for BLK and SCSI devices
684// NOTE this is wrong in the i2o.h definitions
685// This is not currently supported by our adapter but we issue it anyway
686static int adpt_device_reset(struct scsi_cmnd* cmd)
687{
688 adpt_hba* pHba;
689 u32 msg[4];
690 u32 rcode;
691 int old_state;
Benoit Boissinot 1c2fb3f2005-04-25 19:46:48 -0700692 struct adpt_device* d = cmd->device->hostdata;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700693
694 pHba = (void*) cmd->device->host->hostdata[0];
695 printk(KERN_INFO"%s: Trying to reset device\n",pHba->name);
696 if (!d) {
697 printk(KERN_INFO"%s: Reset Device: Device Not found\n",pHba->name);
698 return FAILED;
699 }
700 memset(msg, 0, sizeof(msg));
701 msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
702 msg[1] = (I2O_DEVICE_RESET<<24|HOST_TID<<12|d->tid);
703 msg[2] = 0;
704 msg[3] = 0;
705
Salyzyn, Marke5508c12005-12-17 19:26:30 -0800706 if (pHba->host)
707 spin_lock_irq(pHba->host->host_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700708 old_state = d->state;
709 d->state |= DPTI_DEV_RESET;
Salyzyn, Marke5508c12005-12-17 19:26:30 -0800710 rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER);
711 d->state = old_state;
712 if (pHba->host)
713 spin_unlock_irq(pHba->host->host_lock);
714 if (rcode != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700715 if(rcode == -EOPNOTSUPP ){
716 printk(KERN_INFO"%s: Device reset not supported\n",pHba->name);
717 return FAILED;
718 }
719 printk(KERN_INFO"%s: Device reset failed\n",pHba->name);
720 return FAILED;
721 } else {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700722 printk(KERN_INFO"%s: Device reset successful\n",pHba->name);
723 return SUCCESS;
724 }
725}
726
727
728#define I2O_HBA_BUS_RESET 0x87
729// This version of bus reset is called by the eh_error handler
730static int adpt_bus_reset(struct scsi_cmnd* cmd)
731{
732 adpt_hba* pHba;
733 u32 msg[4];
Salyzyn, Marke5508c12005-12-17 19:26:30 -0800734 u32 rcode;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700735
736 pHba = (adpt_hba*)cmd->device->host->hostdata[0];
737 memset(msg, 0, sizeof(msg));
738 printk(KERN_WARNING"%s: Bus reset: SCSI Bus %d: tid: %d\n",pHba->name, cmd->device->channel,pHba->channel[cmd->device->channel].tid );
739 msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
740 msg[1] = (I2O_HBA_BUS_RESET<<24|HOST_TID<<12|pHba->channel[cmd->device->channel].tid);
741 msg[2] = 0;
742 msg[3] = 0;
Salyzyn, Marke5508c12005-12-17 19:26:30 -0800743 if (pHba->host)
744 spin_lock_irq(pHba->host->host_lock);
745 rcode = adpt_i2o_post_wait(pHba, msg,sizeof(msg), FOREVER);
746 if (pHba->host)
747 spin_unlock_irq(pHba->host->host_lock);
748 if (rcode != 0) {
Linus Torvalds1da177e2005-04-16 15:20:36 -0700749 printk(KERN_WARNING"%s: Bus reset failed.\n",pHba->name);
750 return FAILED;
751 } else {
752 printk(KERN_WARNING"%s: Bus reset success.\n",pHba->name);
753 return SUCCESS;
754 }
755}
756
757// This version of reset is called by the eh_error_handler
Jeff Garzik df0ae242005-05-28 07:57:14 -0400758static int __adpt_reset(struct scsi_cmnd* cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700759{
760 adpt_hba* pHba;
761 int rcode;
762 pHba = (adpt_hba*)cmd->device->host->hostdata[0];
763 printk(KERN_WARNING"%s: Hba Reset: scsi id %d: tid: %d\n",pHba->name,cmd->device->channel,pHba->channel[cmd->device->channel].tid );
764 rcode = adpt_hba_reset(pHba);
765 if(rcode == 0){
766 printk(KERN_WARNING"%s: HBA reset complete\n",pHba->name);
767 return SUCCESS;
768 } else {
769 printk(KERN_WARNING"%s: HBA reset failed (%x)\n",pHba->name, rcode);
770 return FAILED;
771 }
772}
773
Jeff Garzik df0ae242005-05-28 07:57:14 -0400774static int adpt_reset(struct scsi_cmnd* cmd)
775{
776 int rc;
777
778 spin_lock_irq(cmd->device->host->host_lock);
779 rc = __adpt_reset(cmd);
780 spin_unlock_irq(cmd->device->host->host_lock);
781
782 return rc;
783}
784
Linus Torvalds1da177e2005-04-16 15:20:36 -0700785// This version of reset is called by the ioctls and indirectly from eh_error_handler via adpt_reset
786static int adpt_hba_reset(adpt_hba* pHba)
787{
788 int rcode;
789
790 pHba->state |= DPTI_STATE_RESET;
791
792 // Activate does get status , init outbound, and get hrt
793 if ((rcode=adpt_i2o_activate_hba(pHba)) < 0) {
794 printk(KERN_ERR "%s: Could not activate\n", pHba->name);
795 adpt_i2o_delete_hba(pHba);
796 return rcode;
797 }
798
799 if ((rcode=adpt_i2o_build_sys_table()) < 0) {
800 adpt_i2o_delete_hba(pHba);
801 return rcode;
802 }
803 PDEBUG("%s: in HOLD state\n",pHba->name);
804
805 if ((rcode=adpt_i2o_online_hba(pHba)) < 0) {
806 adpt_i2o_delete_hba(pHba);
807 return rcode;
808 }
809 PDEBUG("%s: in OPERATIONAL state\n",pHba->name);
810
811 if ((rcode=adpt_i2o_lct_get(pHba)) < 0){
812 adpt_i2o_delete_hba(pHba);
813 return rcode;
814 }
815
816 if ((rcode=adpt_i2o_reparse_lct(pHba)) < 0){
817 adpt_i2o_delete_hba(pHba);
818 return rcode;
819 }
820 pHba->state &= ~DPTI_STATE_RESET;
821
822 adpt_fail_posted_scbs(pHba);
823 return 0; /* return success */
824}
825
826/*===========================================================================
827 *
828 *===========================================================================
829 */
830
831
832static void adpt_i2o_sys_shutdown(void)
833{
834 adpt_hba *pHba, *pNext;
Adrian Bunk458af542005-11-27 00:36:37 +0100835 struct adpt_i2o_post_wait_data *p1, *old;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700836
837 printk(KERN_INFO"Shutting down Adaptec I2O controllers.\n");
838 printk(KERN_INFO" This could take a few minutes if there are many devices attached\n");
839 /* Delete all IOPs from the controller chain */
840 /* They should have already been released by the
841 * scsi-core
842 */
843 for (pHba = hba_chain; pHba; pHba = pNext) {
844 pNext = pHba->next;
845 adpt_i2o_delete_hba(pHba);
846 }
847
848 /* Remove any timedout entries from the wait queue. */
Linus Torvalds1da177e2005-04-16 15:20:36 -0700849// spin_lock_irqsave(&adpt_post_wait_lock, flags);
850 /* Nothing should be outstanding at this point so just
851 * free them
852 */
Adrian Bunk458af542005-11-27 00:36:37 +0100853 for(p1 = adpt_post_wait_queue; p1;) {
854 old = p1;
855 p1 = p1->next;
856 kfree(old);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700857 }
858// spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
859 adpt_post_wait_queue = NULL;
860
861 printk(KERN_INFO "Adaptec I2O controllers down.\n");
862}
863
864/*
865 * reboot/shutdown notification.
866 *
867 * - Quiesce each IOP in the system
868 *
869 */
870
871#ifdef REBOOT_NOTIFIER
872static int adpt_reboot_event(struct notifier_block *n, ulong code, void *p)
873{
874
875 if(code != SYS_RESTART && code != SYS_HALT && code != SYS_POWER_OFF)
876 return NOTIFY_DONE;
877
878 adpt_i2o_sys_shutdown();
879
880 return NOTIFY_DONE;
881}
882#endif
883
884
Andrew Morton24601bb2007-12-10 15:49:20 -0800885static int adpt_install_hba(struct scsi_host_template* sht, struct pci_dev* pDev)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700886{
887
888 adpt_hba* pHba = NULL;
889 adpt_hba* p = NULL;
890 ulong base_addr0_phys = 0;
891 ulong base_addr1_phys = 0;
892 u32 hba_map0_area_size = 0;
893 u32 hba_map1_area_size = 0;
894 void __iomem *base_addr_virt = NULL;
895 void __iomem *msg_addr_virt = NULL;
896
897 int raptorFlag = FALSE;
Linus Torvalds1da177e2005-04-16 15:20:36 -0700898
899 if(pci_enable_device(pDev)) {
900 return -EINVAL;
901 }
Salyzyn, Mark9638d892006-01-12 08:31:57 -0500902
903 if (pci_request_regions(pDev, "dpt_i2o")) {
904 PERROR("dpti: adpt_config_hba: pci request region failed\n");
905 return -EINVAL;
906 }
907
Linus Torvalds1da177e2005-04-16 15:20:36 -0700908 pci_set_master(pDev);
James Bottomleyc80ddf02007-12-12 15:06:21 -0500909 if (pci_set_dma_mask(pDev, DMA_32BIT_MASK))
Linus Torvalds1da177e2005-04-16 15:20:36 -0700910 return -EINVAL;
911
912 base_addr0_phys = pci_resource_start(pDev,0);
913 hba_map0_area_size = pci_resource_len(pDev,0);
914
915 // Check if standard PCI card or single BAR Raptor
916 if(pDev->device == PCI_DPT_DEVICE_ID){
917 if(pDev->subsystem_device >=0xc032 && pDev->subsystem_device <= 0xc03b){
918 // Raptor card with this device id needs 4M
919 hba_map0_area_size = 0x400000;
920 } else { // Not Raptor - it is a PCI card
921 if(hba_map0_area_size > 0x100000 ){
922 hba_map0_area_size = 0x100000;
923 }
924 }
925 } else {// Raptor split BAR config
926 // Use BAR1 in this configuration
927 base_addr1_phys = pci_resource_start(pDev,1);
928 hba_map1_area_size = pci_resource_len(pDev,1);
929 raptorFlag = TRUE;
930 }
931
Linus Torvalds1da177e2005-04-16 15:20:36 -0700932 base_addr_virt = ioremap(base_addr0_phys,hba_map0_area_size);
933 if (!base_addr_virt) {
James Bottomley9c472dd2005-08-08 11:51:38 -0500934 pci_release_regions(pDev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700935 PERROR("dpti: adpt_config_hba: io remap failed\n");
936 return -EINVAL;
937 }
938
939 if(raptorFlag == TRUE) {
940 msg_addr_virt = ioremap(base_addr1_phys, hba_map1_area_size );
941 if (!msg_addr_virt) {
942 PERROR("dpti: adpt_config_hba: io remap failed on BAR1\n");
943 iounmap(base_addr_virt);
James Bottomley9c472dd2005-08-08 11:51:38 -0500944 pci_release_regions(pDev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700945 return -EINVAL;
946 }
947 } else {
948 msg_addr_virt = base_addr_virt;
949 }
950
951 // Allocate and zero the data structure
Mariusz Kozlowskibbfbbbc2007-08-11 10:13:24 +0200952 pHba = kzalloc(sizeof(adpt_hba), GFP_KERNEL);
953 if (!pHba) {
954 if (msg_addr_virt != base_addr_virt)
Linus Torvalds1da177e2005-04-16 15:20:36 -0700955 iounmap(msg_addr_virt);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700956 iounmap(base_addr_virt);
James Bottomley9c472dd2005-08-08 11:51:38 -0500957 pci_release_regions(pDev);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700958 return -ENOMEM;
959 }
Linus Torvalds1da177e2005-04-16 15:20:36 -0700960
Arjan van de Ven0b950672006-01-11 13:16:10 +0100961 mutex_lock(&adpt_configuration_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700962
963 if(hba_chain != NULL){
964 for(p = hba_chain; p->next; p = p->next);
965 p->next = pHba;
966 } else {
967 hba_chain = pHba;
968 }
969 pHba->next = NULL;
970 pHba->unit = hba_count;
Benoit Boissinot 23a2bc22005-04-25 19:46:30 -0700971 sprintf(pHba->name, "dpti%d", hba_count);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700972 hba_count++;
973
Arjan van de Ven0b950672006-01-11 13:16:10 +0100974 mutex_unlock(&adpt_configuration_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -0700975
976 pHba->pDev = pDev;
977 pHba->base_addr_phys = base_addr0_phys;
978
979 // Set up the Virtual Base Address of the I2O Device
980 pHba->base_addr_virt = base_addr_virt;
981 pHba->msg_addr_virt = msg_addr_virt;
982 pHba->irq_mask = base_addr_virt+0x30;
983 pHba->post_port = base_addr_virt+0x40;
984 pHba->reply_port = base_addr_virt+0x44;
985
986 pHba->hrt = NULL;
987 pHba->lct = NULL;
988 pHba->lct_size = 0;
989 pHba->status_block = NULL;
990 pHba->post_count = 0;
991 pHba->state = DPTI_STATE_RESET;
992 pHba->pDev = pDev;
993 pHba->devices = NULL;
994
995 // Initializing the spinlocks
996 spin_lock_init(&pHba->state_lock);
997 spin_lock_init(&adpt_post_wait_lock);
998
999 if(raptorFlag == 0){
1000 printk(KERN_INFO"Adaptec I2O RAID controller %d at %p size=%x irq=%d\n",
1001 hba_count-1, base_addr_virt, hba_map0_area_size, pDev->irq);
1002 } else {
1003 printk(KERN_INFO"Adaptec I2O RAID controller %d irq=%d\n",hba_count-1, pDev->irq);
1004 printk(KERN_INFO" BAR0 %p - size= %x\n",base_addr_virt,hba_map0_area_size);
1005 printk(KERN_INFO" BAR1 %p - size= %x\n",msg_addr_virt,hba_map1_area_size);
1006 }
1007
Thomas Gleixner1d6f3592006-07-01 19:29:42 -07001008 if (request_irq (pDev->irq, adpt_isr, IRQF_SHARED, pHba->name, pHba)) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07001009 printk(KERN_ERR"%s: Couldn't register IRQ %d\n", pHba->name, pDev->irq);
1010 adpt_i2o_delete_hba(pHba);
1011 return -EINVAL;
1012 }
1013
1014 return 0;
1015}
1016
1017
1018static void adpt_i2o_delete_hba(adpt_hba* pHba)
1019{
1020 adpt_hba* p1;
1021 adpt_hba* p2;
1022 struct i2o_device* d;
1023 struct i2o_device* next;
1024 int i;
1025 int j;
1026 struct adpt_device* pDev;
1027 struct adpt_device* pNext;
1028
1029
Arjan van de Ven0b950672006-01-11 13:16:10 +01001030 mutex_lock(&adpt_configuration_lock);
Andrew Morton24601bb2007-12-10 15:49:20 -08001031 // scsi_unregister calls our adpt_release which
1032 // does a quiese
Linus Torvalds1da177e2005-04-16 15:20:36 -07001033 if(pHba->host){
1034 free_irq(pHba->host->irq, pHba);
1035 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001036 p2 = NULL;
1037 for( p1 = hba_chain; p1; p2 = p1,p1=p1->next){
1038 if(p1 == pHba) {
1039 if(p2) {
1040 p2->next = p1->next;
1041 } else {
1042 hba_chain = p1->next;
1043 }
1044 break;
1045 }
1046 }
1047
1048 hba_count--;
Arjan van de Ven0b950672006-01-11 13:16:10 +01001049 mutex_unlock(&adpt_configuration_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001050
1051 iounmap(pHba->base_addr_virt);
James Bottomley9c472dd2005-08-08 11:51:38 -05001052 pci_release_regions(pHba->pDev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001053 if(pHba->msg_addr_virt != pHba->base_addr_virt){
1054 iounmap(pHba->msg_addr_virt);
1055 }
Jesper Juhlc9475cb2005-11-07 01:01:26 -08001056 kfree(pHba->hrt);
1057 kfree(pHba->lct);
1058 kfree(pHba->status_block);
1059 kfree(pHba->reply_pool);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001060
1061 for(d = pHba->devices; d ; d = next){
1062 next = d->next;
1063 kfree(d);
1064 }
1065 for(i = 0 ; i < pHba->top_scsi_channel ; i++){
1066 for(j = 0; j < MAX_ID; j++){
1067 if(pHba->channel[i].device[j] != NULL){
1068 for(pDev = pHba->channel[i].device[j]; pDev; pDev = pNext){
1069 pNext = pDev->next_lun;
1070 kfree(pDev);
1071 }
1072 }
1073 }
1074 }
Alan Coxa07f3532006-09-15 15:34:32 +01001075 pci_dev_put(pHba->pDev);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001076 kfree(pHba);
1077
1078 if(hba_count <= 0){
1079 unregister_chrdev(DPTI_I2O_MAJOR, DPT_DRIVER);
1080 }
1081}
1082
1083
Andrew Morton24601bb2007-12-10 15:49:20 -08001084static int adpt_init(void)
1085{
1086 printk("Loading Adaptec I2O RAID: Version " DPT_I2O_VERSION "\n");
1087#ifdef REBOOT_NOTIFIER
1088 register_reboot_notifier(&adpt_reboot_notifier);
1089#endif
1090
1091 return 0;
1092}
1093
1094
Linus Torvalds1da177e2005-04-16 15:20:36 -07001095static struct adpt_device* adpt_find_device(adpt_hba* pHba, u32 chan, u32 id, u32 lun)
1096{
1097 struct adpt_device* d;
1098
1099 if(chan < 0 || chan >= MAX_CHANNEL)
1100 return NULL;
1101
1102 if( pHba->channel[chan].device == NULL){
1103 printk(KERN_DEBUG"Adaptec I2O RAID: Trying to find device before they are allocated\n");
1104 return NULL;
1105 }
1106
1107 d = pHba->channel[chan].device[id];
1108 if(!d || d->tid == 0) {
1109 return NULL;
1110 }
1111
1112 /* If it is the only lun at that address then this should match*/
1113 if(d->scsi_lun == lun){
1114 return d;
1115 }
1116
1117 /* else we need to look through all the luns */
1118 for(d=d->next_lun ; d ; d = d->next_lun){
1119 if(d->scsi_lun == lun){
1120 return d;
1121 }
1122 }
1123 return NULL;
1124}
1125
1126
1127static int adpt_i2o_post_wait(adpt_hba* pHba, u32* msg, int len, int timeout)
1128{
1129 // I used my own version of the WAIT_QUEUE_HEAD
1130 // to handle some version differences
1131 // When embedded in the kernel this could go back to the vanilla one
1132 ADPT_DECLARE_WAIT_QUEUE_HEAD(adpt_wq_i2o_post);
1133 int status = 0;
1134 ulong flags = 0;
1135 struct adpt_i2o_post_wait_data *p1, *p2;
1136 struct adpt_i2o_post_wait_data *wait_data =
1137 kmalloc(sizeof(struct adpt_i2o_post_wait_data),GFP_KERNEL);
Andrew Morton4452ea52005-06-23 00:10:26 -07001138 DECLARE_WAITQUEUE(wait, current);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001139
Andrew Morton4452ea52005-06-23 00:10:26 -07001140 if (!wait_data)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001141 return -ENOMEM;
Andrew Morton4452ea52005-06-23 00:10:26 -07001142
Linus Torvalds1da177e2005-04-16 15:20:36 -07001143 /*
1144 * The spin locking is needed to keep anyone from playing
1145 * with the queue pointers and id while we do the same
1146 */
1147 spin_lock_irqsave(&adpt_post_wait_lock, flags);
1148 // TODO we need a MORE unique way of getting ids
1149 // to support async LCT get
1150 wait_data->next = adpt_post_wait_queue;
1151 adpt_post_wait_queue = wait_data;
1152 adpt_post_wait_id++;
1153 adpt_post_wait_id &= 0x7fff;
1154 wait_data->id = adpt_post_wait_id;
1155 spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
1156
1157 wait_data->wq = &adpt_wq_i2o_post;
1158 wait_data->status = -ETIMEDOUT;
1159
Andrew Morton4452ea52005-06-23 00:10:26 -07001160 add_wait_queue(&adpt_wq_i2o_post, &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001161
1162 msg[2] |= 0x80000000 | ((u32)wait_data->id);
1163 timeout *= HZ;
1164 if((status = adpt_i2o_post_this(pHba, msg, len)) == 0){
1165 set_current_state(TASK_INTERRUPTIBLE);
1166 if(pHba->host)
1167 spin_unlock_irq(pHba->host->host_lock);
1168 if (!timeout)
1169 schedule();
1170 else{
1171 timeout = schedule_timeout(timeout);
1172 if (timeout == 0) {
1173 // I/O issued, but cannot get result in
1174 // specified time. Freeing resorces is
1175 // dangerous.
1176 status = -ETIME;
1177 }
1178 }
1179 if(pHba->host)
1180 spin_lock_irq(pHba->host->host_lock);
1181 }
Andrew Morton4452ea52005-06-23 00:10:26 -07001182 remove_wait_queue(&adpt_wq_i2o_post, &wait);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001183
1184 if(status == -ETIMEDOUT){
1185 printk(KERN_INFO"dpti%d: POST WAIT TIMEOUT\n",pHba->unit);
1186 // We will have to free the wait_data memory during shutdown
1187 return status;
1188 }
1189
1190 /* Remove the entry from the queue. */
1191 p2 = NULL;
1192 spin_lock_irqsave(&adpt_post_wait_lock, flags);
1193 for(p1 = adpt_post_wait_queue; p1; p2 = p1, p1 = p1->next) {
1194 if(p1 == wait_data) {
1195 if(p1->status == I2O_DETAIL_STATUS_UNSUPPORTED_FUNCTION ) {
1196 status = -EOPNOTSUPP;
1197 }
1198 if(p2) {
1199 p2->next = p1->next;
1200 } else {
1201 adpt_post_wait_queue = p1->next;
1202 }
1203 break;
1204 }
1205 }
1206 spin_unlock_irqrestore(&adpt_post_wait_lock, flags);
1207
1208 kfree(wait_data);
1209
1210 return status;
1211}
1212
1213
1214static s32 adpt_i2o_post_this(adpt_hba* pHba, u32* data, int len)
1215{
1216
1217 u32 m = EMPTY_QUEUE;
1218 u32 __iomem *msg;
1219 ulong timeout = jiffies + 30*HZ;
1220 do {
1221 rmb();
1222 m = readl(pHba->post_port);
1223 if (m != EMPTY_QUEUE) {
1224 break;
1225 }
1226 if(time_after(jiffies,timeout)){
1227 printk(KERN_WARNING"dpti%d: Timeout waiting for message frame!\n", pHba->unit);
1228 return -ETIMEDOUT;
1229 }
Nishanth Aravamudana9a30472005-11-07 01:01:20 -08001230 schedule_timeout_uninterruptible(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001231 } while(m == EMPTY_QUEUE);
1232
1233 msg = pHba->msg_addr_virt + m;
1234 memcpy_toio(msg, data, len);
1235 wmb();
1236
1237 //post message
1238 writel(m, pHba->post_port);
1239 wmb();
1240
1241 return 0;
1242}
1243
1244
1245static void adpt_i2o_post_wait_complete(u32 context, int status)
1246{
1247 struct adpt_i2o_post_wait_data *p1 = NULL;
1248 /*
1249 * We need to search through the adpt_post_wait
1250 * queue to see if the given message is still
1251 * outstanding. If not, it means that the IOP
1252 * took longer to respond to the message than we
1253 * had allowed and timer has already expired.
1254 * Not much we can do about that except log
1255 * it for debug purposes, increase timeout, and recompile
1256 *
1257 * Lock needed to keep anyone from moving queue pointers
1258 * around while we're looking through them.
1259 */
1260
1261 context &= 0x7fff;
1262
1263 spin_lock(&adpt_post_wait_lock);
1264 for(p1 = adpt_post_wait_queue; p1; p1 = p1->next) {
1265 if(p1->id == context) {
1266 p1->status = status;
1267 spin_unlock(&adpt_post_wait_lock);
1268 wake_up_interruptible(p1->wq);
1269 return;
1270 }
1271 }
1272 spin_unlock(&adpt_post_wait_lock);
1273 // If this happens we lose commands that probably really completed
1274 printk(KERN_DEBUG"dpti: Could Not find task %d in wait queue\n",context);
1275 printk(KERN_DEBUG" Tasks in wait queue:\n");
1276 for(p1 = adpt_post_wait_queue; p1; p1 = p1->next) {
1277 printk(KERN_DEBUG" %d\n",p1->id);
1278 }
1279 return;
1280}
1281
1282static s32 adpt_i2o_reset_hba(adpt_hba* pHba)
1283{
1284 u32 msg[8];
1285 u8* status;
1286 u32 m = EMPTY_QUEUE ;
1287 ulong timeout = jiffies + (TMOUT_IOPRESET*HZ);
1288
1289 if(pHba->initialized == FALSE) { // First time reset should be quick
1290 timeout = jiffies + (25*HZ);
1291 } else {
1292 adpt_i2o_quiesce_hba(pHba);
1293 }
1294
1295 do {
1296 rmb();
1297 m = readl(pHba->post_port);
1298 if (m != EMPTY_QUEUE) {
1299 break;
1300 }
1301 if(time_after(jiffies,timeout)){
1302 printk(KERN_WARNING"Timeout waiting for message!\n");
1303 return -ETIMEDOUT;
1304 }
Nishanth Aravamudana9a30472005-11-07 01:01:20 -08001305 schedule_timeout_uninterruptible(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001306 } while (m == EMPTY_QUEUE);
1307
vignesh.babu@wipro.comab552202007-04-16 11:35:38 +05301308 status = kzalloc(4, GFP_KERNEL|ADDR32);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001309 if(status == NULL) {
1310 adpt_send_nop(pHba, m);
1311 printk(KERN_ERR"IOP reset failed - no free memory.\n");
1312 return -ENOMEM;
1313 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001314
1315 msg[0]=EIGHT_WORD_MSG_SIZE|SGL_OFFSET_0;
1316 msg[1]=I2O_CMD_ADAPTER_RESET<<24|HOST_TID<<12|ADAPTER_TID;
1317 msg[2]=0;
1318 msg[3]=0;
1319 msg[4]=0;
1320 msg[5]=0;
1321 msg[6]=virt_to_bus(status);
1322 msg[7]=0;
1323
1324 memcpy_toio(pHba->msg_addr_virt+m, msg, sizeof(msg));
1325 wmb();
1326 writel(m, pHba->post_port);
1327 wmb();
1328
1329 while(*status == 0){
1330 if(time_after(jiffies,timeout)){
1331 printk(KERN_WARNING"%s: IOP Reset Timeout\n",pHba->name);
1332 kfree(status);
1333 return -ETIMEDOUT;
1334 }
1335 rmb();
Nishanth Aravamudana9a30472005-11-07 01:01:20 -08001336 schedule_timeout_uninterruptible(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001337 }
1338
1339 if(*status == 0x01 /*I2O_EXEC_IOP_RESET_IN_PROGRESS*/) {
1340 PDEBUG("%s: Reset in progress...\n", pHba->name);
1341 // Here we wait for message frame to become available
1342 // indicated that reset has finished
1343 do {
1344 rmb();
1345 m = readl(pHba->post_port);
1346 if (m != EMPTY_QUEUE) {
1347 break;
1348 }
1349 if(time_after(jiffies,timeout)){
1350 printk(KERN_ERR "%s:Timeout waiting for IOP Reset.\n",pHba->name);
1351 return -ETIMEDOUT;
1352 }
Nishanth Aravamudana9a30472005-11-07 01:01:20 -08001353 schedule_timeout_uninterruptible(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001354 } while (m == EMPTY_QUEUE);
1355 // Flush the offset
1356 adpt_send_nop(pHba, m);
1357 }
1358 adpt_i2o_status_get(pHba);
1359 if(*status == 0x02 ||
1360 pHba->status_block->iop_state != ADAPTER_STATE_RESET) {
1361 printk(KERN_WARNING"%s: Reset reject, trying to clear\n",
1362 pHba->name);
1363 } else {
1364 PDEBUG("%s: Reset completed.\n", pHba->name);
1365 }
1366
1367 kfree(status);
1368#ifdef UARTDELAY
1369 // This delay is to allow someone attached to the card through the debug UART to
1370 // set up the dump levels that they want before the rest of the initialization sequence
1371 adpt_delay(20000);
1372#endif
1373 return 0;
1374}
1375
1376
1377static int adpt_i2o_parse_lct(adpt_hba* pHba)
1378{
1379 int i;
1380 int max;
1381 int tid;
1382 struct i2o_device *d;
1383 i2o_lct *lct = pHba->lct;
1384 u8 bus_no = 0;
1385 s16 scsi_id;
1386 s16 scsi_lun;
1387 u32 buf[10]; // larger than 7, or 8 ...
1388 struct adpt_device* pDev;
1389
1390 if (lct == NULL) {
1391 printk(KERN_ERR "%s: LCT is empty???\n",pHba->name);
1392 return -1;
1393 }
1394
1395 max = lct->table_size;
1396 max -= 3;
1397 max /= 9;
1398
1399 for(i=0;i<max;i++) {
1400 if( lct->lct_entry[i].user_tid != 0xfff){
1401 /*
1402 * If we have hidden devices, we need to inform the upper layers about
1403 * the possible maximum id reference to handle device access when
1404 * an array is disassembled. This code has no other purpose but to
1405 * allow us future access to devices that are currently hidden
1406 * behind arrays, hotspares or have not been configured (JBOD mode).
1407 */
1408 if( lct->lct_entry[i].class_id != I2O_CLASS_RANDOM_BLOCK_STORAGE &&
1409 lct->lct_entry[i].class_id != I2O_CLASS_SCSI_PERIPHERAL &&
1410 lct->lct_entry[i].class_id != I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
1411 continue;
1412 }
1413 tid = lct->lct_entry[i].tid;
1414 // I2O_DPT_DEVICE_INFO_GROUP_NO;
1415 if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)<0) {
1416 continue;
1417 }
1418 bus_no = buf[0]>>16;
1419 scsi_id = buf[1];
1420 scsi_lun = (buf[2]>>8 )&0xff;
1421 if(bus_no >= MAX_CHANNEL) { // Something wrong skip it
1422 printk(KERN_WARNING"%s: Channel number %d out of range \n", pHba->name, bus_no);
1423 continue;
1424 }
1425 if (scsi_id >= MAX_ID){
1426 printk(KERN_WARNING"%s: SCSI ID %d out of range \n", pHba->name, bus_no);
1427 continue;
1428 }
1429 if(bus_no > pHba->top_scsi_channel){
1430 pHba->top_scsi_channel = bus_no;
1431 }
1432 if(scsi_id > pHba->top_scsi_id){
1433 pHba->top_scsi_id = scsi_id;
1434 }
1435 if(scsi_lun > pHba->top_scsi_lun){
1436 pHba->top_scsi_lun = scsi_lun;
1437 }
1438 continue;
1439 }
Robert P. J. Day5cbded52006-12-13 00:35:56 -08001440 d = kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001441 if(d==NULL)
1442 {
1443 printk(KERN_CRIT"%s: Out of memory for I2O device data.\n",pHba->name);
1444 return -ENOMEM;
1445 }
1446
Benoit Boissinot 1c2fb3f2005-04-25 19:46:48 -07001447 d->controller = pHba;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001448 d->next = NULL;
1449
1450 memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
1451
1452 d->flags = 0;
1453 tid = d->lct_data.tid;
1454 adpt_i2o_report_hba_unit(pHba, d);
1455 adpt_i2o_install_device(pHba, d);
1456 }
1457 bus_no = 0;
1458 for(d = pHba->devices; d ; d = d->next) {
1459 if(d->lct_data.class_id == I2O_CLASS_BUS_ADAPTER_PORT ||
1460 d->lct_data.class_id == I2O_CLASS_FIBRE_CHANNEL_PORT){
1461 tid = d->lct_data.tid;
1462 // TODO get the bus_no from hrt-but for now they are in order
1463 //bus_no =
1464 if(bus_no > pHba->top_scsi_channel){
1465 pHba->top_scsi_channel = bus_no;
1466 }
1467 pHba->channel[bus_no].type = d->lct_data.class_id;
1468 pHba->channel[bus_no].tid = tid;
1469 if(adpt_i2o_query_scalar(pHba, tid, 0x0200, -1, buf, 28)>=0)
1470 {
1471 pHba->channel[bus_no].scsi_id = buf[1];
1472 PDEBUG("Bus %d - SCSI ID %d.\n", bus_no, buf[1]);
1473 }
1474 // TODO remove - this is just until we get from hrt
1475 bus_no++;
1476 if(bus_no >= MAX_CHANNEL) { // Something wrong skip it
1477 printk(KERN_WARNING"%s: Channel number %d out of range - LCT\n", pHba->name, bus_no);
1478 break;
1479 }
1480 }
1481 }
1482
1483 // Setup adpt_device table
1484 for(d = pHba->devices; d ; d = d->next) {
1485 if(d->lct_data.class_id == I2O_CLASS_RANDOM_BLOCK_STORAGE ||
1486 d->lct_data.class_id == I2O_CLASS_SCSI_PERIPHERAL ||
1487 d->lct_data.class_id == I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
1488
1489 tid = d->lct_data.tid;
1490 scsi_id = -1;
1491 // I2O_DPT_DEVICE_INFO_GROUP_NO;
1492 if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)>=0) {
1493 bus_no = buf[0]>>16;
1494 scsi_id = buf[1];
1495 scsi_lun = (buf[2]>>8 )&0xff;
1496 if(bus_no >= MAX_CHANNEL) { // Something wrong skip it
1497 continue;
1498 }
1499 if (scsi_id >= MAX_ID) {
1500 continue;
1501 }
1502 if( pHba->channel[bus_no].device[scsi_id] == NULL){
vignesh.babu@wipro.comab552202007-04-16 11:35:38 +05301503 pDev = kzalloc(sizeof(struct adpt_device),GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001504 if(pDev == NULL) {
1505 return -ENOMEM;
1506 }
1507 pHba->channel[bus_no].device[scsi_id] = pDev;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001508 } else {
1509 for( pDev = pHba->channel[bus_no].device[scsi_id];
1510 pDev->next_lun; pDev = pDev->next_lun){
1511 }
vignesh.babu@wipro.comab552202007-04-16 11:35:38 +05301512 pDev->next_lun = kzalloc(sizeof(struct adpt_device),GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001513 if(pDev->next_lun == NULL) {
1514 return -ENOMEM;
1515 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001516 pDev = pDev->next_lun;
1517 }
1518 pDev->tid = tid;
1519 pDev->scsi_channel = bus_no;
1520 pDev->scsi_id = scsi_id;
1521 pDev->scsi_lun = scsi_lun;
1522 pDev->pI2o_dev = d;
1523 d->owner = pDev;
1524 pDev->type = (buf[0])&0xff;
1525 pDev->flags = (buf[0]>>8)&0xff;
1526 if(scsi_id > pHba->top_scsi_id){
1527 pHba->top_scsi_id = scsi_id;
1528 }
1529 if(scsi_lun > pHba->top_scsi_lun){
1530 pHba->top_scsi_lun = scsi_lun;
1531 }
1532 }
1533 if(scsi_id == -1){
1534 printk(KERN_WARNING"Could not find SCSI ID for %s\n",
1535 d->lct_data.identity_tag);
1536 }
1537 }
1538 }
1539 return 0;
1540}
1541
1542
1543/*
1544 * Each I2O controller has a chain of devices on it - these match
1545 * the useful parts of the LCT of the board.
1546 */
1547
1548static int adpt_i2o_install_device(adpt_hba* pHba, struct i2o_device *d)
1549{
Arjan van de Ven0b950672006-01-11 13:16:10 +01001550 mutex_lock(&adpt_configuration_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001551 d->controller=pHba;
1552 d->owner=NULL;
1553 d->next=pHba->devices;
1554 d->prev=NULL;
1555 if (pHba->devices != NULL){
1556 pHba->devices->prev=d;
1557 }
1558 pHba->devices=d;
1559 *d->dev_name = 0;
1560
Arjan van de Ven0b950672006-01-11 13:16:10 +01001561 mutex_unlock(&adpt_configuration_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001562 return 0;
1563}
1564
1565static int adpt_open(struct inode *inode, struct file *file)
1566{
1567 int minor;
1568 adpt_hba* pHba;
1569
1570 //TODO check for root access
1571 //
1572 minor = iminor(inode);
1573 if (minor >= hba_count) {
1574 return -ENXIO;
1575 }
Arjan van de Ven0b950672006-01-11 13:16:10 +01001576 mutex_lock(&adpt_configuration_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001577 for (pHba = hba_chain; pHba; pHba = pHba->next) {
1578 if (pHba->unit == minor) {
1579 break; /* found adapter */
1580 }
1581 }
1582 if (pHba == NULL) {
Arjan van de Ven0b950672006-01-11 13:16:10 +01001583 mutex_unlock(&adpt_configuration_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001584 return -ENXIO;
1585 }
1586
1587// if(pHba->in_use){
Arjan van de Ven0b950672006-01-11 13:16:10 +01001588 // mutex_unlock(&adpt_configuration_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001589// return -EBUSY;
1590// }
1591
1592 pHba->in_use = 1;
Arjan van de Ven0b950672006-01-11 13:16:10 +01001593 mutex_unlock(&adpt_configuration_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001594
1595 return 0;
1596}
1597
1598static int adpt_close(struct inode *inode, struct file *file)
1599{
1600 int minor;
1601 adpt_hba* pHba;
1602
1603 minor = iminor(inode);
1604 if (minor >= hba_count) {
1605 return -ENXIO;
1606 }
Arjan van de Ven0b950672006-01-11 13:16:10 +01001607 mutex_lock(&adpt_configuration_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001608 for (pHba = hba_chain; pHba; pHba = pHba->next) {
1609 if (pHba->unit == minor) {
1610 break; /* found adapter */
1611 }
1612 }
Arjan van de Ven0b950672006-01-11 13:16:10 +01001613 mutex_unlock(&adpt_configuration_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001614 if (pHba == NULL) {
1615 return -ENXIO;
1616 }
1617
1618 pHba->in_use = 0;
1619
1620 return 0;
1621}
1622
1623
1624static int adpt_i2o_passthru(adpt_hba* pHba, u32 __user *arg)
1625{
1626 u32 msg[MAX_MESSAGE_SIZE];
1627 u32* reply = NULL;
1628 u32 size = 0;
1629 u32 reply_size = 0;
1630 u32 __user *user_msg = arg;
1631 u32 __user * user_reply = NULL;
1632 void *sg_list[pHba->sg_tablesize];
1633 u32 sg_offset = 0;
1634 u32 sg_count = 0;
1635 int sg_index = 0;
1636 u32 i = 0;
1637 u32 rcode = 0;
1638 void *p = NULL;
1639 ulong flags = 0;
1640
1641 memset(&msg, 0, MAX_MESSAGE_SIZE*4);
1642 // get user msg size in u32s
1643 if(get_user(size, &user_msg[0])){
1644 return -EFAULT;
1645 }
1646 size = size>>16;
1647
1648 user_reply = &user_msg[size];
1649 if(size > MAX_MESSAGE_SIZE){
1650 return -EFAULT;
1651 }
1652 size *= 4; // Convert to bytes
1653
1654 /* Copy in the user's I2O command */
1655 if(copy_from_user(msg, user_msg, size)) {
1656 return -EFAULT;
1657 }
1658 get_user(reply_size, &user_reply[0]);
1659 reply_size = reply_size>>16;
1660 if(reply_size > REPLY_FRAME_SIZE){
1661 reply_size = REPLY_FRAME_SIZE;
1662 }
1663 reply_size *= 4;
vignesh.babu@wipro.comab552202007-04-16 11:35:38 +05301664 reply = kzalloc(REPLY_FRAME_SIZE*4, GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001665 if(reply == NULL) {
1666 printk(KERN_WARNING"%s: Could not allocate reply buffer\n",pHba->name);
1667 return -ENOMEM;
1668 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07001669 sg_offset = (msg[0]>>4)&0xf;
1670 msg[2] = 0x40000000; // IOCTL context
1671 msg[3] = (u32)reply;
1672 memset(sg_list,0, sizeof(sg_list[0])*pHba->sg_tablesize);
1673 if(sg_offset) {
1674 // TODO 64bit fix
1675 struct sg_simple_element *sg = (struct sg_simple_element*) (msg+sg_offset);
1676 sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
1677 if (sg_count > pHba->sg_tablesize){
1678 printk(KERN_DEBUG"%s:IOCTL SG List too large (%u)\n", pHba->name,sg_count);
1679 kfree (reply);
1680 return -EINVAL;
1681 }
1682
1683 for(i = 0; i < sg_count; i++) {
1684 int sg_size;
1685
1686 if (!(sg[i].flag_count & 0x10000000 /*I2O_SGL_FLAGS_SIMPLE_ADDRESS_ELEMENT*/)) {
1687 printk(KERN_DEBUG"%s:Bad SG element %d - not simple (%x)\n",pHba->name,i, sg[i].flag_count);
1688 rcode = -EINVAL;
1689 goto cleanup;
1690 }
1691 sg_size = sg[i].flag_count & 0xffffff;
1692 /* Allocate memory for the transfer */
1693 p = kmalloc(sg_size, GFP_KERNEL|ADDR32);
1694 if(!p) {
1695 printk(KERN_DEBUG"%s: Could not allocate SG buffer - size = %d buffer number %d of %d\n",
1696 pHba->name,sg_size,i,sg_count);
1697 rcode = -ENOMEM;
1698 goto cleanup;
1699 }
1700 sg_list[sg_index++] = p; // sglist indexed with input frame, not our internal frame.
1701 /* Copy in the user's SG buffer if necessary */
1702 if(sg[i].flag_count & 0x04000000 /*I2O_SGL_FLAGS_DIR*/) {
1703 // TODO 64bit fix
1704 if (copy_from_user(p,(void __user *)sg[i].addr_bus, sg_size)) {
1705 printk(KERN_DEBUG"%s: Could not copy SG buf %d FROM user\n",pHba->name,i);
1706 rcode = -EFAULT;
1707 goto cleanup;
1708 }
1709 }
1710 //TODO 64bit fix
1711 sg[i].addr_bus = (u32)virt_to_bus(p);
1712 }
1713 }
1714
1715 do {
1716 if(pHba->host)
1717 spin_lock_irqsave(pHba->host->host_lock, flags);
1718 // This state stops any new commands from enterring the
1719 // controller while processing the ioctl
1720// pHba->state |= DPTI_STATE_IOCTL;
1721// We can't set this now - The scsi subsystem sets host_blocked and
1722// the queue empties and stops. We need a way to restart the queue
1723 rcode = adpt_i2o_post_wait(pHba, msg, size, FOREVER);
1724 if (rcode != 0)
1725 printk("adpt_i2o_passthru: post wait failed %d %p\n",
1726 rcode, reply);
1727// pHba->state &= ~DPTI_STATE_IOCTL;
1728 if(pHba->host)
1729 spin_unlock_irqrestore(pHba->host->host_lock, flags);
1730 } while(rcode == -ETIMEDOUT);
1731
1732 if(rcode){
1733 goto cleanup;
1734 }
1735
1736 if(sg_offset) {
1737 /* Copy back the Scatter Gather buffers back to user space */
1738 u32 j;
1739 // TODO 64bit fix
1740 struct sg_simple_element* sg;
1741 int sg_size;
1742
1743 // re-acquire the original message to handle correctly the sg copy operation
1744 memset(&msg, 0, MAX_MESSAGE_SIZE*4);
1745 // get user msg size in u32s
1746 if(get_user(size, &user_msg[0])){
1747 rcode = -EFAULT;
1748 goto cleanup;
1749 }
1750 size = size>>16;
1751 size *= 4;
1752 /* Copy in the user's I2O command */
1753 if (copy_from_user (msg, user_msg, size)) {
1754 rcode = -EFAULT;
1755 goto cleanup;
1756 }
1757 sg_count = (size - sg_offset*4) / sizeof(struct sg_simple_element);
1758
1759 // TODO 64bit fix
1760 sg = (struct sg_simple_element*)(msg + sg_offset);
1761 for (j = 0; j < sg_count; j++) {
1762 /* Copy out the SG list to user's buffer if necessary */
1763 if(! (sg[j].flag_count & 0x4000000 /*I2O_SGL_FLAGS_DIR*/)) {
1764 sg_size = sg[j].flag_count & 0xffffff;
1765 // TODO 64bit fix
1766 if (copy_to_user((void __user *)sg[j].addr_bus,sg_list[j], sg_size)) {
1767 printk(KERN_WARNING"%s: Could not copy %p TO user %x\n",pHba->name, sg_list[j], sg[j].addr_bus);
1768 rcode = -EFAULT;
1769 goto cleanup;
1770 }
1771 }
1772 }
1773 }
1774
1775 /* Copy back the reply to user space */
1776 if (reply_size) {
1777 // we wrote our own values for context - now restore the user supplied ones
1778 if(copy_from_user(reply+2, user_msg+2, sizeof(u32)*2)) {
1779 printk(KERN_WARNING"%s: Could not copy message context FROM user\n",pHba->name);
1780 rcode = -EFAULT;
1781 }
1782 if(copy_to_user(user_reply, reply, reply_size)) {
1783 printk(KERN_WARNING"%s: Could not copy reply TO user\n",pHba->name);
1784 rcode = -EFAULT;
1785 }
1786 }
1787
1788
1789cleanup:
1790 if (rcode != -ETIME && rcode != -EINTR)
1791 kfree (reply);
1792 while(sg_index) {
1793 if(sg_list[--sg_index]) {
1794 if (rcode != -ETIME && rcode != -EINTR)
1795 kfree(sg_list[sg_index]);
1796 }
1797 }
1798 return rcode;
1799}
1800
1801
1802/*
1803 * This routine returns information about the system. This does not effect
1804 * any logic and if the info is wrong - it doesn't matter.
1805 */
1806
1807/* Get all the info we can not get from kernel services */
1808static int adpt_system_info(void __user *buffer)
1809{
1810 sysInfo_S si;
1811
1812 memset(&si, 0, sizeof(si));
1813
1814 si.osType = OS_LINUX;
Adrian Bunka4cd16e2005-06-25 14:59:01 -07001815 si.osMajorVersion = 0;
1816 si.osMinorVersion = 0;
1817 si.osRevision = 0;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001818 si.busType = SI_PCI_BUS;
1819 si.processorFamily = DPTI_sig.dsProcessorFamily;
1820
1821#if defined __i386__
1822 adpt_i386_info(&si);
1823#elif defined (__ia64__)
1824 adpt_ia64_info(&si);
1825#elif defined(__sparc__)
1826 adpt_sparc_info(&si);
1827#elif defined (__alpha__)
1828 adpt_alpha_info(&si);
1829#else
1830 si.processorType = 0xff ;
1831#endif
1832 if(copy_to_user(buffer, &si, sizeof(si))){
1833 printk(KERN_WARNING"dpti: Could not copy buffer TO user\n");
1834 return -EFAULT;
1835 }
1836
1837 return 0;
1838}
1839
1840#if defined __ia64__
1841static void adpt_ia64_info(sysInfo_S* si)
1842{
1843 // This is all the info we need for now
1844 // We will add more info as our new
1845 // managmenent utility requires it
1846 si->processorType = PROC_IA64;
1847}
1848#endif
1849
1850
1851#if defined __sparc__
1852static void adpt_sparc_info(sysInfo_S* si)
1853{
1854 // This is all the info we need for now
1855 // We will add more info as our new
1856 // managmenent utility requires it
1857 si->processorType = PROC_ULTRASPARC;
1858}
1859#endif
1860
1861#if defined __alpha__
1862static void adpt_alpha_info(sysInfo_S* si)
1863{
1864 // This is all the info we need for now
1865 // We will add more info as our new
1866 // managmenent utility requires it
1867 si->processorType = PROC_ALPHA;
1868}
1869#endif
1870
1871#if defined __i386__
1872
1873static void adpt_i386_info(sysInfo_S* si)
1874{
1875 // This is all the info we need for now
1876 // We will add more info as our new
1877 // managmenent utility requires it
1878 switch (boot_cpu_data.x86) {
1879 case CPU_386:
1880 si->processorType = PROC_386;
1881 break;
1882 case CPU_486:
1883 si->processorType = PROC_486;
1884 break;
1885 case CPU_586:
1886 si->processorType = PROC_PENTIUM;
1887 break;
1888 default: // Just in case
1889 si->processorType = PROC_PENTIUM;
1890 break;
1891 }
1892}
1893
1894#endif
1895
1896
1897static int adpt_ioctl(struct inode *inode, struct file *file, uint cmd,
1898 ulong arg)
1899{
1900 int minor;
1901 int error = 0;
1902 adpt_hba* pHba;
1903 ulong flags = 0;
1904 void __user *argp = (void __user *)arg;
1905
1906 minor = iminor(inode);
1907 if (minor >= DPTI_MAX_HBA){
1908 return -ENXIO;
1909 }
Arjan van de Ven0b950672006-01-11 13:16:10 +01001910 mutex_lock(&adpt_configuration_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001911 for (pHba = hba_chain; pHba; pHba = pHba->next) {
1912 if (pHba->unit == minor) {
1913 break; /* found adapter */
1914 }
1915 }
Arjan van de Ven0b950672006-01-11 13:16:10 +01001916 mutex_unlock(&adpt_configuration_lock);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001917 if(pHba == NULL){
1918 return -ENXIO;
1919 }
1920
Nishanth Aravamudana9a30472005-11-07 01:01:20 -08001921 while((volatile u32) pHba->state & DPTI_STATE_RESET )
1922 schedule_timeout_uninterruptible(2);
Linus Torvalds1da177e2005-04-16 15:20:36 -07001923
1924 switch (cmd) {
1925 // TODO: handle 3 cases
1926 case DPT_SIGNATURE:
1927 if (copy_to_user(argp, &DPTI_sig, sizeof(DPTI_sig))) {
1928 return -EFAULT;
1929 }
1930 break;
1931 case I2OUSRCMD:
1932 return adpt_i2o_passthru(pHba, argp);
1933
1934 case DPT_CTRLINFO:{
1935 drvrHBAinfo_S HbaInfo;
1936
1937#define FLG_OSD_PCI_VALID 0x0001
1938#define FLG_OSD_DMA 0x0002
1939#define FLG_OSD_I2O 0x0004
1940 memset(&HbaInfo, 0, sizeof(HbaInfo));
1941 HbaInfo.drvrHBAnum = pHba->unit;
1942 HbaInfo.baseAddr = (ulong) pHba->base_addr_phys;
1943 HbaInfo.blinkState = adpt_read_blink_led(pHba);
1944 HbaInfo.pciBusNum = pHba->pDev->bus->number;
1945 HbaInfo.pciDeviceNum=PCI_SLOT(pHba->pDev->devfn);
1946 HbaInfo.Interrupt = pHba->pDev->irq;
1947 HbaInfo.hbaFlags = FLG_OSD_PCI_VALID | FLG_OSD_DMA | FLG_OSD_I2O;
1948 if(copy_to_user(argp, &HbaInfo, sizeof(HbaInfo))){
1949 printk(KERN_WARNING"%s: Could not copy HbaInfo TO user\n",pHba->name);
1950 return -EFAULT;
1951 }
1952 break;
1953 }
1954 case DPT_SYSINFO:
1955 return adpt_system_info(argp);
1956 case DPT_BLINKLED:{
1957 u32 value;
1958 value = (u32)adpt_read_blink_led(pHba);
1959 if (copy_to_user(argp, &value, sizeof(value))) {
1960 return -EFAULT;
1961 }
1962 break;
1963 }
1964 case I2ORESETCMD:
1965 if(pHba->host)
1966 spin_lock_irqsave(pHba->host->host_lock, flags);
1967 adpt_hba_reset(pHba);
1968 if(pHba->host)
1969 spin_unlock_irqrestore(pHba->host->host_lock, flags);
1970 break;
1971 case I2ORESCANCMD:
1972 adpt_rescan(pHba);
1973 break;
1974 default:
1975 return -EINVAL;
1976 }
1977
1978 return error;
1979}
1980
1981
David Howells7d12e782006-10-05 14:55:46 +01001982static irqreturn_t adpt_isr(int irq, void *dev_id)
Linus Torvalds1da177e2005-04-16 15:20:36 -07001983{
1984 struct scsi_cmnd* cmd;
1985 adpt_hba* pHba = dev_id;
1986 u32 m;
Benoit Boissinot 1c2fb3f2005-04-25 19:46:48 -07001987 void __iomem *reply;
Linus Torvalds1da177e2005-04-16 15:20:36 -07001988 u32 status=0;
1989 u32 context;
1990 ulong flags = 0;
1991 int handled = 0;
1992
1993 if (pHba == NULL){
1994 printk(KERN_WARNING"adpt_isr: NULL dev_id\n");
1995 return IRQ_NONE;
1996 }
1997 if(pHba->host)
1998 spin_lock_irqsave(pHba->host->host_lock, flags);
1999
2000 while( readl(pHba->irq_mask) & I2O_INTERRUPT_PENDING_B) {
2001 m = readl(pHba->reply_port);
2002 if(m == EMPTY_QUEUE){
2003 // Try twice then give up
2004 rmb();
2005 m = readl(pHba->reply_port);
2006 if(m == EMPTY_QUEUE){
2007 // This really should not happen
2008 printk(KERN_ERR"dpti: Could not get reply frame\n");
2009 goto out;
2010 }
2011 }
Benoit Boissinot 1c2fb3f2005-04-25 19:46:48 -07002012 reply = bus_to_virt(m);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002013
2014 if (readl(reply) & MSG_FAIL) {
2015 u32 old_m = readl(reply+28);
Benoit Boissinot 1c2fb3f2005-04-25 19:46:48 -07002016 void __iomem *msg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002017 u32 old_context;
2018 PDEBUG("%s: Failed message\n",pHba->name);
2019 if(old_m >= 0x100000){
2020 printk(KERN_ERR"%s: Bad preserved MFA (%x)- dropping frame\n",pHba->name,old_m);
2021 writel(m,pHba->reply_port);
2022 continue;
2023 }
2024 // Transaction context is 0 in failed reply frame
Benoit Boissinot 1c2fb3f2005-04-25 19:46:48 -07002025 msg = pHba->msg_addr_virt + old_m;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002026 old_context = readl(msg+12);
2027 writel(old_context, reply+12);
2028 adpt_send_nop(pHba, old_m);
2029 }
2030 context = readl(reply+8);
2031 if(context & 0x40000000){ // IOCTL
Benoit Boissinot 1c2fb3f2005-04-25 19:46:48 -07002032 void *p = (void *)readl(reply+12);
2033 if( p != NULL) {
2034 memcpy_fromio(p, reply, REPLY_FRAME_SIZE * 4);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002035 }
2036 // All IOCTLs will also be post wait
2037 }
2038 if(context & 0x80000000){ // Post wait message
2039 status = readl(reply+16);
2040 if(status >> 24){
2041 status &= 0xffff; /* Get detail status */
2042 } else {
2043 status = I2O_POST_WAIT_OK;
2044 }
2045 if(!(context & 0x40000000)) {
2046 cmd = (struct scsi_cmnd*) readl(reply+12);
2047 if(cmd != NULL) {
2048 printk(KERN_WARNING"%s: Apparent SCSI cmd in Post Wait Context - cmd=%p context=%x\n", pHba->name, cmd, context);
2049 }
2050 }
2051 adpt_i2o_post_wait_complete(context, status);
2052 } else { // SCSI message
2053 cmd = (struct scsi_cmnd*) readl(reply+12);
2054 if(cmd != NULL){
2055 if(cmd->serial_number != 0) { // If not timedout
2056 adpt_i2o_to_scsi(reply, cmd);
2057 }
2058 }
2059 }
2060 writel(m, pHba->reply_port);
2061 wmb();
2062 rmb();
2063 }
2064 handled = 1;
2065out: if(pHba->host)
2066 spin_unlock_irqrestore(pHba->host->host_lock, flags);
2067 return IRQ_RETVAL(handled);
2068}
2069
2070static s32 adpt_scsi_to_i2o(adpt_hba* pHba, struct scsi_cmnd* cmd, struct adpt_device* d)
2071{
2072 int i;
2073 u32 msg[MAX_MESSAGE_SIZE];
2074 u32* mptr;
2075 u32 *lenptr;
2076 int direction;
2077 int scsidir;
FUJITA Tomonori10803de2007-05-26 02:08:10 +09002078 int nseg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002079 u32 len;
2080 u32 reqlen;
2081 s32 rcode;
2082
2083 memset(msg, 0 , sizeof(msg));
FUJITA Tomonori10803de2007-05-26 02:08:10 +09002084 len = scsi_bufflen(cmd);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002085 direction = 0x00000000;
2086
2087 scsidir = 0x00000000; // DATA NO XFER
2088 if(len) {
2089 /*
2090 * Set SCBFlags to indicate if data is being transferred
2091 * in or out, or no data transfer
2092 * Note: Do not have to verify index is less than 0 since
2093 * cmd->cmnd[0] is an unsigned char
2094 */
2095 switch(cmd->sc_data_direction){
2096 case DMA_FROM_DEVICE:
2097 scsidir =0x40000000; // DATA IN (iop<--dev)
2098 break;
2099 case DMA_TO_DEVICE:
2100 direction=0x04000000; // SGL OUT
2101 scsidir =0x80000000; // DATA OUT (iop-->dev)
2102 break;
2103 case DMA_NONE:
2104 break;
2105 case DMA_BIDIRECTIONAL:
2106 scsidir =0x40000000; // DATA IN (iop<--dev)
2107 // Assume In - and continue;
2108 break;
2109 default:
2110 printk(KERN_WARNING"%s: scsi opcode 0x%x not supported.\n",
2111 pHba->name, cmd->cmnd[0]);
2112 cmd->result = (DID_OK <<16) | (INITIATOR_ERROR << 8);
2113 cmd->scsi_done(cmd);
2114 return 0;
2115 }
2116 }
2117 // msg[0] is set later
2118 // I2O_CMD_SCSI_EXEC
2119 msg[1] = ((0xff<<24)|(HOST_TID<<12)|d->tid);
2120 msg[2] = 0;
2121 msg[3] = (u32)cmd; /* We want the SCSI control block back */
2122 // Our cards use the transaction context as the tag for queueing
2123 // Adaptec/DPT Private stuff
2124 msg[4] = I2O_CMD_SCSI_EXEC|(DPT_ORGANIZATION_ID<<16);
2125 msg[5] = d->tid;
2126 /* Direction, disconnect ok | sense data | simple queue , CDBLen */
2127 // I2O_SCB_FLAG_ENABLE_DISCONNECT |
2128 // I2O_SCB_FLAG_SIMPLE_QUEUE_TAG |
2129 // I2O_SCB_FLAG_SENSE_DATA_IN_MESSAGE;
2130 msg[6] = scsidir|0x20a00000|cmd->cmd_len;
2131
2132 mptr=msg+7;
2133
2134 // Write SCSI command into the message - always 16 byte block
2135 memset(mptr, 0, 16);
2136 memcpy(mptr, cmd->cmnd, cmd->cmd_len);
2137 mptr+=4;
2138 lenptr=mptr++; /* Remember me - fill in when we know */
2139 reqlen = 14; // SINGLE SGE
2140 /* Now fill in the SGList and command */
Linus Torvalds1da177e2005-04-16 15:20:36 -07002141
FUJITA Tomonori10803de2007-05-26 02:08:10 +09002142 nseg = scsi_dma_map(cmd);
2143 BUG_ON(nseg < 0);
2144 if (nseg) {
2145 struct scatterlist *sg;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002146
2147 len = 0;
FUJITA Tomonori10803de2007-05-26 02:08:10 +09002148 scsi_for_each_sg(cmd, sg, nseg, i) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002149 *mptr++ = direction|0x10000000|sg_dma_len(sg);
2150 len+=sg_dma_len(sg);
2151 *mptr++ = sg_dma_address(sg);
FUJITA Tomonori10803de2007-05-26 02:08:10 +09002152 /* Make this an end of list */
2153 if (i == nseg - 1)
2154 mptr[-2] = direction|0xD0000000|sg_dma_len(sg);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002155 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002156 reqlen = mptr - msg;
2157 *lenptr = len;
2158
2159 if(cmd->underflow && len != cmd->underflow){
2160 printk(KERN_WARNING"Cmd len %08X Cmd underflow %08X\n",
2161 len, cmd->underflow);
2162 }
2163 } else {
FUJITA Tomonori10803de2007-05-26 02:08:10 +09002164 *lenptr = len = 0;
2165 reqlen = 12;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002166 }
2167
2168 /* Stick the headers on */
2169 msg[0] = reqlen<<16 | ((reqlen > 12) ? SGL_OFFSET_12 : SGL_OFFSET_0);
2170
2171 // Send it on it's way
2172 rcode = adpt_i2o_post_this(pHba, msg, reqlen<<2);
2173 if (rcode == 0) {
2174 return 0;
2175 }
2176 return rcode;
2177}
2178
2179
Andrew Morton24601bb2007-12-10 15:49:20 -08002180static s32 adpt_scsi_register(adpt_hba* pHba,struct scsi_host_template * sht)
2181{
2182 struct Scsi_Host *host = NULL;
2183
2184 host = scsi_register(sht, sizeof(adpt_hba*));
2185 if (host == NULL) {
2186 printk ("%s: scsi_register returned NULL\n",pHba->name);
2187 return -1;
2188 }
2189 host->hostdata[0] = (unsigned long)pHba;
2190 pHba->host = host;
2191
2192 host->irq = pHba->pDev->irq;
2193 /* no IO ports, so don't have to set host->io_port and
2194 * host->n_io_port
2195 */
2196 host->io_port = 0;
2197 host->n_io_port = 0;
2198 /* see comments in scsi_host.h */
2199 host->max_id = 16;
2200 host->max_lun = 256;
2201 host->max_channel = pHba->top_scsi_channel + 1;
2202 host->cmd_per_lun = 1;
2203 host->unique_id = (uint) pHba;
2204 host->sg_tablesize = pHba->sg_tablesize;
2205 host->can_queue = pHba->post_fifo_size;
2206
2207 return 0;
2208}
2209
2210
Benoit Boissinot 1c2fb3f2005-04-25 19:46:48 -07002211static s32 adpt_i2o_to_scsi(void __iomem *reply, struct scsi_cmnd* cmd)
Linus Torvalds1da177e2005-04-16 15:20:36 -07002212{
2213 adpt_hba* pHba;
2214 u32 hba_status;
2215 u32 dev_status;
2216 u32 reply_flags = readl(reply) & 0xff00; // Leave it shifted up 8 bits
2217 // I know this would look cleaner if I just read bytes
2218 // but the model I have been using for all the rest of the
2219 // io is in 4 byte words - so I keep that model
2220 u16 detailed_status = readl(reply+16) &0xffff;
2221 dev_status = (detailed_status & 0xff);
2222 hba_status = detailed_status >> 8;
2223
2224 // calculate resid for sg
FUJITA Tomonori10803de2007-05-26 02:08:10 +09002225 scsi_set_resid(cmd, scsi_bufflen(cmd) - readl(reply+5));
Linus Torvalds1da177e2005-04-16 15:20:36 -07002226
2227 pHba = (adpt_hba*) cmd->device->host->hostdata[0];
2228
2229 cmd->sense_buffer[0] = '\0'; // initialize sense valid flag to false
2230
2231 if(!(reply_flags & MSG_FAIL)) {
2232 switch(detailed_status & I2O_SCSI_DSC_MASK) {
2233 case I2O_SCSI_DSC_SUCCESS:
2234 cmd->result = (DID_OK << 16);
2235 // handle underflow
2236 if(readl(reply+5) < cmd->underflow ) {
2237 cmd->result = (DID_ERROR <<16);
2238 printk(KERN_WARNING"%s: SCSI CMD underflow\n",pHba->name);
2239 }
2240 break;
2241 case I2O_SCSI_DSC_REQUEST_ABORTED:
2242 cmd->result = (DID_ABORT << 16);
2243 break;
2244 case I2O_SCSI_DSC_PATH_INVALID:
2245 case I2O_SCSI_DSC_DEVICE_NOT_PRESENT:
2246 case I2O_SCSI_DSC_SELECTION_TIMEOUT:
2247 case I2O_SCSI_DSC_COMMAND_TIMEOUT:
2248 case I2O_SCSI_DSC_NO_ADAPTER:
2249 case I2O_SCSI_DSC_RESOURCE_UNAVAILABLE:
2250 printk(KERN_WARNING"%s: SCSI Timeout-Device (%d,%d,%d) hba status=0x%x, dev status=0x%x, cmd=0x%x\n",
2251 pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun, hba_status, dev_status, cmd->cmnd[0]);
2252 cmd->result = (DID_TIME_OUT << 16);
2253 break;
2254 case I2O_SCSI_DSC_ADAPTER_BUSY:
2255 case I2O_SCSI_DSC_BUS_BUSY:
2256 cmd->result = (DID_BUS_BUSY << 16);
2257 break;
2258 case I2O_SCSI_DSC_SCSI_BUS_RESET:
2259 case I2O_SCSI_DSC_BDR_MESSAGE_SENT:
2260 cmd->result = (DID_RESET << 16);
2261 break;
2262 case I2O_SCSI_DSC_PARITY_ERROR_FAILURE:
2263 printk(KERN_WARNING"%s: SCSI CMD parity error\n",pHba->name);
2264 cmd->result = (DID_PARITY << 16);
2265 break;
2266 case I2O_SCSI_DSC_UNABLE_TO_ABORT:
2267 case I2O_SCSI_DSC_COMPLETE_WITH_ERROR:
2268 case I2O_SCSI_DSC_UNABLE_TO_TERMINATE:
2269 case I2O_SCSI_DSC_MR_MESSAGE_RECEIVED:
2270 case I2O_SCSI_DSC_AUTOSENSE_FAILED:
2271 case I2O_SCSI_DSC_DATA_OVERRUN:
2272 case I2O_SCSI_DSC_UNEXPECTED_BUS_FREE:
2273 case I2O_SCSI_DSC_SEQUENCE_FAILURE:
2274 case I2O_SCSI_DSC_REQUEST_LENGTH_ERROR:
2275 case I2O_SCSI_DSC_PROVIDE_FAILURE:
2276 case I2O_SCSI_DSC_REQUEST_TERMINATED:
2277 case I2O_SCSI_DSC_IDE_MESSAGE_SENT:
2278 case I2O_SCSI_DSC_UNACKNOWLEDGED_EVENT:
2279 case I2O_SCSI_DSC_MESSAGE_RECEIVED:
2280 case I2O_SCSI_DSC_INVALID_CDB:
2281 case I2O_SCSI_DSC_LUN_INVALID:
2282 case I2O_SCSI_DSC_SCSI_TID_INVALID:
2283 case I2O_SCSI_DSC_FUNCTION_UNAVAILABLE:
2284 case I2O_SCSI_DSC_NO_NEXUS:
2285 case I2O_SCSI_DSC_CDB_RECEIVED:
2286 case I2O_SCSI_DSC_LUN_ALREADY_ENABLED:
2287 case I2O_SCSI_DSC_QUEUE_FROZEN:
2288 case I2O_SCSI_DSC_REQUEST_INVALID:
2289 default:
2290 printk(KERN_WARNING"%s: SCSI error %0x-Device(%d,%d,%d) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n",
2291 pHba->name, detailed_status & I2O_SCSI_DSC_MASK, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun,
2292 hba_status, dev_status, cmd->cmnd[0]);
2293 cmd->result = (DID_ERROR << 16);
2294 break;
2295 }
2296
2297 // copy over the request sense data if it was a check
2298 // condition status
Salyzyn, Markd814c512008-01-14 11:04:40 -08002299 if (dev_status == SAM_STAT_CHECK_CONDITION) {
FUJITA Tomonorib80ca4f2008-01-13 15:46:13 +09002300 u32 len = min(SCSI_SENSE_BUFFERSIZE, 40);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002301 // Copy over the sense data
Benoit Boissinot 1c2fb3f2005-04-25 19:46:48 -07002302 memcpy_fromio(cmd->sense_buffer, (reply+28) , len);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002303 if(cmd->sense_buffer[0] == 0x70 /* class 7 */ &&
2304 cmd->sense_buffer[2] == DATA_PROTECT ){
2305 /* This is to handle an array failed */
2306 cmd->result = (DID_TIME_OUT << 16);
2307 printk(KERN_WARNING"%s: SCSI Data Protect-Device (%d,%d,%d) hba_status=0x%x, dev_status=0x%x, cmd=0x%x\n",
2308 pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun,
2309 hba_status, dev_status, cmd->cmnd[0]);
2310
2311 }
2312 }
2313 } else {
2314 /* In this condtion we could not talk to the tid
2315 * the card rejected it. We should signal a retry
2316 * for a limitted number of retries.
2317 */
2318 cmd->result = (DID_TIME_OUT << 16);
2319 printk(KERN_WARNING"%s: I2O MSG_FAIL - Device (%d,%d,%d) tid=%d, cmd=0x%x\n",
2320 pHba->name, (u32)cmd->device->channel, (u32)cmd->device->id, (u32)cmd->device->lun,
2321 ((struct adpt_device*)(cmd->device->hostdata))->tid, cmd->cmnd[0]);
2322 }
2323
2324 cmd->result |= (dev_status);
2325
2326 if(cmd->scsi_done != NULL){
2327 cmd->scsi_done(cmd);
2328 }
2329 return cmd->result;
2330}
2331
2332
2333static s32 adpt_rescan(adpt_hba* pHba)
2334{
2335 s32 rcode;
2336 ulong flags = 0;
2337
2338 if(pHba->host)
2339 spin_lock_irqsave(pHba->host->host_lock, flags);
2340 if ((rcode=adpt_i2o_lct_get(pHba)) < 0)
2341 goto out;
2342 if ((rcode=adpt_i2o_reparse_lct(pHba)) < 0)
2343 goto out;
2344 rcode = 0;
2345out: if(pHba->host)
2346 spin_unlock_irqrestore(pHba->host->host_lock, flags);
2347 return rcode;
2348}
2349
2350
2351static s32 adpt_i2o_reparse_lct(adpt_hba* pHba)
2352{
2353 int i;
2354 int max;
2355 int tid;
2356 struct i2o_device *d;
2357 i2o_lct *lct = pHba->lct;
2358 u8 bus_no = 0;
2359 s16 scsi_id;
2360 s16 scsi_lun;
2361 u32 buf[10]; // at least 8 u32's
2362 struct adpt_device* pDev = NULL;
2363 struct i2o_device* pI2o_dev = NULL;
2364
2365 if (lct == NULL) {
2366 printk(KERN_ERR "%s: LCT is empty???\n",pHba->name);
2367 return -1;
2368 }
2369
2370 max = lct->table_size;
2371 max -= 3;
2372 max /= 9;
2373
2374 // Mark each drive as unscanned
2375 for (d = pHba->devices; d; d = d->next) {
2376 pDev =(struct adpt_device*) d->owner;
2377 if(!pDev){
2378 continue;
2379 }
2380 pDev->state |= DPTI_DEV_UNSCANNED;
2381 }
2382
2383 printk(KERN_INFO "%s: LCT has %d entries.\n", pHba->name,max);
2384
2385 for(i=0;i<max;i++) {
2386 if( lct->lct_entry[i].user_tid != 0xfff){
2387 continue;
2388 }
2389
2390 if( lct->lct_entry[i].class_id == I2O_CLASS_RANDOM_BLOCK_STORAGE ||
2391 lct->lct_entry[i].class_id == I2O_CLASS_SCSI_PERIPHERAL ||
2392 lct->lct_entry[i].class_id == I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL ){
2393 tid = lct->lct_entry[i].tid;
2394 if(adpt_i2o_query_scalar(pHba, tid, 0x8000, -1, buf, 32)<0) {
2395 printk(KERN_ERR"%s: Could not query device\n",pHba->name);
2396 continue;
2397 }
2398 bus_no = buf[0]>>16;
2399 scsi_id = buf[1];
2400 scsi_lun = (buf[2]>>8 )&0xff;
2401 pDev = pHba->channel[bus_no].device[scsi_id];
2402 /* da lun */
2403 while(pDev) {
2404 if(pDev->scsi_lun == scsi_lun) {
2405 break;
2406 }
2407 pDev = pDev->next_lun;
2408 }
2409 if(!pDev ) { // Something new add it
Robert P. J. Day5cbded52006-12-13 00:35:56 -08002410 d = kmalloc(sizeof(struct i2o_device), GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002411 if(d==NULL)
2412 {
2413 printk(KERN_CRIT "Out of memory for I2O device data.\n");
2414 return -ENOMEM;
2415 }
2416
Benoit Boissinot 1c2fb3f2005-04-25 19:46:48 -07002417 d->controller = pHba;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002418 d->next = NULL;
2419
2420 memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
2421
2422 d->flags = 0;
2423 adpt_i2o_report_hba_unit(pHba, d);
2424 adpt_i2o_install_device(pHba, d);
2425
2426 if(bus_no >= MAX_CHANNEL) { // Something wrong skip it
2427 printk(KERN_WARNING"%s: Channel number %d out of range \n", pHba->name, bus_no);
2428 continue;
2429 }
2430 pDev = pHba->channel[bus_no].device[scsi_id];
2431 if( pDev == NULL){
vignesh.babu@wipro.comab552202007-04-16 11:35:38 +05302432 pDev = kzalloc(sizeof(struct adpt_device),GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002433 if(pDev == NULL) {
2434 return -ENOMEM;
2435 }
2436 pHba->channel[bus_no].device[scsi_id] = pDev;
2437 } else {
2438 while (pDev->next_lun) {
2439 pDev = pDev->next_lun;
2440 }
vignesh.babu@wipro.comab552202007-04-16 11:35:38 +05302441 pDev = pDev->next_lun = kzalloc(sizeof(struct adpt_device),GFP_KERNEL);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002442 if(pDev == NULL) {
2443 return -ENOMEM;
2444 }
2445 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002446 pDev->tid = d->lct_data.tid;
2447 pDev->scsi_channel = bus_no;
2448 pDev->scsi_id = scsi_id;
2449 pDev->scsi_lun = scsi_lun;
2450 pDev->pI2o_dev = d;
2451 d->owner = pDev;
2452 pDev->type = (buf[0])&0xff;
2453 pDev->flags = (buf[0]>>8)&0xff;
2454 // Too late, SCSI system has made up it's mind, but what the hey ...
2455 if(scsi_id > pHba->top_scsi_id){
2456 pHba->top_scsi_id = scsi_id;
2457 }
2458 if(scsi_lun > pHba->top_scsi_lun){
2459 pHba->top_scsi_lun = scsi_lun;
2460 }
2461 continue;
2462 } // end of new i2o device
2463
2464 // We found an old device - check it
2465 while(pDev) {
2466 if(pDev->scsi_lun == scsi_lun) {
2467 if(!scsi_device_online(pDev->pScsi_dev)) {
2468 printk(KERN_WARNING"%s: Setting device (%d,%d,%d) back online\n",
2469 pHba->name,bus_no,scsi_id,scsi_lun);
2470 if (pDev->pScsi_dev) {
2471 scsi_device_set_state(pDev->pScsi_dev, SDEV_RUNNING);
2472 }
2473 }
2474 d = pDev->pI2o_dev;
2475 if(d->lct_data.tid != tid) { // something changed
2476 pDev->tid = tid;
2477 memcpy(&d->lct_data, &lct->lct_entry[i], sizeof(i2o_lct_entry));
2478 if (pDev->pScsi_dev) {
2479 pDev->pScsi_dev->changed = TRUE;
2480 pDev->pScsi_dev->removable = TRUE;
2481 }
2482 }
2483 // Found it - mark it scanned
2484 pDev->state = DPTI_DEV_ONLINE;
2485 break;
2486 }
2487 pDev = pDev->next_lun;
2488 }
2489 }
2490 }
2491 for (pI2o_dev = pHba->devices; pI2o_dev; pI2o_dev = pI2o_dev->next) {
2492 pDev =(struct adpt_device*) pI2o_dev->owner;
2493 if(!pDev){
2494 continue;
2495 }
2496 // Drive offline drives that previously existed but could not be found
2497 // in the LCT table
2498 if (pDev->state & DPTI_DEV_UNSCANNED){
2499 pDev->state = DPTI_DEV_OFFLINE;
2500 printk(KERN_WARNING"%s: Device (%d,%d,%d) offline\n",pHba->name,pDev->scsi_channel,pDev->scsi_id,pDev->scsi_lun);
2501 if (pDev->pScsi_dev) {
2502 scsi_device_set_state(pDev->pScsi_dev, SDEV_OFFLINE);
2503 }
2504 }
2505 }
2506 return 0;
2507}
2508
2509static void adpt_fail_posted_scbs(adpt_hba* pHba)
2510{
2511 struct scsi_cmnd* cmd = NULL;
2512 struct scsi_device* d = NULL;
2513
2514 shost_for_each_device(d, pHba->host) {
2515 unsigned long flags;
2516 spin_lock_irqsave(&d->list_lock, flags);
2517 list_for_each_entry(cmd, &d->cmd_list, list) {
2518 if(cmd->serial_number == 0){
2519 continue;
2520 }
2521 cmd->result = (DID_OK << 16) | (QUEUE_FULL <<1);
2522 cmd->scsi_done(cmd);
2523 }
2524 spin_unlock_irqrestore(&d->list_lock, flags);
2525 }
2526}
2527
2528
2529/*============================================================================
2530 * Routines from i2o subsystem
2531 *============================================================================
2532 */
2533
2534
2535
2536/*
2537 * Bring an I2O controller into HOLD state. See the spec.
2538 */
2539static int adpt_i2o_activate_hba(adpt_hba* pHba)
2540{
2541 int rcode;
2542
2543 if(pHba->initialized ) {
2544 if (adpt_i2o_status_get(pHba) < 0) {
2545 if((rcode = adpt_i2o_reset_hba(pHba)) != 0){
2546 printk(KERN_WARNING"%s: Could NOT reset.\n", pHba->name);
2547 return rcode;
2548 }
2549 if (adpt_i2o_status_get(pHba) < 0) {
2550 printk(KERN_INFO "HBA not responding.\n");
2551 return -1;
2552 }
2553 }
2554
2555 if(pHba->status_block->iop_state == ADAPTER_STATE_FAULTED) {
2556 printk(KERN_CRIT "%s: hardware fault\n", pHba->name);
2557 return -1;
2558 }
2559
2560 if (pHba->status_block->iop_state == ADAPTER_STATE_READY ||
2561 pHba->status_block->iop_state == ADAPTER_STATE_OPERATIONAL ||
2562 pHba->status_block->iop_state == ADAPTER_STATE_HOLD ||
2563 pHba->status_block->iop_state == ADAPTER_STATE_FAILED) {
2564 adpt_i2o_reset_hba(pHba);
2565 if (adpt_i2o_status_get(pHba) < 0 || pHba->status_block->iop_state != ADAPTER_STATE_RESET) {
2566 printk(KERN_ERR "%s: Failed to initialize.\n", pHba->name);
2567 return -1;
2568 }
2569 }
2570 } else {
2571 if((rcode = adpt_i2o_reset_hba(pHba)) != 0){
2572 printk(KERN_WARNING"%s: Could NOT reset.\n", pHba->name);
2573 return rcode;
2574 }
2575
2576 }
2577
2578 if (adpt_i2o_init_outbound_q(pHba) < 0) {
2579 return -1;
2580 }
2581
2582 /* In HOLD state */
2583
2584 if (adpt_i2o_hrt_get(pHba) < 0) {
2585 return -1;
2586 }
2587
2588 return 0;
2589}
2590
2591/*
2592 * Bring a controller online into OPERATIONAL state.
2593 */
2594
2595static int adpt_i2o_online_hba(adpt_hba* pHba)
2596{
2597 if (adpt_i2o_systab_send(pHba) < 0) {
2598 adpt_i2o_delete_hba(pHba);
2599 return -1;
2600 }
2601 /* In READY state */
2602
2603 if (adpt_i2o_enable_hba(pHba) < 0) {
2604 adpt_i2o_delete_hba(pHba);
2605 return -1;
2606 }
2607
2608 /* In OPERATIONAL state */
2609 return 0;
2610}
2611
2612static s32 adpt_send_nop(adpt_hba*pHba,u32 m)
2613{
2614 u32 __iomem *msg;
2615 ulong timeout = jiffies + 5*HZ;
2616
2617 while(m == EMPTY_QUEUE){
2618 rmb();
2619 m = readl(pHba->post_port);
2620 if(m != EMPTY_QUEUE){
2621 break;
2622 }
2623 if(time_after(jiffies,timeout)){
2624 printk(KERN_ERR "%s: Timeout waiting for message frame!\n",pHba->name);
2625 return 2;
2626 }
Nishanth Aravamudana9a30472005-11-07 01:01:20 -08002627 schedule_timeout_uninterruptible(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002628 }
2629 msg = (u32 __iomem *)(pHba->msg_addr_virt + m);
2630 writel( THREE_WORD_MSG_SIZE | SGL_OFFSET_0,&msg[0]);
2631 writel( I2O_CMD_UTIL_NOP << 24 | HOST_TID << 12 | 0,&msg[1]);
2632 writel( 0,&msg[2]);
2633 wmb();
2634
2635 writel(m, pHba->post_port);
2636 wmb();
2637 return 0;
2638}
2639
2640static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba)
2641{
2642 u8 *status;
2643 u32 __iomem *msg = NULL;
2644 int i;
2645 ulong timeout = jiffies + TMOUT_INITOUTBOUND*HZ;
2646 u32* ptr;
2647 u32 outbound_frame; // This had to be a 32 bit address
2648 u32 m;
2649
2650 do {
2651 rmb();
2652 m = readl(pHba->post_port);
2653 if (m != EMPTY_QUEUE) {
2654 break;
2655 }
2656
2657 if(time_after(jiffies,timeout)){
2658 printk(KERN_WARNING"%s: Timeout waiting for message frame\n",pHba->name);
2659 return -ETIMEDOUT;
2660 }
Nishanth Aravamudana9a30472005-11-07 01:01:20 -08002661 schedule_timeout_uninterruptible(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002662 } while(m == EMPTY_QUEUE);
2663
2664 msg=(u32 __iomem *)(pHba->msg_addr_virt+m);
2665
Mariusz Kozlowskibbfbbbc2007-08-11 10:13:24 +02002666 status = kzalloc(4, GFP_KERNEL|ADDR32);
2667 if (!status) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002668 adpt_send_nop(pHba, m);
2669 printk(KERN_WARNING"%s: IOP reset failed - no free memory.\n",
2670 pHba->name);
2671 return -ENOMEM;
2672 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002673
2674 writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]);
2675 writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]);
2676 writel(0, &msg[2]);
2677 writel(0x0106, &msg[3]); /* Transaction context */
2678 writel(4096, &msg[4]); /* Host page frame size */
2679 writel((REPLY_FRAME_SIZE)<<16|0x80, &msg[5]); /* Outbound msg frame size and Initcode */
2680 writel(0xD0000004, &msg[6]); /* Simple SG LE, EOB */
2681 writel(virt_to_bus(status), &msg[7]);
2682
2683 writel(m, pHba->post_port);
2684 wmb();
2685
2686 // Wait for the reply status to come back
2687 do {
2688 if (*status) {
2689 if (*status != 0x01 /*I2O_EXEC_OUTBOUND_INIT_IN_PROGRESS*/) {
2690 break;
2691 }
2692 }
2693 rmb();
2694 if(time_after(jiffies,timeout)){
2695 printk(KERN_WARNING"%s: Timeout Initializing\n",pHba->name);
2696 return -ETIMEDOUT;
2697 }
Nishanth Aravamudana9a30472005-11-07 01:01:20 -08002698 schedule_timeout_uninterruptible(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002699 } while (1);
2700
2701 // If the command was successful, fill the fifo with our reply
2702 // message packets
2703 if(*status != 0x04 /*I2O_EXEC_OUTBOUND_INIT_COMPLETE*/) {
Jesper Juhlc9475cb2005-11-07 01:01:26 -08002704 kfree(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002705 return -2;
2706 }
Jesper Juhlc9475cb2005-11-07 01:01:26 -08002707 kfree(status);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002708
Jesper Juhlc9475cb2005-11-07 01:01:26 -08002709 kfree(pHba->reply_pool);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002710
Mariusz Kozlowskibbfbbbc2007-08-11 10:13:24 +02002711 pHba->reply_pool = kzalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32);
2712 if (!pHba->reply_pool) {
2713 printk(KERN_ERR "%s: Could not allocate reply pool\n", pHba->name);
2714 return -ENOMEM;
Linus Torvalds1da177e2005-04-16 15:20:36 -07002715 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002716
2717 ptr = pHba->reply_pool;
2718 for(i = 0; i < pHba->reply_fifo_size; i++) {
2719 outbound_frame = (u32)virt_to_bus(ptr);
2720 writel(outbound_frame, pHba->reply_port);
2721 wmb();
2722 ptr += REPLY_FRAME_SIZE;
2723 }
2724 adpt_i2o_status_get(pHba);
2725 return 0;
2726}
2727
2728
2729/*
2730 * I2O System Table. Contains information about
2731 * all the IOPs in the system. Used to inform IOPs
2732 * about each other's existence.
2733 *
2734 * sys_tbl_ver is the CurrentChangeIndicator that is
2735 * used by IOPs to track changes.
2736 */
2737
2738
2739
2740static s32 adpt_i2o_status_get(adpt_hba* pHba)
2741{
2742 ulong timeout;
2743 u32 m;
2744 u32 __iomem *msg;
2745 u8 *status_block=NULL;
2746 ulong status_block_bus;
2747
2748 if(pHba->status_block == NULL) {
2749 pHba->status_block = (i2o_status_block*)
2750 kmalloc(sizeof(i2o_status_block),GFP_KERNEL|ADDR32);
2751 if(pHba->status_block == NULL) {
2752 printk(KERN_ERR
2753 "dpti%d: Get Status Block failed; Out of memory. \n",
2754 pHba->unit);
2755 return -ENOMEM;
2756 }
2757 }
2758 memset(pHba->status_block, 0, sizeof(i2o_status_block));
2759 status_block = (u8*)(pHba->status_block);
2760 status_block_bus = virt_to_bus(pHba->status_block);
2761 timeout = jiffies+TMOUT_GETSTATUS*HZ;
2762 do {
2763 rmb();
2764 m = readl(pHba->post_port);
2765 if (m != EMPTY_QUEUE) {
2766 break;
2767 }
2768 if(time_after(jiffies,timeout)){
2769 printk(KERN_ERR "%s: Timeout waiting for message !\n",
2770 pHba->name);
2771 return -ETIMEDOUT;
2772 }
Nishanth Aravamudana9a30472005-11-07 01:01:20 -08002773 schedule_timeout_uninterruptible(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002774 } while(m==EMPTY_QUEUE);
2775
2776
2777 msg=(u32 __iomem *)(pHba->msg_addr_virt+m);
2778
2779 writel(NINE_WORD_MSG_SIZE|SGL_OFFSET_0, &msg[0]);
2780 writel(I2O_CMD_STATUS_GET<<24|HOST_TID<<12|ADAPTER_TID, &msg[1]);
2781 writel(1, &msg[2]);
2782 writel(0, &msg[3]);
2783 writel(0, &msg[4]);
2784 writel(0, &msg[5]);
2785 writel(((u32)status_block_bus)&0xffffffff, &msg[6]);
2786 writel(0, &msg[7]);
2787 writel(sizeof(i2o_status_block), &msg[8]); // 88 bytes
2788
2789 //post message
2790 writel(m, pHba->post_port);
2791 wmb();
2792
2793 while(status_block[87]!=0xff){
2794 if(time_after(jiffies,timeout)){
2795 printk(KERN_ERR"dpti%d: Get status timeout.\n",
2796 pHba->unit);
2797 return -ETIMEDOUT;
2798 }
2799 rmb();
Nishanth Aravamudana9a30472005-11-07 01:01:20 -08002800 schedule_timeout_uninterruptible(1);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002801 }
2802
2803 // Set up our number of outbound and inbound messages
2804 pHba->post_fifo_size = pHba->status_block->max_inbound_frames;
2805 if (pHba->post_fifo_size > MAX_TO_IOP_MESSAGES) {
2806 pHba->post_fifo_size = MAX_TO_IOP_MESSAGES;
2807 }
2808
2809 pHba->reply_fifo_size = pHba->status_block->max_outbound_frames;
2810 if (pHba->reply_fifo_size > MAX_FROM_IOP_MESSAGES) {
2811 pHba->reply_fifo_size = MAX_FROM_IOP_MESSAGES;
2812 }
2813
2814 // Calculate the Scatter Gather list size
2815 pHba->sg_tablesize = (pHba->status_block->inbound_frame_size * 4 -40)/ sizeof(struct sg_simple_element);
2816 if (pHba->sg_tablesize > SG_LIST_ELEMENTS) {
2817 pHba->sg_tablesize = SG_LIST_ELEMENTS;
2818 }
2819
2820
2821#ifdef DEBUG
2822 printk("dpti%d: State = ",pHba->unit);
2823 switch(pHba->status_block->iop_state) {
2824 case 0x01:
2825 printk("INIT\n");
2826 break;
2827 case 0x02:
2828 printk("RESET\n");
2829 break;
2830 case 0x04:
2831 printk("HOLD\n");
2832 break;
2833 case 0x05:
2834 printk("READY\n");
2835 break;
2836 case 0x08:
2837 printk("OPERATIONAL\n");
2838 break;
2839 case 0x10:
2840 printk("FAILED\n");
2841 break;
2842 case 0x11:
2843 printk("FAULTED\n");
2844 break;
2845 default:
2846 printk("%x (unknown!!)\n",pHba->status_block->iop_state);
2847 }
2848#endif
2849 return 0;
2850}
2851
2852/*
2853 * Get the IOP's Logical Configuration Table
2854 */
2855static int adpt_i2o_lct_get(adpt_hba* pHba)
2856{
2857 u32 msg[8];
2858 int ret;
2859 u32 buf[16];
2860
2861 if ((pHba->lct_size == 0) || (pHba->lct == NULL)){
2862 pHba->lct_size = pHba->status_block->expected_lct_size;
2863 }
2864 do {
2865 if (pHba->lct == NULL) {
2866 pHba->lct = kmalloc(pHba->lct_size, GFP_KERNEL|ADDR32);
2867 if(pHba->lct == NULL) {
2868 printk(KERN_CRIT "%s: Lct Get failed. Out of memory.\n",
2869 pHba->name);
2870 return -ENOMEM;
2871 }
2872 }
2873 memset(pHba->lct, 0, pHba->lct_size);
2874
2875 msg[0] = EIGHT_WORD_MSG_SIZE|SGL_OFFSET_6;
2876 msg[1] = I2O_CMD_LCT_NOTIFY<<24 | HOST_TID<<12 | ADAPTER_TID;
2877 msg[2] = 0;
2878 msg[3] = 0;
2879 msg[4] = 0xFFFFFFFF; /* All devices */
2880 msg[5] = 0x00000000; /* Report now */
2881 msg[6] = 0xD0000000|pHba->lct_size;
2882 msg[7] = virt_to_bus(pHba->lct);
2883
2884 if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 360))) {
2885 printk(KERN_ERR "%s: LCT Get failed (status=%#10x.\n",
2886 pHba->name, ret);
2887 printk(KERN_ERR"Adaptec: Error Reading Hardware.\n");
2888 return ret;
2889 }
2890
2891 if ((pHba->lct->table_size << 2) > pHba->lct_size) {
2892 pHba->lct_size = pHba->lct->table_size << 2;
2893 kfree(pHba->lct);
2894 pHba->lct = NULL;
2895 }
2896 } while (pHba->lct == NULL);
2897
2898 PDEBUG("%s: Hardware resource table read.\n", pHba->name);
2899
2900
2901 // I2O_DPT_EXEC_IOP_BUFFERS_GROUP_NO;
2902 if(adpt_i2o_query_scalar(pHba, 0 , 0x8000, -1, buf, sizeof(buf))>=0) {
2903 pHba->FwDebugBufferSize = buf[1];
2904 pHba->FwDebugBuffer_P = pHba->base_addr_virt + buf[0];
2905 pHba->FwDebugFlags_P = pHba->FwDebugBuffer_P + FW_DEBUG_FLAGS_OFFSET;
2906 pHba->FwDebugBLEDvalue_P = pHba->FwDebugBuffer_P + FW_DEBUG_BLED_OFFSET;
2907 pHba->FwDebugBLEDflag_P = pHba->FwDebugBLEDvalue_P + 1;
2908 pHba->FwDebugStrLength_P = pHba->FwDebugBuffer_P + FW_DEBUG_STR_LENGTH_OFFSET;
2909 pHba->FwDebugBuffer_P += buf[2];
2910 pHba->FwDebugFlags = 0;
2911 }
2912
2913 return 0;
2914}
2915
2916static int adpt_i2o_build_sys_table(void)
2917{
2918 adpt_hba* pHba = NULL;
2919 int count = 0;
2920
2921 sys_tbl_len = sizeof(struct i2o_sys_tbl) + // Header + IOPs
2922 (hba_count) * sizeof(struct i2o_sys_tbl_entry);
2923
Jesper Juhlc9475cb2005-11-07 01:01:26 -08002924 kfree(sys_tbl);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002925
Mariusz Kozlowskibbfbbbc2007-08-11 10:13:24 +02002926 sys_tbl = kzalloc(sys_tbl_len, GFP_KERNEL|ADDR32);
2927 if (!sys_tbl) {
Linus Torvalds1da177e2005-04-16 15:20:36 -07002928 printk(KERN_WARNING "SysTab Set failed. Out of memory.\n");
2929 return -ENOMEM;
2930 }
Linus Torvalds1da177e2005-04-16 15:20:36 -07002931
2932 sys_tbl->num_entries = hba_count;
2933 sys_tbl->version = I2OVERSION;
2934 sys_tbl->change_ind = sys_tbl_ind++;
2935
2936 for(pHba = hba_chain; pHba; pHba = pHba->next) {
2937 // Get updated Status Block so we have the latest information
2938 if (adpt_i2o_status_get(pHba)) {
2939 sys_tbl->num_entries--;
2940 continue; // try next one
2941 }
2942
2943 sys_tbl->iops[count].org_id = pHba->status_block->org_id;
2944 sys_tbl->iops[count].iop_id = pHba->unit + 2;
2945 sys_tbl->iops[count].seg_num = 0;
2946 sys_tbl->iops[count].i2o_version = pHba->status_block->i2o_version;
2947 sys_tbl->iops[count].iop_state = pHba->status_block->iop_state;
2948 sys_tbl->iops[count].msg_type = pHba->status_block->msg_type;
2949 sys_tbl->iops[count].frame_size = pHba->status_block->inbound_frame_size;
2950 sys_tbl->iops[count].last_changed = sys_tbl_ind - 1; // ??
2951 sys_tbl->iops[count].iop_capabilities = pHba->status_block->iop_capabilities;
Benoit Boissinot 1c2fb3f2005-04-25 19:46:48 -07002952 sys_tbl->iops[count].inbound_low = (u32)virt_to_bus(pHba->post_port);
2953 sys_tbl->iops[count].inbound_high = (u32)((u64)virt_to_bus(pHba->post_port)>>32);
Linus Torvalds1da177e2005-04-16 15:20:36 -07002954
2955 count++;
2956 }
2957
2958#ifdef DEBUG
2959{
2960 u32 *table = (u32*)sys_tbl;
2961 printk(KERN_DEBUG"sys_tbl_len=%d in 32bit words\n",(sys_tbl_len >>2));
2962 for(count = 0; count < (sys_tbl_len >>2); count++) {
2963 printk(KERN_INFO "sys_tbl[%d] = %0#10x\n",
2964 count, table[count]);
2965 }
2966}
2967#endif
2968
2969 return 0;
2970}
2971
2972
2973/*
2974 * Dump the information block associated with a given unit (TID)
2975 */
2976
2977static void adpt_i2o_report_hba_unit(adpt_hba* pHba, struct i2o_device *d)
2978{
2979 char buf[64];
2980 int unit = d->lct_data.tid;
2981
2982 printk(KERN_INFO "TID %3.3d ", unit);
2983
2984 if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 3, buf, 16)>=0)
2985 {
2986 buf[16]=0;
2987 printk(" Vendor: %-12.12s", buf);
2988 }
2989 if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 4, buf, 16)>=0)
2990 {
2991 buf[16]=0;
2992 printk(" Device: %-12.12s", buf);
2993 }
2994 if(adpt_i2o_query_scalar(pHba, unit, 0xF100, 6, buf, 8)>=0)
2995 {
2996 buf[8]=0;
2997 printk(" Rev: %-12.12s\n", buf);
2998 }
2999#ifdef DEBUG
3000 printk(KERN_INFO "\tClass: %.21s\n", adpt_i2o_get_class_name(d->lct_data.class_id));
3001 printk(KERN_INFO "\tSubclass: 0x%04X\n", d->lct_data.sub_class);
3002 printk(KERN_INFO "\tFlags: ");
3003
3004 if(d->lct_data.device_flags&(1<<0))
3005 printk("C"); // ConfigDialog requested
3006 if(d->lct_data.device_flags&(1<<1))
3007 printk("U"); // Multi-user capable
3008 if(!(d->lct_data.device_flags&(1<<4)))
3009 printk("P"); // Peer service enabled!
3010 if(!(d->lct_data.device_flags&(1<<5)))
3011 printk("M"); // Mgmt service enabled!
3012 printk("\n");
3013#endif
3014}
3015
3016#ifdef DEBUG
3017/*
3018 * Do i2o class name lookup
3019 */
3020static const char *adpt_i2o_get_class_name(int class)
3021{
3022 int idx = 16;
3023 static char *i2o_class_name[] = {
3024 "Executive",
3025 "Device Driver Module",
3026 "Block Device",
3027 "Tape Device",
3028 "LAN Interface",
3029 "WAN Interface",
3030 "Fibre Channel Port",
3031 "Fibre Channel Device",
3032 "SCSI Device",
3033 "ATE Port",
3034 "ATE Device",
3035 "Floppy Controller",
3036 "Floppy Device",
3037 "Secondary Bus Port",
3038 "Peer Transport Agent",
3039 "Peer Transport",
3040 "Unknown"
3041 };
3042
3043 switch(class&0xFFF) {
3044 case I2O_CLASS_EXECUTIVE:
3045 idx = 0; break;
3046 case I2O_CLASS_DDM:
3047 idx = 1; break;
3048 case I2O_CLASS_RANDOM_BLOCK_STORAGE:
3049 idx = 2; break;
3050 case I2O_CLASS_SEQUENTIAL_STORAGE:
3051 idx = 3; break;
3052 case I2O_CLASS_LAN:
3053 idx = 4; break;
3054 case I2O_CLASS_WAN:
3055 idx = 5; break;
3056 case I2O_CLASS_FIBRE_CHANNEL_PORT:
3057 idx = 6; break;
3058 case I2O_CLASS_FIBRE_CHANNEL_PERIPHERAL:
3059 idx = 7; break;
3060 case I2O_CLASS_SCSI_PERIPHERAL:
3061 idx = 8; break;
3062 case I2O_CLASS_ATE_PORT:
3063 idx = 9; break;
3064 case I2O_CLASS_ATE_PERIPHERAL:
3065 idx = 10; break;
3066 case I2O_CLASS_FLOPPY_CONTROLLER:
3067 idx = 11; break;
3068 case I2O_CLASS_FLOPPY_DEVICE:
3069 idx = 12; break;
3070 case I2O_CLASS_BUS_ADAPTER_PORT:
3071 idx = 13; break;
3072 case I2O_CLASS_PEER_TRANSPORT_AGENT:
3073 idx = 14; break;
3074 case I2O_CLASS_PEER_TRANSPORT:
3075 idx = 15; break;
3076 }
3077 return i2o_class_name[idx];
3078}
3079#endif
3080
3081
3082static s32 adpt_i2o_hrt_get(adpt_hba* pHba)
3083{
3084 u32 msg[6];
3085 int ret, size = sizeof(i2o_hrt);
3086
3087 do {
3088 if (pHba->hrt == NULL) {
3089 pHba->hrt=kmalloc(size, GFP_KERNEL|ADDR32);
3090 if (pHba->hrt == NULL) {
3091 printk(KERN_CRIT "%s: Hrt Get failed; Out of memory.\n", pHba->name);
3092 return -ENOMEM;
3093 }
3094 }
3095
3096 msg[0]= SIX_WORD_MSG_SIZE| SGL_OFFSET_4;
3097 msg[1]= I2O_CMD_HRT_GET<<24 | HOST_TID<<12 | ADAPTER_TID;
3098 msg[2]= 0;
3099 msg[3]= 0;
3100 msg[4]= (0xD0000000 | size); /* Simple transaction */
3101 msg[5]= virt_to_bus(pHba->hrt); /* Dump it here */
3102
3103 if ((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg),20))) {
3104 printk(KERN_ERR "%s: Unable to get HRT (status=%#10x)\n", pHba->name, ret);
3105 return ret;
3106 }
3107
3108 if (pHba->hrt->num_entries * pHba->hrt->entry_len << 2 > size) {
3109 size = pHba->hrt->num_entries * pHba->hrt->entry_len << 2;
3110 kfree(pHba->hrt);
3111 pHba->hrt = NULL;
3112 }
3113 } while(pHba->hrt == NULL);
3114 return 0;
3115}
3116
3117/*
3118 * Query one scalar group value or a whole scalar group.
3119 */
3120static int adpt_i2o_query_scalar(adpt_hba* pHba, int tid,
3121 int group, int field, void *buf, int buflen)
3122{
3123 u16 opblk[] = { 1, 0, I2O_PARAMS_FIELD_GET, group, 1, field };
3124 u8 *resblk;
3125
3126 int size;
3127
3128 /* 8 bytes for header */
3129 resblk = kmalloc(sizeof(u8) * (8+buflen), GFP_KERNEL|ADDR32);
3130 if (resblk == NULL) {
3131 printk(KERN_CRIT "%s: query scalar failed; Out of memory.\n", pHba->name);
3132 return -ENOMEM;
3133 }
3134
3135 if (field == -1) /* whole group */
3136 opblk[4] = -1;
3137
3138 size = adpt_i2o_issue_params(I2O_CMD_UTIL_PARAMS_GET, pHba, tid,
3139 opblk, sizeof(opblk), resblk, sizeof(u8)*(8+buflen));
3140 if (size == -ETIME) {
3141 printk(KERN_WARNING "%s: issue params failed; Timed out.\n", pHba->name);
3142 return -ETIME;
3143 } else if (size == -EINTR) {
3144 printk(KERN_WARNING "%s: issue params failed; Interrupted.\n", pHba->name);
3145 return -EINTR;
3146 }
3147
3148 memcpy(buf, resblk+8, buflen); /* cut off header */
3149
3150 kfree(resblk);
3151 if (size < 0)
3152 return size;
3153
3154 return buflen;
3155}
3156
3157
3158/* Issue UTIL_PARAMS_GET or UTIL_PARAMS_SET
3159 *
3160 * This function can be used for all UtilParamsGet/Set operations.
3161 * The OperationBlock is given in opblk-buffer,
3162 * and results are returned in resblk-buffer.
3163 * Note that the minimum sized resblk is 8 bytes and contains
3164 * ResultCount, ErrorInfoSize, BlockStatus and BlockSize.
3165 */
3166static int adpt_i2o_issue_params(int cmd, adpt_hba* pHba, int tid,
3167 void *opblk, int oplen, void *resblk, int reslen)
3168{
3169 u32 msg[9];
3170 u32 *res = (u32 *)resblk;
3171 int wait_status;
3172
3173 msg[0] = NINE_WORD_MSG_SIZE | SGL_OFFSET_5;
3174 msg[1] = cmd << 24 | HOST_TID << 12 | tid;
3175 msg[2] = 0;
3176 msg[3] = 0;
3177 msg[4] = 0;
3178 msg[5] = 0x54000000 | oplen; /* OperationBlock */
3179 msg[6] = virt_to_bus(opblk);
3180 msg[7] = 0xD0000000 | reslen; /* ResultBlock */
3181 msg[8] = virt_to_bus(resblk);
3182
3183 if ((wait_status = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 20))) {
3184 printk("adpt_i2o_issue_params: post_wait failed (%p)\n", resblk);
3185 return wait_status; /* -DetailedStatus */
3186 }
3187
3188 if (res[1]&0x00FF0000) { /* BlockStatus != SUCCESS */
3189 printk(KERN_WARNING "%s: %s - Error:\n ErrorInfoSize = 0x%02x, "
3190 "BlockStatus = 0x%02x, BlockSize = 0x%04x\n",
3191 pHba->name,
3192 (cmd == I2O_CMD_UTIL_PARAMS_SET) ? "PARAMS_SET"
3193 : "PARAMS_GET",
3194 res[1]>>24, (res[1]>>16)&0xFF, res[1]&0xFFFF);
3195 return -((res[1] >> 16) & 0xFF); /* -BlockStatus */
3196 }
3197
3198 return 4 + ((res[1] & 0x0000FFFF) << 2); /* bytes used in resblk */
3199}
3200
3201
3202static s32 adpt_i2o_quiesce_hba(adpt_hba* pHba)
3203{
3204 u32 msg[4];
3205 int ret;
3206
3207 adpt_i2o_status_get(pHba);
3208
3209 /* SysQuiesce discarded if IOP not in READY or OPERATIONAL state */
3210
3211 if((pHba->status_block->iop_state != ADAPTER_STATE_READY) &&
3212 (pHba->status_block->iop_state != ADAPTER_STATE_OPERATIONAL)){
3213 return 0;
3214 }
3215
3216 msg[0] = FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
3217 msg[1] = I2O_CMD_SYS_QUIESCE<<24|HOST_TID<<12|ADAPTER_TID;
3218 msg[2] = 0;
3219 msg[3] = 0;
3220
3221 if((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 240))) {
3222 printk(KERN_INFO"dpti%d: Unable to quiesce (status=%#x).\n",
3223 pHba->unit, -ret);
3224 } else {
3225 printk(KERN_INFO"dpti%d: Quiesced.\n",pHba->unit);
3226 }
3227
3228 adpt_i2o_status_get(pHba);
3229 return ret;
3230}
3231
3232
3233/*
3234 * Enable IOP. Allows the IOP to resume external operations.
3235 */
3236static int adpt_i2o_enable_hba(adpt_hba* pHba)
3237{
3238 u32 msg[4];
3239 int ret;
3240
3241 adpt_i2o_status_get(pHba);
3242 if(!pHba->status_block){
3243 return -ENOMEM;
3244 }
3245 /* Enable only allowed on READY state */
3246 if(pHba->status_block->iop_state == ADAPTER_STATE_OPERATIONAL)
3247 return 0;
3248
3249 if(pHba->status_block->iop_state != ADAPTER_STATE_READY)
3250 return -EINVAL;
3251
3252 msg[0]=FOUR_WORD_MSG_SIZE|SGL_OFFSET_0;
3253 msg[1]=I2O_CMD_SYS_ENABLE<<24|HOST_TID<<12|ADAPTER_TID;
3254 msg[2]= 0;
3255 msg[3]= 0;
3256
3257 if ((ret = adpt_i2o_post_wait(pHba, msg, sizeof(msg), 240))) {
3258 printk(KERN_WARNING"%s: Could not enable (status=%#10x).\n",
3259 pHba->name, ret);
3260 } else {
3261 PDEBUG("%s: Enabled.\n", pHba->name);
3262 }
3263
3264 adpt_i2o_status_get(pHba);
3265 return ret;
3266}
3267
3268
3269static int adpt_i2o_systab_send(adpt_hba* pHba)
3270{
3271 u32 msg[12];
3272 int ret;
3273
3274 msg[0] = I2O_MESSAGE_SIZE(12) | SGL_OFFSET_6;
3275 msg[1] = I2O_CMD_SYS_TAB_SET<<24 | HOST_TID<<12 | ADAPTER_TID;
3276 msg[2] = 0;
3277 msg[3] = 0;
3278 msg[4] = (0<<16) | ((pHba->unit+2) << 12); /* Host 0 IOP ID (unit + 2) */
3279 msg[5] = 0; /* Segment 0 */
3280
3281 /*
3282 * Provide three SGL-elements:
3283 * System table (SysTab), Private memory space declaration and
3284 * Private i/o space declaration
3285 */
3286 msg[6] = 0x54000000 | sys_tbl_len;
3287 msg[7] = virt_to_phys(sys_tbl);
3288 msg[8] = 0x54000000 | 0;
3289 msg[9] = 0;
3290 msg[10] = 0xD4000000 | 0;
3291 msg[11] = 0;
3292
3293 if ((ret=adpt_i2o_post_wait(pHba, msg, sizeof(msg), 120))) {
3294 printk(KERN_INFO "%s: Unable to set SysTab (status=%#10x).\n",
3295 pHba->name, ret);
3296 }
3297#ifdef DEBUG
3298 else {
3299 PINFO("%s: SysTab set.\n", pHba->name);
3300 }
3301#endif
3302
3303 return ret;
3304 }
3305
3306
3307/*============================================================================
3308 *
3309 *============================================================================
3310 */
3311
3312
3313#ifdef UARTDELAY
3314
3315static static void adpt_delay(int millisec)
3316{
3317 int i;
3318 for (i = 0; i < millisec; i++) {
3319 udelay(1000); /* delay for one millisecond */
3320 }
3321}
3322
3323#endif
3324
Andrew Morton24601bb2007-12-10 15:49:20 -08003325static struct scsi_host_template driver_template = {
Linus Torvalds1da177e2005-04-16 15:20:36 -07003326 .name = "dpt_i2o",
3327 .proc_name = "dpt_i2o",
3328 .proc_info = adpt_proc_info,
Andrew Morton24601bb2007-12-10 15:49:20 -08003329 .detect = adpt_detect,
3330 .release = adpt_release,
Linus Torvalds1da177e2005-04-16 15:20:36 -07003331 .info = adpt_info,
3332 .queuecommand = adpt_queue,
3333 .eh_abort_handler = adpt_abort,
3334 .eh_device_reset_handler = adpt_device_reset,
3335 .eh_bus_reset_handler = adpt_bus_reset,
3336 .eh_host_reset_handler = adpt_reset,
3337 .bios_param = adpt_bios_param,
3338 .slave_configure = adpt_slave_configure,
3339 .can_queue = MAX_TO_IOP_MESSAGES,
3340 .this_id = 7,
3341 .cmd_per_lun = 1,
3342 .use_clustering = ENABLE_CLUSTERING,
3343};
Andrew Morton24601bb2007-12-10 15:49:20 -08003344#include "scsi_module.c"
Linus Torvalds1da177e2005-04-16 15:20:36 -07003345MODULE_LICENSE("GPL");