1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164#include <asm/io.h>
165#include <asm/byteorder.h>
166#include <asm/page.h>
167#include <linux/stddef.h>
168#include <linux/version.h>
169#include <linux/string.h>
170#include <linux/errno.h>
171#include <linux/kernel.h>
172#include <linux/ioport.h>
173#include <linux/slab.h>
174#include <linux/delay.h>
175#include <linux/pci.h>
176#include <linux/proc_fs.h>
177#include <linux/reboot.h>
178#include <linux/interrupt.h>
179
180#include <linux/blkdev.h>
181#include <linux/types.h>
182#include <linux/dma-mapping.h>
183
184#include <scsi/sg.h>
185#include "scsi.h"
186#include <scsi/scsi_host.h>
187
188#include "ips.h"
189
190#include <linux/module.h>
191
192#include <linux/stat.h>
193
194#include <linux/spinlock.h>
195#include <linux/init.h>
196
197#include <linux/smp.h>
198
199#ifdef MODULE
200static char *ips = NULL;
201module_param(ips, charp, 0);
202#endif
203
204
205
206
207#define IPS_VERSION_HIGH IPS_VER_MAJOR_STRING "." IPS_VER_MINOR_STRING
208#define IPS_VERSION_LOW "." IPS_VER_BUILD_STRING " "
209
210#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
211#warning "This driver has only been tested on the x86/ia64/x86_64 platforms"
212#endif
213
214#define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || \
215 DMA_NONE == scb->scsi_cmd->sc_data_direction) ? \
216 PCI_DMA_BIDIRECTIONAL : \
217 scb->scsi_cmd->sc_data_direction)
218
219#ifdef IPS_DEBUG
220#define METHOD_TRACE(s, i) if (ips_debug >= (i+10)) printk(KERN_NOTICE s "\n");
221#define DEBUG(i, s) if (ips_debug >= i) printk(KERN_NOTICE s "\n");
222#define DEBUG_VAR(i, s, v...) if (ips_debug >= i) printk(KERN_NOTICE s "\n", v);
223#else
224#define METHOD_TRACE(s, i)
225#define DEBUG(i, s)
226#define DEBUG_VAR(i, s, v...)
227#endif
228
229
230
231
232static int ips_detect(struct scsi_host_template *);
233static int ips_release(struct Scsi_Host *);
234static int ips_eh_abort(struct scsi_cmnd *);
235static int ips_eh_reset(struct scsi_cmnd *);
236static int ips_queue(struct scsi_cmnd *, void (*)(struct scsi_cmnd *));
237static const char *ips_info(struct Scsi_Host *);
238static irqreturn_t do_ipsintr(int, void *);
239static int ips_hainit(ips_ha_t *);
240static int ips_map_status(ips_ha_t *, ips_scb_t *, ips_stat_t *);
241static int ips_send_wait(ips_ha_t *, ips_scb_t *, int, int);
242static int ips_send_cmd(ips_ha_t *, ips_scb_t *);
243static int ips_online(ips_ha_t *, ips_scb_t *);
244static int ips_inquiry(ips_ha_t *, ips_scb_t *);
245static int ips_rdcap(ips_ha_t *, ips_scb_t *);
246static int ips_msense(ips_ha_t *, ips_scb_t *);
247static int ips_reqsen(ips_ha_t *, ips_scb_t *);
248static int ips_deallocatescbs(ips_ha_t *, int);
249static int ips_allocatescbs(ips_ha_t *);
250static int ips_reset_copperhead(ips_ha_t *);
251static int ips_reset_copperhead_memio(ips_ha_t *);
252static int ips_reset_morpheus(ips_ha_t *);
253static int ips_issue_copperhead(ips_ha_t *, ips_scb_t *);
254static int ips_issue_copperhead_memio(ips_ha_t *, ips_scb_t *);
255static int ips_issue_i2o(ips_ha_t *, ips_scb_t *);
256static int ips_issue_i2o_memio(ips_ha_t *, ips_scb_t *);
257static int ips_isintr_copperhead(ips_ha_t *);
258static int ips_isintr_copperhead_memio(ips_ha_t *);
259static int ips_isintr_morpheus(ips_ha_t *);
260static int ips_wait(ips_ha_t *, int, int);
261static int ips_write_driver_status(ips_ha_t *, int);
262static int ips_read_adapter_status(ips_ha_t *, int);
263static int ips_read_subsystem_parameters(ips_ha_t *, int);
264static int ips_read_config(ips_ha_t *, int);
265static int ips_clear_adapter(ips_ha_t *, int);
266static int ips_readwrite_page5(ips_ha_t *, int, int);
267static int ips_init_copperhead(ips_ha_t *);
268static int ips_init_copperhead_memio(ips_ha_t *);
269static int ips_init_morpheus(ips_ha_t *);
270static int ips_isinit_copperhead(ips_ha_t *);
271static int ips_isinit_copperhead_memio(ips_ha_t *);
272static int ips_isinit_morpheus(ips_ha_t *);
273static int ips_erase_bios(ips_ha_t *);
274static int ips_program_bios(ips_ha_t *, char *, uint32_t, uint32_t);
275static int ips_verify_bios(ips_ha_t *, char *, uint32_t, uint32_t);
276static int ips_erase_bios_memio(ips_ha_t *);
277static int ips_program_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
278static int ips_verify_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
279static int ips_flash_copperhead(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
280static int ips_flash_bios(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
281static int ips_flash_firmware(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
282static void ips_free_flash_copperhead(ips_ha_t * ha);
283static void ips_get_bios_version(ips_ha_t *, int);
284static void ips_identify_controller(ips_ha_t *);
285static void ips_chkstatus(ips_ha_t *, IPS_STATUS *);
286static void ips_enable_int_copperhead(ips_ha_t *);
287static void ips_enable_int_copperhead_memio(ips_ha_t *);
288static void ips_enable_int_morpheus(ips_ha_t *);
289static int ips_intr_copperhead(ips_ha_t *);
290static int ips_intr_morpheus(ips_ha_t *);
291static void ips_next(ips_ha_t *, int);
292static void ipsintr_blocking(ips_ha_t *, struct ips_scb *);
293static void ipsintr_done(ips_ha_t *, struct ips_scb *);
294static void ips_done(ips_ha_t *, ips_scb_t *);
295static void ips_free(ips_ha_t *);
296static void ips_init_scb(ips_ha_t *, ips_scb_t *);
297static void ips_freescb(ips_ha_t *, ips_scb_t *);
298static void ips_setup_funclist(ips_ha_t *);
299static void ips_statinit(ips_ha_t *);
300static void ips_statinit_memio(ips_ha_t *);
301static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time_t);
302static void ips_ffdc_reset(ips_ha_t *, int);
303static void ips_ffdc_time(ips_ha_t *);
304static uint32_t ips_statupd_copperhead(ips_ha_t *);
305static uint32_t ips_statupd_copperhead_memio(ips_ha_t *);
306static uint32_t ips_statupd_morpheus(ips_ha_t *);
307static ips_scb_t *ips_getscb(ips_ha_t *);
308static void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *);
309static void ips_putq_wait_tail(ips_wait_queue_t *, struct scsi_cmnd *);
310static void ips_putq_copp_tail(ips_copp_queue_t *,
311 ips_copp_wait_item_t *);
312static ips_scb_t *ips_removeq_scb_head(ips_scb_queue_t *);
313static ips_scb_t *ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *);
314static struct scsi_cmnd *ips_removeq_wait_head(ips_wait_queue_t *);
315static struct scsi_cmnd *ips_removeq_wait(ips_wait_queue_t *,
316 struct scsi_cmnd *);
317static ips_copp_wait_item_t *ips_removeq_copp(ips_copp_queue_t *,
318 ips_copp_wait_item_t *);
319static ips_copp_wait_item_t *ips_removeq_copp_head(ips_copp_queue_t *);
320
321static int ips_is_passthru(struct scsi_cmnd *);
322static int ips_make_passthru(ips_ha_t *, struct scsi_cmnd *, ips_scb_t *, int);
323static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
324static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *);
325static void ips_scmd_buf_write(struct scsi_cmnd * scmd, void *data,
326 unsigned int count);
327static void ips_scmd_buf_read(struct scsi_cmnd * scmd, void *data,
328 unsigned int count);
329
330static int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
331static int ips_host_info(ips_ha_t *, char *, off_t, int);
332static void copy_mem_info(IPS_INFOSTR *, char *, int);
333static int copy_info(IPS_INFOSTR *, char *, ...);
334static int ips_abort_init(ips_ha_t * ha, int index);
335static int ips_init_phase2(int index);
336
337static int ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr);
338static int ips_register_scsi(int index);
339
340static int ips_poll_for_flush_complete(ips_ha_t * ha);
341static void ips_flush_and_reset(ips_ha_t *ha);
342
343
344
345
346static const char ips_name[] = "ips";
347static struct Scsi_Host *ips_sh[IPS_MAX_ADAPTERS];
348static ips_ha_t *ips_ha[IPS_MAX_ADAPTERS];
349static unsigned int ips_next_controller;
350static unsigned int ips_num_controllers;
351static unsigned int ips_released_controllers;
352static int ips_hotplug;
353static int ips_cmd_timeout = 60;
354static int ips_reset_timeout = 60 * 5;
355static int ips_force_memio = 1;
356static int ips_force_i2o = 1;
357static int ips_ioctlsize = IPS_IOCTL_SIZE;
358static int ips_cd_boot;
359static char *ips_FlashData = NULL;
360static dma_addr_t ips_flashbusaddr;
361static long ips_FlashDataInUse;
362static uint32_t MaxLiteCmds = 32;
363static struct scsi_host_template ips_driver_template = {
364 .detect = ips_detect,
365 .release = ips_release,
366 .info = ips_info,
367 .queuecommand = ips_queue,
368 .eh_abort_handler = ips_eh_abort,
369 .eh_host_reset_handler = ips_eh_reset,
370 .proc_name = "ips",
371 .proc_info = ips_proc_info,
372 .slave_configure = ips_slave_configure,
373 .bios_param = ips_biosparam,
374 .this_id = -1,
375 .sg_tablesize = IPS_MAX_SG,
376 .cmd_per_lun = 3,
377 .use_clustering = ENABLE_CLUSTERING,
378};
379
380
381
382static struct pci_device_id ips_pci_table[] = {
383 { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
384 { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
385 { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
386 { 0, }
387};
388
389MODULE_DEVICE_TABLE( pci, ips_pci_table );
390
391static char ips_hot_plug_name[] = "ips";
392
393static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent);
394static void __devexit ips_remove_device(struct pci_dev *pci_dev);
395
396static struct pci_driver ips_pci_driver = {
397 .name = ips_hot_plug_name,
398 .id_table = ips_pci_table,
399 .probe = ips_insert_device,
400 .remove = __devexit_p(ips_remove_device),
401};
402
403
404
405
406
407static int ips_halt(struct notifier_block *nb, ulong event, void *buf);
408
409#define MAX_ADAPTER_NAME 15
410
411static char ips_adapter_name[][30] = {
412 "ServeRAID",
413 "ServeRAID II",
414 "ServeRAID on motherboard",
415 "ServeRAID on motherboard",
416 "ServeRAID 3H",
417 "ServeRAID 3L",
418 "ServeRAID 4H",
419 "ServeRAID 4M",
420 "ServeRAID 4L",
421 "ServeRAID 4Mx",
422 "ServeRAID 4Lx",
423 "ServeRAID 5i",
424 "ServeRAID 5i",
425 "ServeRAID 6M",
426 "ServeRAID 6i",
427 "ServeRAID 7t",
428 "ServeRAID 7k",
429 "ServeRAID 7M"
430};
431
432static struct notifier_block ips_notifier = {
433 ips_halt, NULL, 0
434};
435
436
437
438
439static char ips_command_direction[] = {
440 IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT,
441 IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK,
442 IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
443 IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
444 IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT,
445 IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
446 IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_IN,
447 IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
448 IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_UNK,
449 IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
450 IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE,
451 IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
452 IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT,
453 IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_NONE,
454 IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK,
455 IPS_DATA_NONE, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
456 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
457 IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
458 IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
459 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
460 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
461 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
462 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
463 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
464 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
465 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
466 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
467 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
468 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
469 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
470 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
471 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
472 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
473 IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_NONE,
474 IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_OUT,
475 IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_NONE,
476 IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN,
477 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
478 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
479 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
480 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
481 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
482 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
483 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
484 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
485 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
486 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_OUT,
487 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
488 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
489 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
490 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK
491};
492
493
494
495
496
497
498
499
500
501
502
503static int
504ips_setup(char *ips_str)
505{
506
507 int i;
508 char *key;
509 char *value;
510 IPS_OPTION options[] = {
511 {"noi2o", &ips_force_i2o, 0},
512 {"nommap", &ips_force_memio, 0},
513 {"ioctlsize", &ips_ioctlsize, IPS_IOCTL_SIZE},
514 {"cdboot", &ips_cd_boot, 0},
515 {"maxcmds", &MaxLiteCmds, 32},
516 };
517
518
519
520 while ((key = strsep(&ips_str, ",."))) {
521 if (!*key)
522 continue;
523 value = strchr(key, ':');
524 if (value)
525 *value++ = '\0';
526
527
528
529
530 for (i = 0; i < ARRAY_SIZE(options); i++) {
531 if (strnicmp
532 (key, options[i].option_name,
533 strlen(options[i].option_name)) == 0) {
534 if (value)
535 *options[i].option_flag =
536 simple_strtoul(value, NULL, 0);
537 else
538 *options[i].option_flag =
539 options[i].option_value;
540 break;
541 }
542 }
543 }
544
545 return (1);
546}
547
548__setup("ips=", ips_setup);
549
550
551
552
553
554
555
556
557
558
559
560
561static int
562ips_detect(struct scsi_host_template * SHT)
563{
564 int i;
565
566 METHOD_TRACE("ips_detect", 1);
567
568#ifdef MODULE
569 if (ips)
570 ips_setup(ips);
571#endif
572
573 for (i = 0; i < ips_num_controllers; i++) {
574 if (ips_register_scsi(i))
575 ips_free(ips_ha[i]);
576 ips_released_controllers++;
577 }
578 ips_hotplug = 1;
579 return (ips_num_controllers);
580}
581
582
583
584
585
586static void
587ips_setup_funclist(ips_ha_t * ha)
588{
589
590
591
592
593 if (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) {
594
595 ha->func.isintr = ips_isintr_morpheus;
596 ha->func.isinit = ips_isinit_morpheus;
597 ha->func.issue = ips_issue_i2o_memio;
598 ha->func.init = ips_init_morpheus;
599 ha->func.statupd = ips_statupd_morpheus;
600 ha->func.reset = ips_reset_morpheus;
601 ha->func.intr = ips_intr_morpheus;
602 ha->func.enableint = ips_enable_int_morpheus;
603 } else if (IPS_USE_MEMIO(ha)) {
604
605 ha->func.isintr = ips_isintr_copperhead_memio;
606 ha->func.isinit = ips_isinit_copperhead_memio;
607 ha->func.init = ips_init_copperhead_memio;
608 ha->func.statupd = ips_statupd_copperhead_memio;
609 ha->func.statinit = ips_statinit_memio;
610 ha->func.reset = ips_reset_copperhead_memio;
611 ha->func.intr = ips_intr_copperhead;
612 ha->func.erasebios = ips_erase_bios_memio;
613 ha->func.programbios = ips_program_bios_memio;
614 ha->func.verifybios = ips_verify_bios_memio;
615 ha->func.enableint = ips_enable_int_copperhead_memio;
616 if (IPS_USE_I2O_DELIVER(ha))
617 ha->func.issue = ips_issue_i2o_memio;
618 else
619 ha->func.issue = ips_issue_copperhead_memio;
620 } else {
621
622 ha->func.isintr = ips_isintr_copperhead;
623 ha->func.isinit = ips_isinit_copperhead;
624 ha->func.init = ips_init_copperhead;
625 ha->func.statupd = ips_statupd_copperhead;
626 ha->func.statinit = ips_statinit;
627 ha->func.reset = ips_reset_copperhead;
628 ha->func.intr = ips_intr_copperhead;
629 ha->func.erasebios = ips_erase_bios;
630 ha->func.programbios = ips_program_bios;
631 ha->func.verifybios = ips_verify_bios;
632 ha->func.enableint = ips_enable_int_copperhead;
633
634 if (IPS_USE_I2O_DELIVER(ha))
635 ha->func.issue = ips_issue_i2o;
636 else
637 ha->func.issue = ips_issue_copperhead;
638 }
639}
640
641
642
643
644
645
646
647
648
649
650static int
651ips_release(struct Scsi_Host *sh)
652{
653 ips_scb_t *scb;
654 ips_ha_t *ha;
655 int i;
656
657 METHOD_TRACE("ips_release", 1);
658
659 scsi_remove_host(sh);
660
661 for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++) ;
662
663 if (i == IPS_MAX_ADAPTERS) {
664 printk(KERN_WARNING
665 "(%s) release, invalid Scsi_Host pointer.\n", ips_name);
666 BUG();
667 return (FALSE);
668 }
669
670 ha = IPS_HA(sh);
671
672 if (!ha)
673 return (FALSE);
674
675
676 scb = &ha->scbs[ha->max_cmds - 1];
677
678 ips_init_scb(ha, scb);
679
680 scb->timeout = ips_cmd_timeout;
681 scb->cdb[0] = IPS_CMD_FLUSH;
682
683 scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
684 scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
685 scb->cmd.flush_cache.state = IPS_NORM_STATE;
686 scb->cmd.flush_cache.reserved = 0;
687 scb->cmd.flush_cache.reserved2 = 0;
688 scb->cmd.flush_cache.reserved3 = 0;
689 scb->cmd.flush_cache.reserved4 = 0;
690
691 IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n");
692
693
694 if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE)
695 IPS_PRINTK(KERN_WARNING, ha->pcidev, "Incomplete Flush.\n");
696
697 IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Complete.\n");
698
699 ips_sh[i] = NULL;
700 ips_ha[i] = NULL;
701
702
703 ips_free(ha);
704
705
706 if (ha->io_addr)
707 release_region(ha->io_addr, ha->io_len);
708
709
710 free_irq(ha->irq, ha);
711
712 scsi_host_put(sh);
713
714 ips_released_controllers++;
715
716 return (FALSE);
717}
718
719
720
721
722
723
724
725
726
727
728static int
729ips_halt(struct notifier_block *nb, ulong event, void *buf)
730{
731 ips_scb_t *scb;
732 ips_ha_t *ha;
733 int i;
734
735 if ((event != SYS_RESTART) && (event != SYS_HALT) &&
736 (event != SYS_POWER_OFF))
737 return (NOTIFY_DONE);
738
739 for (i = 0; i < ips_next_controller; i++) {
740 ha = (ips_ha_t *) ips_ha[i];
741
742 if (!ha)
743 continue;
744
745 if (!ha->active)
746 continue;
747
748
749 scb = &ha->scbs[ha->max_cmds - 1];
750
751 ips_init_scb(ha, scb);
752
753 scb->timeout = ips_cmd_timeout;
754 scb->cdb[0] = IPS_CMD_FLUSH;
755
756 scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
757 scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
758 scb->cmd.flush_cache.state = IPS_NORM_STATE;
759 scb->cmd.flush_cache.reserved = 0;
760 scb->cmd.flush_cache.reserved2 = 0;
761 scb->cmd.flush_cache.reserved3 = 0;
762 scb->cmd.flush_cache.reserved4 = 0;
763
764 IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n");
765
766
767 if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) ==
768 IPS_FAILURE)
769 IPS_PRINTK(KERN_WARNING, ha->pcidev,
770 "Incomplete Flush.\n");
771 else
772 IPS_PRINTK(KERN_WARNING, ha->pcidev,
773 "Flushing Complete.\n");
774 }
775
776 return (NOTIFY_OK);
777}
778
779
780
781
782
783
784
785
786
787
788int ips_eh_abort(struct scsi_cmnd *SC)
789{
790 ips_ha_t *ha;
791 ips_copp_wait_item_t *item;
792 int ret;
793 struct Scsi_Host *host;
794
795 METHOD_TRACE("ips_eh_abort", 1);
796
797 if (!SC)
798 return (FAILED);
799
800 host = SC->device->host;
801 ha = (ips_ha_t *) SC->device->host->hostdata;
802
803 if (!ha)
804 return (FAILED);
805
806 if (!ha->active)
807 return (FAILED);
808
809 spin_lock(host->host_lock);
810
811
812 item = ha->copp_waitlist.head;
813 while ((item) && (item->scsi_cmd != SC))
814 item = item->next;
815
816 if (item) {
817
818 ips_removeq_copp(&ha->copp_waitlist, item);
819 ret = (SUCCESS);
820
821
822 } else if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
823
824 ret = (SUCCESS);
825 } else {
826
827 ret = (FAILED);
828 }
829
830 spin_unlock(host->host_lock);
831 return ret;
832}
833
834
835
836
837
838
839
840
841
842
843
844
845static int __ips_eh_reset(struct scsi_cmnd *SC)
846{
847 int ret;
848 int i;
849 ips_ha_t *ha;
850 ips_scb_t *scb;
851 ips_copp_wait_item_t *item;
852
853 METHOD_TRACE("ips_eh_reset", 1);
854
855#ifdef NO_IPS_RESET
856 return (FAILED);
857#else
858
859 if (!SC) {
860 DEBUG(1, "Reset called with NULL scsi command");
861
862 return (FAILED);
863 }
864
865 ha = (ips_ha_t *) SC->device->host->hostdata;
866
867 if (!ha) {
868 DEBUG(1, "Reset called with NULL ha struct");
869
870 return (FAILED);
871 }
872
873 if (!ha->active)
874 return (FAILED);
875
876
877 item = ha->copp_waitlist.head;
878 while ((item) && (item->scsi_cmd != SC))
879 item = item->next;
880
881 if (item) {
882
883 ips_removeq_copp(&ha->copp_waitlist, item);
884 return (SUCCESS);
885 }
886
887
888 if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
889
890 return (SUCCESS);
891 }
892
893
894
895
896
897
898
899
900
901
902
903 if (ha->ioctl_reset == 0) {
904 scb = &ha->scbs[ha->max_cmds - 1];
905
906 ips_init_scb(ha, scb);
907
908 scb->timeout = ips_cmd_timeout;
909 scb->cdb[0] = IPS_CMD_FLUSH;
910
911 scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
912 scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
913 scb->cmd.flush_cache.state = IPS_NORM_STATE;
914 scb->cmd.flush_cache.reserved = 0;
915 scb->cmd.flush_cache.reserved2 = 0;
916 scb->cmd.flush_cache.reserved3 = 0;
917 scb->cmd.flush_cache.reserved4 = 0;
918
919
920 ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL);
921 if (ret == IPS_SUCCESS) {
922 IPS_PRINTK(KERN_NOTICE, ha->pcidev,
923 "Reset Request - Flushed Cache\n");
924 return (SUCCESS);
925 }
926 }
927
928
929
930
931 ha->ioctl_reset = 0;
932
933
934
935
936
937 IPS_PRINTK(KERN_NOTICE, ha->pcidev, "Resetting controller.\n");
938 ret = (*ha->func.reset) (ha);
939
940 if (!ret) {
941 struct scsi_cmnd *scsi_cmd;
942
943 IPS_PRINTK(KERN_NOTICE, ha->pcidev,
944 "Controller reset failed - controller now offline.\n");
945
946
947 DEBUG_VAR(1, "(%s%d) Failing active commands",
948 ips_name, ha->host_num);
949
950 while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
951 scb->scsi_cmd->result = DID_ERROR << 16;
952 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
953 ips_freescb(ha, scb);
954 }
955
956
957 DEBUG_VAR(1, "(%s%d) Failing pending commands",
958 ips_name, ha->host_num);
959
960 while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
961 scsi_cmd->result = DID_ERROR;
962 scsi_cmd->scsi_done(scsi_cmd);
963 }
964
965 ha->active = FALSE;
966 return (FAILED);
967 }
968
969 if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
970 struct scsi_cmnd *scsi_cmd;
971
972 IPS_PRINTK(KERN_NOTICE, ha->pcidev,
973 "Controller reset failed - controller now offline.\n");
974
975
976 DEBUG_VAR(1, "(%s%d) Failing active commands",
977 ips_name, ha->host_num);
978
979 while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
980 scb->scsi_cmd->result = DID_ERROR << 16;
981 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
982 ips_freescb(ha, scb);
983 }
984
985
986 DEBUG_VAR(1, "(%s%d) Failing pending commands",
987 ips_name, ha->host_num);
988
989 while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
990 scsi_cmd->result = DID_ERROR << 16;
991 scsi_cmd->scsi_done(scsi_cmd);
992 }
993
994 ha->active = FALSE;
995 return (FAILED);
996 }
997
998
999 if (le32_to_cpu(ha->subsys->param[3]) & 0x300000) {
1000 struct timeval tv;
1001
1002 do_gettimeofday(&tv);
1003 ha->last_ffdc = tv.tv_sec;
1004 ha->reset_count++;
1005 ips_ffdc_reset(ha, IPS_INTR_IORL);
1006 }
1007
1008
1009 DEBUG_VAR(1, "(%s%d) Failing active commands", ips_name, ha->host_num);
1010
1011 while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
1012 scb->scsi_cmd->result =
1013 (DID_RESET << 16) | (SUGGEST_RETRY << 24);
1014 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
1015 ips_freescb(ha, scb);
1016 }
1017
1018
1019 for (i = 1; i < ha->nbus; i++)
1020 ha->dcdb_active[i - 1] = 0;
1021
1022
1023 ha->num_ioctl = 0;
1024
1025 ips_next(ha, IPS_INTR_IORL);
1026
1027 return (SUCCESS);
1028#endif
1029
1030}
1031
1032static int ips_eh_reset(struct scsi_cmnd *SC)
1033{
1034 int rc;
1035
1036 spin_lock_irq(SC->device->host->host_lock);
1037 rc = __ips_eh_reset(SC);
1038 spin_unlock_irq(SC->device->host->host_lock);
1039
1040 return rc;
1041}
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
1054
1055static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
1056{
1057 ips_ha_t *ha;
1058 ips_passthru_t *pt;
1059
1060 METHOD_TRACE("ips_queue", 1);
1061
1062 ha = (ips_ha_t *) SC->device->host->hostdata;
1063
1064 if (!ha)
1065 return (1);
1066
1067 if (!ha->active)
1068 return (DID_ERROR);
1069
1070 if (ips_is_passthru(SC)) {
1071 if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) {
1072 SC->result = DID_BUS_BUSY << 16;
1073 done(SC);
1074
1075 return (0);
1076 }
1077 } else if (ha->scb_waitlist.count == IPS_MAX_QUEUE) {
1078 SC->result = DID_BUS_BUSY << 16;
1079 done(SC);
1080
1081 return (0);
1082 }
1083
1084 SC->scsi_done = done;
1085
1086 DEBUG_VAR(2, "(%s%d): ips_queue: cmd 0x%X (%d %d %d)",
1087 ips_name,
1088 ha->host_num,
1089 SC->cmnd[0],
1090 SC->device->channel, SC->device->id, SC->device->lun);
1091
1092
1093 if ((scmd_channel(SC) > 0)
1094 && (scmd_id(SC) == ha->ha_id[scmd_channel(SC)])) {
1095 SC->result = DID_NO_CONNECT << 16;
1096 done(SC);
1097
1098 return (0);
1099 }
1100
1101 if (ips_is_passthru(SC)) {
1102
1103 ips_copp_wait_item_t *scratch;
1104
1105
1106
1107
1108 pt = (ips_passthru_t *) scsi_sglist(SC);
1109 if ((pt->CoppCP.cmd.reset.op_code == IPS_CMD_RESET_CHANNEL) &&
1110 (pt->CoppCP.cmd.reset.adapter_flag == 1)) {
1111 if (ha->scb_activelist.count != 0) {
1112 SC->result = DID_BUS_BUSY << 16;
1113 done(SC);
1114 return (0);
1115 }
1116 ha->ioctl_reset = 1;
1117 __ips_eh_reset(SC);
1118 SC->result = DID_OK << 16;
1119 SC->scsi_done(SC);
1120 return (0);
1121 }
1122
1123
1124 scratch = kmalloc(sizeof (ips_copp_wait_item_t), GFP_ATOMIC);
1125
1126 if (!scratch) {
1127 SC->result = DID_ERROR << 16;
1128 done(SC);
1129
1130 return (0);
1131 }
1132
1133 scratch->scsi_cmd = SC;
1134 scratch->next = NULL;
1135
1136 ips_putq_copp_tail(&ha->copp_waitlist, scratch);
1137 } else {
1138 ips_putq_wait_tail(&ha->scb_waitlist, SC);
1139 }
1140
1141 ips_next(ha, IPS_INTR_IORL);
1142
1143 return (0);
1144}
1145
1146
1147
1148
1149
1150
1151
1152
1153
1154
1155static int ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
1156 sector_t capacity, int geom[])
1157{
1158 ips_ha_t *ha = (ips_ha_t *) sdev->host->hostdata;
1159 int heads;
1160 int sectors;
1161 int cylinders;
1162
1163 METHOD_TRACE("ips_biosparam", 1);
1164
1165 if (!ha)
1166
1167 return (0);
1168
1169 if (!ha->active)
1170 return (0);
1171
1172 if (!ips_read_adapter_status(ha, IPS_INTR_ON))
1173
1174 return (0);
1175
1176 if ((capacity > 0x400000) && ((ha->enq->ucMiscFlag & 0x8) == 0)) {
1177 heads = IPS_NORM_HEADS;
1178 sectors = IPS_NORM_SECTORS;
1179 } else {
1180 heads = IPS_COMP_HEADS;
1181 sectors = IPS_COMP_SECTORS;
1182 }
1183
1184 cylinders = (unsigned long) capacity / (heads * sectors);
1185
1186 DEBUG_VAR(2, "Geometry: heads: %d, sectors: %d, cylinders: %d",
1187 heads, sectors, cylinders);
1188
1189 geom[0] = heads;
1190 geom[1] = sectors;
1191 geom[2] = cylinders;
1192
1193 return (0);
1194}
1195
1196
1197
1198
1199
1200
1201
1202
1203
1204
1205static int
1206ips_slave_configure(struct scsi_device * SDptr)
1207{
1208 ips_ha_t *ha;
1209 int min;
1210
1211 ha = IPS_HA(SDptr->host);
1212 if (SDptr->tagged_supported && SDptr->type == TYPE_DISK) {
1213 min = ha->max_cmds / 2;
1214 if (ha->enq->ucLogDriveCount <= 2)
1215 min = ha->max_cmds - 1;
1216 scsi_adjust_queue_depth(SDptr, MSG_ORDERED_TAG, min);
1217 }
1218
1219 SDptr->skip_ms_page_8 = 1;
1220 SDptr->skip_ms_page_3f = 1;
1221 return 0;
1222}
1223
1224
1225
1226
1227
1228
1229
1230
1231
1232
1233static irqreturn_t
1234do_ipsintr(int irq, void *dev_id)
1235{
1236 ips_ha_t *ha;
1237 struct Scsi_Host *host;
1238 int irqstatus;
1239
1240 METHOD_TRACE("do_ipsintr", 2);
1241
1242 ha = (ips_ha_t *) dev_id;
1243 if (!ha)
1244 return IRQ_NONE;
1245 host = ips_sh[ha->host_num];
1246
1247 if (!host) {
1248 (*ha->func.intr) (ha);
1249 return IRQ_HANDLED;
1250 }
1251
1252 spin_lock(host->host_lock);
1253
1254 if (!ha->active) {
1255 spin_unlock(host->host_lock);
1256 return IRQ_HANDLED;
1257 }
1258
1259 irqstatus = (*ha->func.intr) (ha);
1260
1261 spin_unlock(host->host_lock);
1262
1263
1264 ips_next(ha, IPS_INTR_ON);
1265 return IRQ_RETVAL(irqstatus);
1266}
1267
1268
1269
1270
1271
1272
1273
1274
1275
1276
1277
1278
1279int
1280ips_intr_copperhead(ips_ha_t * ha)
1281{
1282 ips_stat_t *sp;
1283 ips_scb_t *scb;
1284 IPS_STATUS cstatus;
1285 int intrstatus;
1286
1287 METHOD_TRACE("ips_intr", 2);
1288
1289 if (!ha)
1290 return 0;
1291
1292 if (!ha->active)
1293 return 0;
1294
1295 intrstatus = (*ha->func.isintr) (ha);
1296
1297 if (!intrstatus) {
1298
1299
1300
1301
1302 return 0;
1303 }
1304
1305 while (TRUE) {
1306 sp = &ha->sp;
1307
1308 intrstatus = (*ha->func.isintr) (ha);
1309
1310 if (!intrstatus)
1311 break;
1312 else
1313 cstatus.value = (*ha->func.statupd) (ha);
1314
1315 if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
1316
1317 continue;
1318 }
1319
1320 ips_chkstatus(ha, &cstatus);
1321 scb = (ips_scb_t *) sp->scb_addr;
1322
1323
1324
1325
1326
1327 (*scb->callback) (ha, scb);
1328 }
1329 return 1;
1330}
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343int
1344ips_intr_morpheus(ips_ha_t * ha)
1345{
1346 ips_stat_t *sp;
1347 ips_scb_t *scb;
1348 IPS_STATUS cstatus;
1349 int intrstatus;
1350
1351 METHOD_TRACE("ips_intr_morpheus", 2);
1352
1353 if (!ha)
1354 return 0;
1355
1356 if (!ha->active)
1357 return 0;
1358
1359 intrstatus = (*ha->func.isintr) (ha);
1360
1361 if (!intrstatus) {
1362
1363
1364
1365
1366 return 0;
1367 }
1368
1369 while (TRUE) {
1370 sp = &ha->sp;
1371
1372 intrstatus = (*ha->func.isintr) (ha);
1373
1374 if (!intrstatus)
1375 break;
1376 else
1377 cstatus.value = (*ha->func.statupd) (ha);
1378
1379 if (cstatus.value == 0xffffffff)
1380
1381 break;
1382
1383 if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
1384 IPS_PRINTK(KERN_WARNING, ha->pcidev,
1385 "Spurious interrupt; no ccb.\n");
1386
1387 continue;
1388 }
1389
1390 ips_chkstatus(ha, &cstatus);
1391 scb = (ips_scb_t *) sp->scb_addr;
1392
1393
1394
1395
1396
1397 (*scb->callback) (ha, scb);
1398 }
1399 return 1;
1400}
1401
1402
1403
1404
1405
1406
1407
1408
1409
1410
1411static const char *
1412ips_info(struct Scsi_Host *SH)
1413{
1414 static char buffer[256];
1415 char *bp;
1416 ips_ha_t *ha;
1417
1418 METHOD_TRACE("ips_info", 1);
1419
1420 ha = IPS_HA(SH);
1421
1422 if (!ha)
1423 return (NULL);
1424
1425 bp = &buffer[0];
1426 memset(bp, 0, sizeof (buffer));
1427
1428 sprintf(bp, "%s%s%s Build %d", "IBM PCI ServeRAID ",
1429 IPS_VERSION_HIGH, IPS_VERSION_LOW, IPS_BUILD_IDENT);
1430
1431 if (ha->ad_type > 0 && ha->ad_type <= MAX_ADAPTER_NAME) {
1432 strcat(bp, " <");
1433 strcat(bp, ips_adapter_name[ha->ad_type - 1]);
1434 strcat(bp, ">");
1435 }
1436
1437 return (bp);
1438}
1439
1440
1441
1442
1443
1444
1445
1446
1447
1448
1449static int
1450ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1451 int length, int func)
1452{
1453 int i;
1454 int ret;
1455 ips_ha_t *ha = NULL;
1456
1457 METHOD_TRACE("ips_proc_info", 1);
1458
1459
1460 for (i = 0; i < ips_next_controller; i++) {
1461 if (ips_sh[i]) {
1462 if (ips_sh[i] == host) {
1463 ha = (ips_ha_t *) ips_sh[i]->hostdata;
1464 break;
1465 }
1466 }
1467 }
1468
1469 if (!ha)
1470 return (-EINVAL);
1471
1472 if (func) {
1473
1474 return (0);
1475 } else {
1476
1477 if (start)
1478 *start = buffer;
1479
1480 ret = ips_host_info(ha, buffer, offset, length);
1481
1482 return (ret);
1483 }
1484}
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
1495
1496
1497
1498
1499static int ips_is_passthru(struct scsi_cmnd *SC)
1500{
1501 unsigned long flags;
1502
1503 METHOD_TRACE("ips_is_passthru", 1);
1504
1505 if (!SC)
1506 return (0);
1507
1508 if ((SC->cmnd[0] == IPS_IOCTL_COMMAND) &&
1509 (SC->device->channel == 0) &&
1510 (SC->device->id == IPS_ADAPTER_ID) &&
1511 (SC->device->lun == 0) && scsi_sglist(SC)) {
1512 struct scatterlist *sg = scsi_sglist(SC);
1513 char *buffer;
1514
1515
1516
1517 local_irq_save(flags);
1518 buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
1519 if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
1520 buffer[2] == 'P' && buffer[3] == 'P') {
1521 kunmap_atomic(buffer - sg->offset, KM_IRQ0);
1522 local_irq_restore(flags);
1523 return 1;
1524 }
1525 kunmap_atomic(buffer - sg->offset, KM_IRQ0);
1526 local_irq_restore(flags);
1527 }
1528 return 0;
1529}
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539static int
1540ips_alloc_passthru_buffer(ips_ha_t * ha, int length)
1541{
1542 void *bigger_buf;
1543 dma_addr_t dma_busaddr;
1544
1545 if (ha->ioctl_data && length <= ha->ioctl_len)
1546 return 0;
1547
1548 bigger_buf = pci_alloc_consistent(ha->pcidev, length, &dma_busaddr);
1549 if (bigger_buf) {
1550
1551 pci_free_consistent(ha->pcidev, ha->ioctl_len, ha->ioctl_data,
1552 ha->ioctl_busaddr);
1553
1554 ha->ioctl_data = (char *) bigger_buf;
1555 ha->ioctl_len = length;
1556 ha->ioctl_busaddr = dma_busaddr;
1557 } else {
1558 return -1;
1559 }
1560 return 0;
1561}
1562
1563
1564
1565
1566
1567
1568
1569
1570
1571
1572static int
1573ips_make_passthru(ips_ha_t *ha, struct scsi_cmnd *SC, ips_scb_t *scb, int intr)
1574{
1575 ips_passthru_t *pt;
1576 int length = 0;
1577 int i, ret;
1578 struct scatterlist *sg = scsi_sglist(SC);
1579
1580 METHOD_TRACE("ips_make_passthru", 1);
1581
1582 scsi_for_each_sg(SC, sg, scsi_sg_count(SC), i)
1583 length += sg[i].length;
1584
1585 if (length < sizeof (ips_passthru_t)) {
1586
1587 DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
1588 ips_name, ha->host_num);
1589 return (IPS_FAILURE);
1590 }
1591 if (ips_alloc_passthru_buffer(ha, length)) {
1592
1593
1594 if (ha->ioctl_data) {
1595 pt = (ips_passthru_t *) ha->ioctl_data;
1596 ips_scmd_buf_read(SC, pt, sizeof (ips_passthru_t));
1597 pt->BasicStatus = 0x0B;
1598 pt->ExtendedStatus = 0x00;
1599 ips_scmd_buf_write(SC, pt, sizeof (ips_passthru_t));
1600 }
1601 return IPS_FAILURE;
1602 }
1603 ha->ioctl_datasize = length;
1604
1605 ips_scmd_buf_read(SC, ha->ioctl_data, ha->ioctl_datasize);
1606 pt = (ips_passthru_t *) ha->ioctl_data;
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618 switch (pt->CoppCmd) {
1619 case IPS_NUMCTRLS:
1620 memcpy(ha->ioctl_data + sizeof (ips_passthru_t),
1621 &ips_num_controllers, sizeof (int));
1622 ips_scmd_buf_write(SC, ha->ioctl_data,
1623 sizeof (ips_passthru_t) + sizeof (int));
1624 SC->result = DID_OK << 16;
1625
1626 return (IPS_SUCCESS_IMM);
1627
1628 case IPS_COPPUSRCMD:
1629 case IPS_COPPIOCCMD:
1630 if (SC->cmnd[0] == IPS_IOCTL_COMMAND) {
1631 if (length < (sizeof (ips_passthru_t) + pt->CmdBSize)) {
1632
1633 DEBUG_VAR(1,
1634 "(%s%d) Passthru structure wrong size",
1635 ips_name, ha->host_num);
1636
1637 return (IPS_FAILURE);
1638 }
1639
1640 if (ha->device_id == IPS_DEVICEID_COPPERHEAD &&
1641 pt->CoppCP.cmd.flashfw.op_code ==
1642 IPS_CMD_RW_BIOSFW) {
1643 ret = ips_flash_copperhead(ha, pt, scb);
1644 ips_scmd_buf_write(SC, ha->ioctl_data,
1645 sizeof (ips_passthru_t));
1646 return ret;
1647 }
1648 if (ips_usrcmd(ha, pt, scb))
1649 return (IPS_SUCCESS);
1650 else
1651 return (IPS_FAILURE);
1652 }
1653
1654 break;
1655
1656 }
1657
1658 return (IPS_FAILURE);
1659}
1660
1661
1662
1663
1664
1665
1666static int
1667ips_flash_copperhead(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1668{
1669 int datasize;
1670
1671
1672
1673 if (IPS_IS_TROMBONE(ha) && pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE) {
1674 if (ips_usrcmd(ha, pt, scb))
1675 return IPS_SUCCESS;
1676 else
1677 return IPS_FAILURE;
1678 }
1679 pt->BasicStatus = 0x0B;
1680 pt->ExtendedStatus = 0;
1681 scb->scsi_cmd->result = DID_OK << 16;
1682
1683
1684 if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1685 pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) {
1686 pt->BasicStatus = 0;
1687 return ips_flash_bios(ha, pt, scb);
1688 } else if (pt->CoppCP.cmd.flashfw.packet_num == 0) {
1689 if (ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)){
1690 ha->flash_data = ips_FlashData;
1691 ha->flash_busaddr = ips_flashbusaddr;
1692 ha->flash_len = PAGE_SIZE << 7;
1693 ha->flash_datasize = 0;
1694 } else if (!ha->flash_data) {
1695 datasize = pt->CoppCP.cmd.flashfw.total_packets *
1696 pt->CoppCP.cmd.flashfw.count;
1697 ha->flash_data = pci_alloc_consistent(ha->pcidev,
1698 datasize,
1699 &ha->flash_busaddr);
1700 if (!ha->flash_data){
1701 printk(KERN_WARNING "Unable to allocate a flash buffer\n");
1702 return IPS_FAILURE;
1703 }
1704 ha->flash_datasize = 0;
1705 ha->flash_len = datasize;
1706 } else
1707 return IPS_FAILURE;
1708 } else {
1709 if (pt->CoppCP.cmd.flashfw.count + ha->flash_datasize >
1710 ha->flash_len) {
1711 ips_free_flash_copperhead(ha);
1712 IPS_PRINTK(KERN_WARNING, ha->pcidev,
1713 "failed size sanity check\n");
1714 return IPS_FAILURE;
1715 }
1716 }
1717 if (!ha->flash_data)
1718 return IPS_FAILURE;
1719 pt->BasicStatus = 0;
1720 memcpy(&ha->flash_data[ha->flash_datasize], pt + 1,
1721 pt->CoppCP.cmd.flashfw.count);
1722 ha->flash_datasize += pt->CoppCP.cmd.flashfw.count;
1723 if (pt->CoppCP.cmd.flashfw.packet_num ==
1724 pt->CoppCP.cmd.flashfw.total_packets - 1) {
1725 if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE)
1726 return ips_flash_bios(ha, pt, scb);
1727 else if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE)
1728 return ips_flash_firmware(ha, pt, scb);
1729 }
1730 return IPS_SUCCESS_IMM;
1731}
1732
1733
1734
1735
1736
1737
1738static int
1739ips_flash_bios(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1740{
1741
1742 if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1743 pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_BIOS) {
1744 if ((!ha->func.programbios) || (!ha->func.erasebios) ||
1745 (!ha->func.verifybios))
1746 goto error;
1747 if ((*ha->func.erasebios) (ha)) {
1748 DEBUG_VAR(1,
1749 "(%s%d) flash bios failed - unable to erase flash",
1750 ips_name, ha->host_num);
1751 goto error;
1752 } else
1753 if ((*ha->func.programbios) (ha,
1754 ha->flash_data +
1755 IPS_BIOS_HEADER,
1756 ha->flash_datasize -
1757 IPS_BIOS_HEADER, 0)) {
1758 DEBUG_VAR(1,
1759 "(%s%d) flash bios failed - unable to flash",
1760 ips_name, ha->host_num);
1761 goto error;
1762 } else
1763 if ((*ha->func.verifybios) (ha,
1764 ha->flash_data +
1765 IPS_BIOS_HEADER,
1766 ha->flash_datasize -
1767 IPS_BIOS_HEADER, 0)) {
1768 DEBUG_VAR(1,
1769 "(%s%d) flash bios failed - unable to verify flash",
1770 ips_name, ha->host_num);
1771 goto error;
1772 }
1773 ips_free_flash_copperhead(ha);
1774 return IPS_SUCCESS_IMM;
1775 } else if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1776 pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) {
1777 if (!ha->func.erasebios)
1778 goto error;
1779 if ((*ha->func.erasebios) (ha)) {
1780 DEBUG_VAR(1,
1781 "(%s%d) flash bios failed - unable to erase flash",
1782 ips_name, ha->host_num);
1783 goto error;
1784 }
1785 return IPS_SUCCESS_IMM;
1786 }
1787 error:
1788 pt->BasicStatus = 0x0B;
1789 pt->ExtendedStatus = 0x00;
1790 ips_free_flash_copperhead(ha);
1791 return IPS_FAILURE;
1792}
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802static int
1803ips_fill_scb_sg_single(ips_ha_t * ha, dma_addr_t busaddr,
1804 ips_scb_t * scb, int indx, unsigned int e_len)
1805{
1806
1807 int ret_val = 0;
1808
1809 if ((scb->data_len + e_len) > ha->max_xfer) {
1810 e_len = ha->max_xfer - scb->data_len;
1811 scb->breakup = indx;
1812 ++scb->sg_break;
1813 ret_val = -1;
1814 } else {
1815 scb->breakup = 0;
1816 scb->sg_break = 0;
1817 }
1818 if (IPS_USE_ENH_SGLIST(ha)) {
1819 scb->sg_list.enh_list[indx].address_lo =
1820 cpu_to_le32(pci_dma_lo32(busaddr));
1821 scb->sg_list.enh_list[indx].address_hi =
1822 cpu_to_le32(pci_dma_hi32(busaddr));
1823 scb->sg_list.enh_list[indx].length = cpu_to_le32(e_len);
1824 } else {
1825 scb->sg_list.std_list[indx].address =
1826 cpu_to_le32(pci_dma_lo32(busaddr));
1827 scb->sg_list.std_list[indx].length = cpu_to_le32(e_len);
1828 }
1829
1830 ++scb->sg_len;
1831 scb->data_len += e_len;
1832 return ret_val;
1833}
1834
1835
1836
1837
1838
1839
1840static int
1841ips_flash_firmware(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1842{
1843 IPS_SG_LIST sg_list;
1844 uint32_t cmd_busaddr;
1845
1846 if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE &&
1847 pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_FW) {
1848 memset(&pt->CoppCP.cmd, 0, sizeof (IPS_HOST_COMMAND));
1849 pt->CoppCP.cmd.flashfw.op_code = IPS_CMD_DOWNLOAD;
1850 pt->CoppCP.cmd.flashfw.count = cpu_to_le32(ha->flash_datasize);
1851 } else {
1852 pt->BasicStatus = 0x0B;
1853 pt->ExtendedStatus = 0x00;
1854 ips_free_flash_copperhead(ha);
1855 return IPS_FAILURE;
1856 }
1857
1858 sg_list.list = scb->sg_list.list;
1859 cmd_busaddr = scb->scb_busaddr;
1860
1861 memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD));
1862
1863 scb->sg_list.list = sg_list.list;
1864 scb->scb_busaddr = cmd_busaddr;
1865 scb->bus = scb->scsi_cmd->device->channel;
1866 scb->target_id = scb->scsi_cmd->device->id;
1867 scb->lun = scb->scsi_cmd->device->lun;
1868 scb->sg_len = 0;
1869 scb->data_len = 0;
1870 scb->flags = 0;
1871 scb->op_code = 0;
1872 scb->callback = ipsintr_done;
1873 scb->timeout = ips_cmd_timeout;
1874
1875 scb->data_len = ha->flash_datasize;
1876 scb->data_busaddr =
1877 pci_map_single(ha->pcidev, ha->flash_data, scb->data_len,
1878 IPS_DMA_DIR(scb));
1879 scb->flags |= IPS_SCB_MAP_SINGLE;
1880 scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
1881 scb->cmd.flashfw.buffer_addr = cpu_to_le32(scb->data_busaddr);
1882 if (pt->TimeOut)
1883 scb->timeout = pt->TimeOut;
1884 scb->scsi_cmd->result = DID_OK << 16;
1885 return IPS_SUCCESS;
1886}
1887
1888
1889
1890
1891
1892
1893static void
1894ips_free_flash_copperhead(ips_ha_t * ha)
1895{
1896 if (ha->flash_data == ips_FlashData)
1897 test_and_clear_bit(0, &ips_FlashDataInUse);
1898 else if (ha->flash_data)
1899 pci_free_consistent(ha->pcidev, ha->flash_len, ha->flash_data,
1900 ha->flash_busaddr);
1901 ha->flash_data = NULL;
1902}
1903
1904
1905
1906
1907
1908
1909
1910
1911
1912
1913static int
1914ips_usrcmd(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1915{
1916 IPS_SG_LIST sg_list;
1917 uint32_t cmd_busaddr;
1918
1919 METHOD_TRACE("ips_usrcmd", 1);
1920
1921 if ((!scb) || (!pt) || (!ha))
1922 return (0);
1923
1924
1925 sg_list.list = scb->sg_list.list;
1926 cmd_busaddr = scb->scb_busaddr;
1927
1928 memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD));
1929 memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof (IPS_DCDB_TABLE));
1930
1931
1932 scb->sg_list.list = sg_list.list;
1933 scb->scb_busaddr = cmd_busaddr;
1934 scb->bus = scb->scsi_cmd->device->channel;
1935 scb->target_id = scb->scsi_cmd->device->id;
1936 scb->lun = scb->scsi_cmd->device->lun;
1937 scb->sg_len = 0;
1938 scb->data_len = 0;
1939 scb->flags = 0;
1940 scb->op_code = 0;
1941 scb->callback = ipsintr_done;
1942 scb->timeout = ips_cmd_timeout;
1943 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
1944
1945
1946 if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) ||
1947 (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) ||
1948 (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG))
1949 return (0);
1950
1951 if (pt->CmdBSize) {
1952 scb->data_len = pt->CmdBSize;
1953 scb->data_busaddr = ha->ioctl_busaddr + sizeof (ips_passthru_t);
1954 } else {
1955 scb->data_busaddr = 0L;
1956 }
1957
1958 if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
1959 scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
1960 (unsigned long) &scb->
1961 dcdb -
1962 (unsigned long) scb);
1963
1964 if (pt->CmdBSize) {
1965 if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
1966 scb->dcdb.buffer_pointer =
1967 cpu_to_le32(scb->data_busaddr);
1968 else
1969 scb->cmd.basic_io.sg_addr =
1970 cpu_to_le32(scb->data_busaddr);
1971 }
1972
1973
1974 if (pt->TimeOut) {
1975 scb->timeout = pt->TimeOut;
1976
1977 if (pt->TimeOut <= 10)
1978 scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
1979 else if (pt->TimeOut <= 60)
1980 scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
1981 else
1982 scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
1983 }
1984
1985
1986 scb->scsi_cmd->result = DID_OK << 16;
1987
1988
1989 return (1);
1990}
1991
1992
1993
1994
1995
1996
1997
1998
1999
2000
2001static void
2002ips_cleanup_passthru(ips_ha_t * ha, ips_scb_t * scb)
2003{
2004 ips_passthru_t *pt;
2005
2006 METHOD_TRACE("ips_cleanup_passthru", 1);
2007
2008 if ((!scb) || (!scb->scsi_cmd) || (!scsi_sglist(scb->scsi_cmd))) {
2009 DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru",
2010 ips_name, ha->host_num);
2011
2012 return;
2013 }
2014 pt = (ips_passthru_t *) ha->ioctl_data;
2015
2016
2017 if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
2018 memcpy(&pt->CoppCP.dcdb, &scb->dcdb, sizeof (IPS_DCDB_TABLE));
2019
2020 pt->BasicStatus = scb->basic_status;
2021 pt->ExtendedStatus = scb->extended_status;
2022 pt->AdapterType = ha->ad_type;
2023
2024 if (ha->device_id == IPS_DEVICEID_COPPERHEAD &&
2025 (scb->cmd.flashfw.op_code == IPS_CMD_DOWNLOAD ||
2026 scb->cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW))
2027 ips_free_flash_copperhead(ha);
2028
2029 ips_scmd_buf_write(scb->scsi_cmd, ha->ioctl_data, ha->ioctl_datasize);
2030}
2031
2032
2033
2034
2035
2036
2037
2038
2039
2040
2041static int
2042ips_host_info(ips_ha_t * ha, char *ptr, off_t offset, int len)
2043{
2044 IPS_INFOSTR info;
2045
2046 METHOD_TRACE("ips_host_info", 1);
2047
2048 info.buffer = ptr;
2049 info.length = len;
2050 info.offset = offset;
2051 info.pos = 0;
2052 info.localpos = 0;
2053
2054 copy_info(&info, "\nIBM ServeRAID General Information:\n\n");
2055
2056 if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) &&
2057 (le16_to_cpu(ha->nvram->adapter_type) != 0))
2058 copy_info(&info, "\tController Type : %s\n",
2059 ips_adapter_name[ha->ad_type - 1]);
2060 else
2061 copy_info(&info,
2062 "\tController Type : Unknown\n");
2063
2064 if (ha->io_addr)
2065 copy_info(&info,
2066 "\tIO region : 0x%lx (%d bytes)\n",
2067 ha->io_addr, ha->io_len);
2068
2069 if (ha->mem_addr) {
2070 copy_info(&info,
2071 "\tMemory region : 0x%lx (%d bytes)\n",
2072 ha->mem_addr, ha->mem_len);
2073 copy_info(&info,
2074 "\tShared memory address : 0x%lx\n",
2075 ha->mem_ptr);
2076 }
2077
2078 copy_info(&info, "\tIRQ number : %d\n", ha->irq);
2079
2080
2081
2082
2083 if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) {
2084 if (ha->nvram->bios_low[3] == 0) {
2085 copy_info(&info,
2086 "\tBIOS Version : %c%c%c%c%c%c%c\n",
2087 ha->nvram->bios_high[0], ha->nvram->bios_high[1],
2088 ha->nvram->bios_high[2], ha->nvram->bios_high[3],
2089 ha->nvram->bios_low[0], ha->nvram->bios_low[1],
2090 ha->nvram->bios_low[2]);
2091
2092 } else {
2093 copy_info(&info,
2094 "\tBIOS Version : %c%c%c%c%c%c%c%c\n",
2095 ha->nvram->bios_high[0], ha->nvram->bios_high[1],
2096 ha->nvram->bios_high[2], ha->nvram->bios_high[3],
2097 ha->nvram->bios_low[0], ha->nvram->bios_low[1],
2098 ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
2099 }
2100
2101 }
2102
2103 if (ha->enq->CodeBlkVersion[7] == 0) {
2104 copy_info(&info,
2105 "\tFirmware Version : %c%c%c%c%c%c%c\n",
2106 ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
2107 ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
2108 ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
2109 ha->enq->CodeBlkVersion[6]);
2110 } else {
2111 copy_info(&info,
2112 "\tFirmware Version : %c%c%c%c%c%c%c%c\n",
2113 ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
2114 ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
2115 ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
2116 ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]);
2117 }
2118
2119 if (ha->enq->BootBlkVersion[7] == 0) {
2120 copy_info(&info,
2121 "\tBoot Block Version : %c%c%c%c%c%c%c\n",
2122 ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
2123 ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
2124 ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
2125 ha->enq->BootBlkVersion[6]);
2126 } else {
2127 copy_info(&info,
2128 "\tBoot Block Version : %c%c%c%c%c%c%c%c\n",
2129 ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
2130 ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
2131 ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
2132 ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]);
2133 }
2134
2135 copy_info(&info, "\tDriver Version : %s%s\n",
2136 IPS_VERSION_HIGH, IPS_VERSION_LOW);
2137
2138 copy_info(&info, "\tDriver Build : %d\n",
2139 IPS_BUILD_IDENT);
2140
2141 copy_info(&info, "\tMax Physical Devices : %d\n",
2142 ha->enq->ucMaxPhysicalDevices);
2143 copy_info(&info, "\tMax Active Commands : %d\n",
2144 ha->max_cmds);
2145 copy_info(&info, "\tCurrent Queued Commands : %d\n",
2146 ha->scb_waitlist.count);
2147 copy_info(&info, "\tCurrent Active Commands : %d\n",
2148 ha->scb_activelist.count - ha->num_ioctl);
2149 copy_info(&info, "\tCurrent Queued PT Commands : %d\n",
2150 ha->copp_waitlist.count);
2151 copy_info(&info, "\tCurrent Active PT Commands : %d\n",
2152 ha->num_ioctl);
2153
2154 copy_info(&info, "\n");
2155
2156 return (info.localpos);
2157}
2158
2159
2160
2161
2162
2163
2164
2165
2166
2167
2168static void
2169copy_mem_info(IPS_INFOSTR * info, char *data, int len)
2170{
2171 METHOD_TRACE("copy_mem_info", 1);
2172
2173 if (info->pos + len < info->offset) {
2174 info->pos += len;
2175 return;
2176 }
2177
2178 if (info->pos < info->offset) {
2179 data += (info->offset - info->pos);
2180 len -= (info->offset - info->pos);
2181 info->pos += (info->offset - info->pos);
2182 }
2183
2184 if (info->localpos + len > info->length)
2185 len = info->length - info->localpos;
2186
2187 if (len > 0) {
2188 memcpy(info->buffer + info->localpos, data, len);
2189 info->pos += len;
2190 info->localpos += len;
2191 }
2192}
2193
2194
2195
2196
2197
2198
2199
2200
2201
2202
2203static int
2204copy_info(IPS_INFOSTR * info, char *fmt, ...)
2205{
2206 va_list args;
2207 char buf[128];
2208 int len;
2209
2210 METHOD_TRACE("copy_info", 1);
2211
2212 va_start(args, fmt);
2213 len = vsprintf(buf, fmt, args);
2214 va_end(args);
2215
2216 copy_mem_info(info, buf, len);
2217
2218 return (len);
2219}
2220
2221
2222
2223
2224
2225
2226
2227
2228
2229
2230static void
2231ips_identify_controller(ips_ha_t * ha)
2232{
2233 METHOD_TRACE("ips_identify_controller", 1);
2234
2235 switch (ha->device_id) {
2236 case IPS_DEVICEID_COPPERHEAD:
2237 if (ha->revision_id <= IPS_REVID_SERVERAID) {
2238 ha->ad_type = IPS_ADTYPE_SERVERAID;
2239 } else if (ha->revision_id == IPS_REVID_SERVERAID2) {
2240 ha->ad_type = IPS_ADTYPE_SERVERAID2;
2241 } else if (ha->revision_id == IPS_REVID_NAVAJO) {
2242 ha->ad_type = IPS_ADTYPE_NAVAJO;
2243 } else if ((ha->revision_id == IPS_REVID_SERVERAID2)
2244 && (ha->slot_num == 0)) {
2245 ha->ad_type = IPS_ADTYPE_KIOWA;
2246 } else if ((ha->revision_id >= IPS_REVID_CLARINETP1) &&
2247 (ha->revision_id <= IPS_REVID_CLARINETP3)) {
2248 if (ha->enq->ucMaxPhysicalDevices == 15)
2249 ha->ad_type = IPS_ADTYPE_SERVERAID3L;
2250 else
2251 ha->ad_type = IPS_ADTYPE_SERVERAID3;
2252 } else if ((ha->revision_id >= IPS_REVID_TROMBONE32) &&
2253 (ha->revision_id <= IPS_REVID_TROMBONE64)) {
2254 ha->ad_type = IPS_ADTYPE_SERVERAID4H;
2255 }
2256 break;
2257
2258 case IPS_DEVICEID_MORPHEUS:
2259 switch (ha->subdevice_id) {
2260 case IPS_SUBDEVICEID_4L:
2261 ha->ad_type = IPS_ADTYPE_SERVERAID4L;
2262 break;
2263
2264 case IPS_SUBDEVICEID_4M:
2265 ha->ad_type = IPS_ADTYPE_SERVERAID4M;
2266 break;
2267
2268 case IPS_SUBDEVICEID_4MX:
2269 ha->ad_type = IPS_ADTYPE_SERVERAID4MX;
2270 break;
2271
2272 case IPS_SUBDEVICEID_4LX:
2273 ha->ad_type = IPS_ADTYPE_SERVERAID4LX;
2274 break;
2275
2276 case IPS_SUBDEVICEID_5I2:
2277 ha->ad_type = IPS_ADTYPE_SERVERAID5I2;
2278 break;
2279
2280 case IPS_SUBDEVICEID_5I1:
2281 ha->ad_type = IPS_ADTYPE_SERVERAID5I1;
2282 break;
2283 }
2284
2285 break;
2286
2287 case IPS_DEVICEID_MARCO:
2288 switch (ha->subdevice_id) {
2289 case IPS_SUBDEVICEID_6M:
2290 ha->ad_type = IPS_ADTYPE_SERVERAID6M;
2291 break;
2292 case IPS_SUBDEVICEID_6I:
2293 ha->ad_type = IPS_ADTYPE_SERVERAID6I;
2294 break;
2295 case IPS_SUBDEVICEID_7k:
2296 ha->ad_type = IPS_ADTYPE_SERVERAID7k;
2297 break;
2298 case IPS_SUBDEVICEID_7M:
2299 ha->ad_type = IPS_ADTYPE_SERVERAID7M;
2300 break;
2301 }
2302 break;
2303 }
2304}
2305
2306
2307
2308
2309
2310
2311
2312
2313
2314
2315static void
2316ips_get_bios_version(ips_ha_t * ha, int intr)
2317{
2318 ips_scb_t *scb;
2319 int ret;
2320 uint8_t major;
2321 uint8_t minor;
2322 uint8_t subminor;
2323 uint8_t *buffer;
2324 char hexDigits[] =
2325 { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
2326 'D', 'E', 'F' };
2327
2328 METHOD_TRACE("ips_get_bios_version", 1);
2329
2330 major = 0;
2331 minor = 0;
2332
2333 strncpy(ha->bios_version, " ?", 8);
2334
2335 if (ha->device_id == IPS_DEVICEID_COPPERHEAD) {
2336 if (IPS_USE_MEMIO(ha)) {
2337
2338
2339
2340 writel(0, ha->mem_ptr + IPS_REG_FLAP);
2341 if (ha->revision_id == IPS_REVID_TROMBONE64)
2342 udelay(25);
2343
2344 if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
2345 return;
2346
2347 writel(1, ha->mem_ptr + IPS_REG_FLAP);
2348 if (ha->revision_id == IPS_REVID_TROMBONE64)
2349 udelay(25);
2350
2351 if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
2352 return;
2353
2354
2355 writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP);
2356 if (ha->revision_id == IPS_REVID_TROMBONE64)
2357 udelay(25);
2358
2359 major = readb(ha->mem_ptr + IPS_REG_FLDP);
2360
2361
2362 writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP);
2363 if (ha->revision_id == IPS_REVID_TROMBONE64)
2364 udelay(25);
2365 minor = readb(ha->mem_ptr + IPS_REG_FLDP);
2366
2367
2368 writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP);
2369 if (ha->revision_id == IPS_REVID_TROMBONE64)
2370 udelay(25);
2371 subminor = readb(ha->mem_ptr + IPS_REG_FLDP);
2372
2373 } else {
2374
2375
2376
2377 outl(0, ha->io_addr + IPS_REG_FLAP);
2378 if (ha->revision_id == IPS_REVID_TROMBONE64)
2379 udelay(25);
2380
2381 if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
2382 return;
2383
2384 outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
2385 if (ha->revision_id == IPS_REVID_TROMBONE64)
2386 udelay(25);
2387
2388 if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
2389 return;
2390
2391
2392 outl(cpu_to_le32(0x1FF), ha->io_addr + IPS_REG_FLAP);
2393 if (ha->revision_id == IPS_REVID_TROMBONE64)
2394 udelay(25);
2395
2396 major = inb(ha->io_addr + IPS_REG_FLDP);
2397
2398
2399 outl(cpu_to_le32(0x1FE), ha->io_addr + IPS_REG_FLAP);
2400 if (ha->revision_id == IPS_REVID_TROMBONE64)
2401 udelay(25);
2402
2403 minor = inb(ha->io_addr + IPS_REG_FLDP);
2404
2405
2406 outl(cpu_to_le32(0x1FD), ha->io_addr + IPS_REG_FLAP);
2407 if (ha->revision_id == IPS_REVID_TROMBONE64)
2408 udelay(25);
2409
2410 subminor = inb(ha->io_addr + IPS_REG_FLDP);
2411
2412 }
2413 } else {
2414
2415
2416 buffer = ha->ioctl_data;
2417
2418 memset(buffer, 0, 0x1000);
2419
2420 scb = &ha->scbs[ha->max_cmds - 1];
2421
2422 ips_init_scb(ha, scb);
2423
2424 scb->timeout = ips_cmd_timeout;
2425 scb->cdb[0] = IPS_CMD_RW_BIOSFW;
2426
2427 scb->cmd.flashfw.op_code = IPS_CMD_RW_BIOSFW;
2428 scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
2429 scb->cmd.flashfw.type = 1;
2430 scb->cmd.flashfw.direction = 0;
2431 scb->cmd.flashfw.count = cpu_to_le32(0x800);
2432 scb->cmd.flashfw.total_packets = 1;
2433 scb->cmd.flashfw.packet_num = 0;
2434 scb->data_len = 0x1000;
2435 scb->cmd.flashfw.buffer_addr = ha->ioctl_busaddr;
2436
2437
2438 if (((ret =
2439 ips_send_wait(ha, scb, ips_cmd_timeout,
2440 intr)) == IPS_FAILURE)
2441 || (ret == IPS_SUCCESS_IMM)
2442 || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
2443
2444
2445 return;
2446 }
2447
2448 if ((buffer[0xC0] == 0x55) && (buffer[0xC1] == 0xAA)) {
2449 major = buffer[0x1ff + 0xC0];
2450 minor = buffer[0x1fe + 0xC0];
2451 subminor = buffer[0x1fd + 0xC0];
2452 } else {
2453 return;
2454 }
2455 }
2456
2457 ha->bios_version[0] = hexDigits[(major & 0xF0) >> 4];
2458 ha->bios_version[1] = '.';
2459 ha->bios_version[2] = hexDigits[major & 0x0F];
2460 ha->bios_version[3] = hexDigits[subminor];
2461 ha->bios_version[4] = '.';
2462 ha->bios_version[5] = hexDigits[(minor & 0xF0) >> 4];
2463 ha->bios_version[6] = hexDigits[minor & 0x0F];
2464 ha->bios_version[7] = 0;
2465}
2466
2467
2468
2469
2470
2471
2472
2473
2474
2475
2476
2477
2478static int
2479ips_hainit(ips_ha_t * ha)
2480{
2481 int i;
2482 struct timeval tv;
2483
2484 METHOD_TRACE("ips_hainit", 1);
2485
2486 if (!ha)
2487 return (0);
2488
2489 if (ha->func.statinit)
2490 (*ha->func.statinit) (ha);
2491
2492 if (ha->func.enableint)
2493 (*ha->func.enableint) (ha);
2494
2495
2496 ha->reset_count = 1;
2497 do_gettimeofday(&tv);
2498 ha->last_ffdc = tv.tv_sec;
2499 ips_ffdc_reset(ha, IPS_INTR_IORL);
2500
2501 if (!ips_read_config(ha, IPS_INTR_IORL)) {
2502 IPS_PRINTK(KERN_WARNING, ha->pcidev,
2503 "unable to read config from controller.\n");
2504
2505 return (0);
2506 }
2507
2508 if (!ips_read_adapter_status(ha, IPS_INTR_IORL)) {
2509 IPS_PRINTK(KERN_WARNING, ha->pcidev,
2510 "unable to read controller status.\n");
2511
2512 return (0);
2513 }
2514
2515
2516 ips_identify_controller(ha);
2517
2518 if (!ips_read_subsystem_parameters(ha, IPS_INTR_IORL)) {
2519 IPS_PRINTK(KERN_WARNING, ha->pcidev,
2520 "unable to read subsystem parameters.\n");
2521
2522 return (0);
2523 }
2524
2525
2526 if (!ips_write_driver_status(ha, IPS_INTR_IORL)) {
2527 IPS_PRINTK(KERN_WARNING, ha->pcidev,
2528 "unable to write driver info to controller.\n");
2529
2530 return (0);
2531 }
2532
2533
2534 if ((ha->conf->ucLogDriveCount > 0) && (ha->requires_esl == 1))
2535 ips_clear_adapter(ha, IPS_INTR_IORL);
2536
2537
2538 ha->ntargets = IPS_MAX_TARGETS + 1;
2539 ha->nlun = 1;
2540 ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS) + 1;
2541
2542 switch (ha->conf->logical_drive[0].ucStripeSize) {
2543 case 4:
2544 ha->max_xfer = 0x10000;
2545 break;
2546
2547 case 5:
2548 ha->max_xfer = 0x20000;
2549 break;
2550
2551 case 6:
2552 ha->max_xfer = 0x40000;
2553 break;
2554
2555 case 7:
2556 default:
2557 ha->max_xfer = 0x80000;
2558 break;
2559 }
2560
2561
2562 if (le32_to_cpu(ha->subsys->param[4]) & 0x1) {
2563
2564 ha->max_cmds = ha->enq->ucConcurrentCmdCount;
2565 } else {
2566
2567 switch (ha->conf->logical_drive[0].ucStripeSize) {
2568 case 4:
2569 ha->max_cmds = 32;
2570 break;
2571
2572 case 5:
2573 ha->max_cmds = 16;
2574 break;
2575
2576 case 6:
2577 ha->max_cmds = 8;
2578 break;
2579
2580 case 7:
2581 default:
2582 ha->max_cmds = 4;
2583 break;
2584 }
2585 }
2586
2587
2588 if ((ha->ad_type == IPS_ADTYPE_SERVERAID3L) ||
2589 (ha->ad_type == IPS_ADTYPE_SERVERAID4L) ||
2590 (ha->ad_type == IPS_ADTYPE_SERVERAID4LX)) {
2591 if ((ha->max_cmds > MaxLiteCmds) && (MaxLiteCmds))
2592 ha->max_cmds = MaxLiteCmds;
2593 }
2594
2595
2596 ha->ha_id[0] = IPS_ADAPTER_ID;
2597 for (i = 1; i < ha->nbus; i++) {
2598 ha->ha_id[i] = ha->conf->init_id[i - 1] & 0x1f;
2599 ha->dcdb_active[i - 1] = 0;
2600 }
2601
2602 return (1);
2603}
2604
2605
2606
2607
2608
2609
2610
2611
2612
2613
2614static void
2615ips_next(ips_ha_t * ha, int intr)
2616{
2617 ips_scb_t *scb;
2618 struct scsi_cmnd *SC;
2619 struct scsi_cmnd *p;
2620 struct scsi_cmnd *q;
2621 ips_copp_wait_item_t *item;
2622 int ret;
2623 struct Scsi_Host *host;
2624 METHOD_TRACE("ips_next", 1);
2625
2626 if (!ha)
2627 return;
2628 host = ips_sh[ha->host_num];
2629
2630
2631
2632
2633 if (intr == IPS_INTR_ON)
2634 spin_lock(host->host_lock);
2635
2636 if ((ha->subsys->param[3] & 0x300000)
2637 && (ha->scb_activelist.count == 0)) {
2638 struct timeval tv;
2639
2640 do_gettimeofday(&tv);
2641
2642 if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) {
2643 ha->last_ffdc = tv.tv_sec;
2644 ips_ffdc_time(ha);
2645 }
2646 }
2647
2648
2649
2650
2651
2652
2653
2654
2655 while ((ha->num_ioctl < IPS_MAX_IOCTL) &&
2656 (ha->copp_waitlist.head) && (scb = ips_getscb(ha))) {
2657
2658 item = ips_removeq_copp_head(&ha->copp_waitlist);
2659 ha->num_ioctl++;
2660 if (intr == IPS_INTR_ON)
2661 spin_unlock(host->host_lock);
2662 scb->scsi_cmd = item->scsi_cmd;
2663 kfree(item);
2664
2665 ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr);
2666
2667 if (intr == IPS_INTR_ON)
2668 spin_lock(host->host_lock);
2669 switch (ret) {
2670 case IPS_FAILURE:
2671 if (scb->scsi_cmd) {
2672 scb->scsi_cmd->result = DID_ERROR << 16;
2673 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2674 }
2675
2676 ips_freescb(ha, scb);
2677 break;
2678 case IPS_SUCCESS_IMM:
2679 if (scb->scsi_cmd) {
2680 scb->scsi_cmd->result = DID_OK << 16;
2681 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2682 }
2683
2684 ips_freescb(ha, scb);
2685 break;
2686 default:
2687 break;
2688 }
2689
2690 if (ret != IPS_SUCCESS) {
2691 ha->num_ioctl--;
2692 continue;
2693 }
2694
2695 ret = ips_send_cmd(ha, scb);
2696
2697 if (ret == IPS_SUCCESS)
2698 ips_putq_scb_head(&ha->scb_activelist, scb);
2699 else
2700 ha->num_ioctl--;
2701
2702 switch (ret) {
2703 case IPS_FAILURE:
2704 if (scb->scsi_cmd) {
2705 scb->scsi_cmd->result = DID_ERROR << 16;
2706 }
2707
2708 ips_freescb(ha, scb);
2709 break;
2710 case IPS_SUCCESS_IMM:
2711 ips_freescb(ha, scb);
2712 break;
2713 default:
2714 break;
2715 }
2716
2717 }
2718
2719
2720
2721
2722
2723 p = ha->scb_waitlist.head;
2724 while ((p) && (scb = ips_getscb(ha))) {
2725 if ((scmd_channel(p) > 0)
2726 && (ha->
2727 dcdb_active[scmd_channel(p) -
2728 1] & (1 << scmd_id(p)))) {
2729 ips_freescb(ha, scb);
2730 p = (struct scsi_cmnd *) p->host_scribble;
2731 continue;
2732 }
2733
2734 q = p;
2735 SC = ips_removeq_wait(&ha->scb_waitlist, q);
2736
2737 if (intr == IPS_INTR_ON)
2738 spin_unlock(host->host_lock);
2739
2740 SC->result = DID_OK;
2741 SC->host_scribble = NULL;
2742
2743 memset(SC->sense_buffer, 0, sizeof (SC->sense_buffer));
2744
2745 scb->target_id = SC->device->id;
2746 scb->lun = SC->device->lun;
2747 scb->bus = SC->device->channel;
2748 scb->scsi_cmd = SC;
2749 scb->breakup = 0;
2750 scb->data_len = 0;
2751 scb->callback = ipsintr_done;
2752 scb->timeout = ips_cmd_timeout;
2753 memset(&scb->cmd, 0, 16);
2754
2755
2756 memcpy(scb->cdb, SC->cmnd, SC->cmd_len);
2757
2758 scb->sg_count = scsi_dma_map(SC);
2759 BUG_ON(scb->sg_count < 0);
2760 if (scb->sg_count) {
2761 struct scatterlist *sg;
2762 int i;
2763
2764 scb->flags |= IPS_SCB_MAP_SG;
2765
2766 scsi_for_each_sg(SC, sg, scb->sg_count, i) {
2767 if (ips_fill_scb_sg_single
2768 (ha, sg_dma_address(sg), scb, i,
2769 sg_dma_len(sg)) < 0)
2770 break;
2771 }
2772 scb->dcdb.transfer_length = scb->data_len;
2773 } else {
2774 scb->data_busaddr = 0L;
2775 scb->sg_len = 0;
2776 scb->data_len = 0;
2777 scb->dcdb.transfer_length = 0;
2778 }
2779
2780 scb->dcdb.cmd_attribute =
2781 ips_command_direction[scb->scsi_cmd->cmnd[0]];
2782
2783
2784
2785 if ((scb->scsi_cmd->cmnd[0] == WRITE_BUFFER) && (scb->data_len == 0))
2786 scb->dcdb.cmd_attribute = 0;
2787
2788 if (!(scb->dcdb.cmd_attribute & 0x3))
2789 scb->dcdb.transfer_length = 0;
2790
2791 if (scb->data_len >= IPS_MAX_XFER) {
2792 scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
2793 scb->dcdb.transfer_length = 0;
2794 }
2795 if (intr == IPS_INTR_ON)
2796 spin_lock(host->host_lock);
2797
2798 ret = ips_send_cmd(ha, scb);
2799
2800 switch (ret) {
2801 case IPS_SUCCESS:
2802 ips_putq_scb_head(&ha->scb_activelist, scb);
2803 break;
2804 case IPS_FAILURE:
2805 if (scb->scsi_cmd) {
2806 scb->scsi_cmd->result = DID_ERROR << 16;
2807 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2808 }
2809
2810 if (scb->bus)
2811 ha->dcdb_active[scb->bus - 1] &=
2812 ~(1 << scb->target_id);
2813
2814 ips_freescb(ha, scb);
2815 break;
2816 case IPS_SUCCESS_IMM:
2817 if (scb->scsi_cmd)
2818 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2819
2820 if (scb->bus)
2821 ha->dcdb_active[scb->bus - 1] &=
2822 ~(1 << scb->target_id);
2823
2824 ips_freescb(ha, scb);
2825 break;
2826 default:
2827 break;
2828 }
2829
2830 p = (struct scsi_cmnd *) p->host_scribble;
2831
2832 }
2833
2834 if (intr == IPS_INTR_ON)
2835 spin_unlock(host->host_lock);
2836}
2837
2838
2839
2840
2841
2842
2843
2844
2845
2846
2847
2848
2849static void
2850ips_putq_scb_head(ips_scb_queue_t * queue, ips_scb_t * item)
2851{
2852 METHOD_TRACE("ips_putq_scb_head", 1);
2853
2854 if (!item)
2855 return;
2856
2857 item->q_next = queue->head;
2858 queue->head = item;
2859
2860 if (!queue->tail)
2861 queue->tail = item;
2862
2863 queue->count++;
2864}
2865
2866
2867
2868
2869
2870
2871
2872
2873
2874
2875
2876
2877static ips_scb_t *
2878ips_removeq_scb_head(ips_scb_queue_t * queue)
2879{
2880 ips_scb_t *item;
2881
2882 METHOD_TRACE("ips_removeq_scb_head", 1);
2883
2884 item = queue->head;
2885
2886 if (!item) {
2887 return (NULL);
2888 }
2889
2890 queue->head = item->q_next;
2891 item->q_next = NULL;
2892
2893 if (queue->tail == item)
2894 queue->tail = NULL;
2895
2896 queue->count--;
2897
2898 return (item);
2899}
2900
2901
2902
2903
2904
2905
2906
2907
2908
2909
2910
2911
2912static ips_scb_t *
2913ips_removeq_scb(ips_scb_queue_t * queue, ips_scb_t * item)
2914{
2915 ips_scb_t *p;
2916
2917 METHOD_TRACE("ips_removeq_scb", 1);
2918
2919 if (!item)
2920 return (NULL);
2921
2922 if (item == queue->head) {
2923 return (ips_removeq_scb_head(queue));
2924 }
2925
2926 p = queue->head;
2927
2928 while ((p) && (item != p->q_next))
2929 p = p->q_next;
2930
2931 if (p) {
2932
2933 p->q_next = item->q_next;
2934
2935 if (!item->q_next)
2936 queue->tail = p;
2937
2938 item->q_next = NULL;
2939 queue->count--;
2940
2941 return (item);
2942 }
2943
2944 return (NULL);
2945}
2946
2947
2948
2949
2950
2951
2952
2953
2954
2955
2956
2957
2958static void ips_putq_wait_tail(ips_wait_queue_t *queue, struct scsi_cmnd *item)
2959{
2960 METHOD_TRACE("ips_putq_wait_tail", 1);
2961
2962 if (!item)
2963 return;
2964
2965 item->host_scribble = NULL;
2966
2967 if (queue->tail)
2968 queue->tail->host_scribble = (char *) item;
2969
2970 queue->tail = item;
2971
2972 if (!queue->head)
2973 queue->head = item;
2974
2975 queue->count++;
2976}
2977
2978
2979
2980
2981
2982
2983
2984
2985
2986
2987
2988
2989static struct scsi_cmnd *ips_removeq_wait_head(ips_wait_queue_t *queue)
2990{
2991 struct scsi_cmnd *item;
2992
2993 METHOD_TRACE("ips_removeq_wait_head", 1);
2994
2995 item = queue->head;
2996
2997 if (!item) {
2998 return (NULL);
2999 }
3000
3001 queue->head = (struct scsi_cmnd *) item->host_scribble;
3002 item->host_scribble = NULL;
3003
3004 if (queue->tail == item)
3005 queue->tail = NULL;
3006
3007 queue->count--;
3008
3009 return (item);
3010}
3011
3012
3013
3014
3015
3016
3017
3018
3019
3020
3021
3022
3023static struct scsi_cmnd *ips_removeq_wait(ips_wait_queue_t *queue,
3024 struct scsi_cmnd *item)
3025{
3026 struct scsi_cmnd *p;
3027
3028 METHOD_TRACE("ips_removeq_wait", 1);
3029
3030 if (!item)
3031 return (NULL);
3032
3033 if (item == queue->head) {
3034 return (ips_removeq_wait_head(queue));
3035 }
3036
3037 p = queue->head;
3038
3039 while ((p) && (item != (struct scsi_cmnd *) p->host_scribble))
3040 p = (struct scsi_cmnd *) p->host_scribble;
3041
3042 if (p) {
3043
3044 p->host_scribble = item->host_scribble;
3045
3046 if (!item->host_scribble)
3047 queue->tail = p;
3048
3049 item->host_scribble = NULL;
3050 queue->count--;
3051
3052 return (item);
3053 }
3054
3055 return (NULL);
3056}
3057
3058
3059
3060
3061
3062
3063
3064
3065
3066
3067
3068
3069static void
3070ips_putq_copp_tail(ips_copp_queue_t * queue, ips_copp_wait_item_t * item)
3071{
3072 METHOD_TRACE("ips_putq_copp_tail", 1);
3073
3074 if (!item)
3075 return;
3076
3077 item->next = NULL;
3078
3079 if (queue->tail)
3080 queue->tail->next = item;
3081
3082 queue->tail = item;
3083
3084 if (!queue->head)
3085 queue->head = item;
3086
3087 queue->count++;
3088}
3089
3090
3091
3092
3093
3094
3095
3096
3097
3098
3099
3100
3101static ips_copp_wait_item_t *
3102ips_removeq_copp_head(ips_copp_queue_t * queue)
3103{
3104 ips_copp_wait_item_t *item;
3105
3106 METHOD_TRACE("ips_removeq_copp_head", 1);
3107
3108 item = queue->head;
3109
3110 if (!item) {
3111 return (NULL);
3112 }
3113
3114 queue->head = item->next;
3115 item->next = NULL;
3116
3117 if (queue->tail == item)
3118 queue->tail = NULL;
3119
3120 queue->count--;
3121
3122 return (item);
3123}
3124
3125
3126
3127
3128
3129
3130
3131
3132
3133
3134
3135
3136static ips_copp_wait_item_t *
3137ips_removeq_copp(ips_copp_queue_t * queue, ips_copp_wait_item_t * item)
3138{
3139 ips_copp_wait_item_t *p;
3140
3141 METHOD_TRACE("ips_removeq_copp", 1);
3142
3143 if (!item)
3144 return (NULL);
3145
3146 if (item == queue->head) {
3147 return (ips_removeq_copp_head(queue));
3148 }
3149
3150 p = queue->head;
3151
3152 while ((p) && (item != p->next))
3153 p = p->next;
3154
3155 if (p) {
3156
3157 p->next = item->next;
3158
3159 if (!item->next)
3160 queue->tail = p;
3161
3162 item->next = NULL;
3163 queue->count--;
3164
3165 return (item);
3166 }
3167
3168 return (NULL);
3169}
3170
3171
3172
3173
3174
3175
3176
3177
3178
3179
3180static void
3181ipsintr_blocking(ips_ha_t * ha, ips_scb_t * scb)
3182{
3183 METHOD_TRACE("ipsintr_blocking", 2);
3184
3185 ips_freescb(ha, scb);
3186 if ((ha->waitflag == TRUE) && (ha->cmd_in_progress == scb->cdb[0])) {
3187 ha->waitflag = FALSE;
3188
3189 return;
3190 }
3191}
3192
3193
3194
3195
3196
3197
3198
3199
3200
3201
3202static void
3203ipsintr_done(ips_ha_t * ha, ips_scb_t * scb)
3204{
3205 METHOD_TRACE("ipsintr_done", 2);
3206
3207 if (!scb) {
3208 IPS_PRINTK(KERN_WARNING, ha->pcidev,
3209 "Spurious interrupt; scb NULL.\n");
3210
3211 return;
3212 }
3213
3214 if (scb->scsi_cmd == NULL) {
3215
3216 IPS_PRINTK(KERN_WARNING, ha->pcidev,
3217 "Spurious interrupt; scsi_cmd not set.\n");
3218
3219 return;
3220 }
3221
3222 ips_done(ha, scb);
3223}
3224
3225
3226
3227
3228
3229
3230
3231
3232
3233
3234static void
3235ips_done(ips_ha_t * ha, ips_scb_t * scb)
3236{
3237 int ret;
3238
3239 METHOD_TRACE("ips_done", 1);
3240
3241 if (!scb)
3242 return;
3243
3244 if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) {
3245 ips_cleanup_passthru(ha, scb);
3246 ha->num_ioctl--;
3247 } else {
3248
3249
3250
3251
3252
3253 if ((scb->breakup) || (scb->sg_break)) {
3254 struct scatterlist *sg;
3255 int i, sg_dma_index, ips_sg_index = 0;
3256
3257
3258 scb->data_len = 0;
3259
3260 sg = scsi_sglist(scb->scsi_cmd);
3261
3262
3263 sg_dma_index = scb->breakup;
3264 for (i = 0; i < scb->breakup; i++)
3265 sg = sg_next(sg);
3266
3267
3268 ips_fill_scb_sg_single(ha,
3269 sg_dma_address(sg),
3270 scb, ips_sg_index++,
3271 sg_dma_len(sg));
3272
3273 for (; sg_dma_index < scsi_sg_count(scb->scsi_cmd);
3274 sg_dma_index++, sg = sg_next(sg)) {
3275 if (ips_fill_scb_sg_single
3276 (ha,
3277 sg_dma_address(sg),
3278 scb, ips_sg_index++,
3279 sg_dma_len(sg)) < 0)
3280 break;
3281 }
3282
3283 scb->dcdb.transfer_length = scb->data_len;
3284 scb->dcdb.cmd_attribute |=
3285 ips_command_direction[scb->scsi_cmd->cmnd[0]];
3286
3287 if (!(scb->dcdb.cmd_attribute & 0x3))
3288 scb->dcdb.transfer_length = 0;
3289
3290 if (scb->data_len >= IPS_MAX_XFER) {
3291 scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
3292 scb->dcdb.transfer_length = 0;
3293 }
3294
3295 ret = ips_send_cmd(ha, scb);
3296
3297 switch (ret) {
3298 case IPS_FAILURE:
3299 if (scb->scsi_cmd) {
3300 scb->scsi_cmd->result = DID_ERROR << 16;
3301 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3302 }
3303
3304 ips_freescb(ha, scb);
3305 break;
3306 case IPS_SUCCESS_IMM:
3307 if (scb->scsi_cmd) {
3308 scb->scsi_cmd->result = DID_ERROR << 16;
3309 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3310 }
3311
3312 ips_freescb(ha, scb);
3313 break;
3314 default:
3315 break;
3316 }
3317
3318 return;
3319 }
3320 }
3321
3322 if (scb->bus) {
3323 ha->dcdb_active[scb->bus - 1] &= ~(1 << scb->target_id);
3324 }
3325
3326 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3327
3328 ips_freescb(ha, scb);
3329}
3330
3331
3332
3333
3334
3335
3336
3337
3338
3339
3340static int
3341ips_map_status(ips_ha_t * ha, ips_scb_t * scb, ips_stat_t * sp)
3342{
3343 int errcode;
3344 int device_error;
3345 uint32_t transfer_len;
3346 IPS_DCDB_TABLE_TAPE *tapeDCDB;
3347 IPS_SCSI_INQ_DATA inquiryData;
3348
3349 METHOD_TRACE("ips_map_status", 1);
3350
3351 if (scb->bus) {
3352 DEBUG_VAR(2,
3353 "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x",
3354 ips_name, ha->host_num,
3355 scb->scsi_cmd->device->channel,
3356 scb->scsi_cmd->device->id, scb->scsi_cmd->device->lun,
3357 scb->basic_status, scb->extended_status,
3358 scb->extended_status ==
3359 IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0,
3360 scb->extended_status ==
3361 IPS_ERR_CKCOND ? scb->dcdb.sense_info[12] : 0,
3362 scb->extended_status ==
3363 IPS_ERR_CKCOND ? scb->dcdb.sense_info[13] : 0);
3364 }
3365
3366
3367 errcode = DID_ERROR;
3368 device_error = 0;
3369
3370 switch (scb->basic_status & IPS_GSC_STATUS_MASK) {
3371 case IPS_CMD_TIMEOUT:
3372 errcode = DID_TIME_OUT;
3373 break;
3374
3375 case IPS_INVAL_OPCO:
3376 case IPS_INVAL_CMD_BLK:
3377 case IPS_INVAL_PARM_BLK:
3378 case IPS_LD_ERROR:
3379 case IPS_CMD_CMPLT_WERROR:
3380 break;
3381
3382 case IPS_PHYS_DRV_ERROR:
3383 switch (scb->extended_status) {
3384 case IPS_ERR_SEL_TO:
3385 if (scb->bus)
3386 errcode = DID_NO_CONNECT;
3387
3388 break;
3389
3390 case IPS_ERR_OU_RUN:
3391 if ((scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB) ||
3392 (scb->cmd.dcdb.op_code ==
3393 IPS_CMD_EXTENDED_DCDB_SG)) {
3394 tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
3395 transfer_len = tapeDCDB->transfer_length;
3396 } else {
3397 transfer_len =
3398 (uint32_t) scb->dcdb.transfer_length;
3399 }
3400
3401 if ((scb->bus) && (transfer_len < scb->data_len)) {
3402
3403 errcode = DID_OK;
3404
3405
3406 if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
3407 ips_scmd_buf_read(scb->scsi_cmd,
3408 &inquiryData, sizeof (inquiryData));
3409 if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK) {
3410 errcode = DID_TIME_OUT;
3411 break;
3412 }
3413 }
3414 } else
3415 errcode = DID_ERROR;
3416
3417 break;
3418
3419 case IPS_ERR_RECOVERY:
3420
3421 if (scb->bus)
3422 errcode = DID_OK;
3423
3424 break;
3425
3426 case IPS_ERR_HOST_RESET:
3427 case IPS_ERR_DEV_RESET:
3428 errcode = DID_RESET;
3429 break;
3430
3431 case IPS_ERR_CKCOND:
3432 if (scb->bus) {
3433 if ((scb->cmd.dcdb.op_code ==
3434 IPS_CMD_EXTENDED_DCDB)
3435 || (scb->cmd.dcdb.op_code ==
3436 IPS_CMD_EXTENDED_DCDB_SG)) {
3437 tapeDCDB =
3438 (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
3439 memcpy(scb->scsi_cmd->sense_buffer,
3440 tapeDCDB->sense_info,
3441 sizeof (scb->scsi_cmd->
3442 sense_buffer));
3443 } else {
3444 memcpy(scb->scsi_cmd->sense_buffer,
3445 scb->dcdb.sense_info,
3446 sizeof (scb->scsi_cmd->
3447 sense_buffer));
3448 }
3449 device_error = 2;
3450 }
3451
3452 errcode = DID_OK;
3453
3454 break;
3455
3456 default:
3457 errcode = DID_ERROR;
3458 break;
3459
3460 }
3461 }
3462
3463 scb->scsi_cmd->result = device_error | (errcode << 16);
3464
3465 return (1);
3466}
3467
3468
3469
3470
3471
3472
3473
3474
3475
3476
3477
3478
3479static int
3480ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr)
3481{
3482 int ret;
3483
3484 METHOD_TRACE("ips_send_wait", 1);
3485
3486 if (intr != IPS_FFDC) {
3487 ha->waitflag = TRUE;
3488 ha->cmd_in_progress = scb->cdb[0];
3489 }
3490 scb->callback = ipsintr_blocking;
3491 ret = ips_send_cmd(ha, scb);
3492
3493 if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
3494 return (ret);
3495
3496 if (intr != IPS_FFDC)
3497 ret = ips_wait(ha, timeout, intr);
3498
3499 return (ret);
3500}
3501
3502
3503
3504
3505
3506
3507
3508
3509static void
3510ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
3511{
3512 int i;
3513 unsigned int min_cnt, xfer_cnt;
3514 char *cdata = (char *) data;
3515 unsigned char *buffer;
3516 unsigned long flags;
3517 struct scatterlist *sg = scsi_sglist(scmd);
3518
3519 for (i = 0, xfer_cnt = 0;
3520 (i < scsi_sg_count(scmd)) && (xfer_cnt < count); i++) {
3521 min_cnt = min(count - xfer_cnt, sg[i].length);
3522
3523
3524
3525 local_irq_save(flags);
3526 buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
3527 memcpy(buffer, &cdata[xfer_cnt], min_cnt);
3528 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
3529 local_irq_restore(flags);
3530
3531 xfer_cnt += min_cnt;
3532 }
3533}
3534
3535
3536
3537
3538
3539
3540
3541
3542static void
3543ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
3544{
3545 int i;
3546 unsigned int min_cnt, xfer_cnt;
3547 char *cdata = (char *) data;
3548 unsigned char *buffer;
3549 unsigned long flags;
3550 struct scatterlist *sg = scsi_sglist(scmd);
3551
3552 for (i = 0, xfer_cnt = 0;
3553 (i < scsi_sg_count(scmd)) && (xfer_cnt < count); i++) {
3554 min_cnt = min(count - xfer_cnt, sg[i].length);
3555
3556
3557
3558 local_irq_save(flags);
3559 buffer = kmap_atomic(sg_page(&sg[i]), KM_IRQ0) + sg[i].offset;
3560 memcpy(&cdata[xfer_cnt], buffer, min_cnt);
3561 kunmap_atomic(buffer - sg[i].offset, KM_IRQ0);
3562 local_irq_restore(flags);
3563
3564 xfer_cnt += min_cnt;
3565 }
3566}
3567
3568
3569
3570
3571
3572
3573
3574
3575
3576
3577static int
3578ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb)
3579{
3580 int ret;
3581 char *sp;
3582 int device_error;
3583 IPS_DCDB_TABLE_TAPE *tapeDCDB;
3584 int TimeOut;
3585
3586 METHOD_TRACE("ips_send_cmd", 1);
3587
3588 ret = IPS_SUCCESS;
3589
3590 if (!scb->scsi_cmd) {
3591
3592
3593 if (scb->bus > 0) {
3594
3595
3596 if ((ha->waitflag == TRUE) &&
3597 (ha->cmd_in_progress == scb->cdb[0])) {
3598 ha->waitflag = FALSE;
3599 }
3600
3601 return (1);
3602 }
3603 } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) {
3604
3605 ret = IPS_SUCCESS_IMM;
3606
3607 switch (scb->scsi_cmd->cmnd[0]) {
3608 case ALLOW_MEDIUM_REMOVAL:
3609 case REZERO_UNIT:
3610 case ERASE:
3611 case WRITE_FILEMARKS:
3612 case SPACE:
3613 scb->scsi_cmd->result = DID_ERROR << 16;
3614 break;
3615
3616 case START_STOP:
3617 scb->scsi_cmd->result = DID_OK << 16;
3618
3619 case TEST_UNIT_READY:
3620 case INQUIRY:
3621 if (scb->target_id == IPS_ADAPTER_ID) {
3622
3623
3624
3625
3626 if (scb->scsi_cmd->cmnd[0] == TEST_UNIT_READY)
3627 scb->scsi_cmd->result = DID_OK << 16;
3628
3629 if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
3630 IPS_SCSI_INQ_DATA inquiry;
3631
3632 memset(&inquiry, 0,
3633 sizeof (IPS_SCSI_INQ_DATA));
3634
3635 inquiry.DeviceType =
3636 IPS_SCSI_INQ_TYPE_PROCESSOR;
3637 inquiry.DeviceTypeQualifier =
3638 IPS_SCSI_INQ_LU_CONNECTED;
3639 inquiry.Version = IPS_SCSI_INQ_REV2;
3640 inquiry.ResponseDataFormat =
3641 IPS_SCSI_INQ_RD_REV2;
3642 inquiry.AdditionalLength = 31;
3643 inquiry.Flags[0] =
3644 IPS_SCSI_INQ_Address16;
3645 inquiry.Flags[1] =
3646 IPS_SCSI_INQ_WBus16 |
3647 IPS_SCSI_INQ_Sync;
3648 strncpy(inquiry.VendorId, "IBM ",
3649 8);
3650 strncpy(inquiry.ProductId,
3651 "SERVERAID ", 16);
3652 strncpy(inquiry.ProductRevisionLevel,
3653 "1.00", 4);
3654
3655 ips_scmd_buf_write(scb->scsi_cmd,
3656 &inquiry,
3657 sizeof (inquiry));
3658
3659 scb->scsi_cmd->result = DID_OK << 16;
3660 }
3661 } else {
3662 scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
3663 scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
3664 scb->cmd.logical_info.reserved = 0;
3665 scb->cmd.logical_info.reserved2 = 0;
3666 scb->data_len = sizeof (IPS_LD_INFO);
3667 scb->data_busaddr = ha->logical_drive_info_dma_addr;
3668 scb->flags = 0;
3669 scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
3670 ret = IPS_SUCCESS;
3671 }
3672
3673 break;
3674
3675 case REQUEST_SENSE:
3676 ips_reqsen(ha, scb);
3677 scb->scsi_cmd->result = DID_OK << 16;
3678 break;
3679
3680 case READ_6:
3681 case WRITE_6:
3682 if (!scb->sg_len) {
3683 scb->cmd.basic_io.op_code =
3684 (scb->scsi_cmd->cmnd[0] ==
3685 READ_6) ? IPS_CMD_READ : IPS_CMD_WRITE;
3686 scb->cmd.basic_io.enhanced_sg = 0;
3687 scb->cmd.basic_io.sg_addr =
3688 cpu_to_le32(scb->data_busaddr);
3689 } else {
3690 scb->cmd.basic_io.op_code =
3691 (scb->scsi_cmd->cmnd[0] ==
3692 READ_6) ? IPS_CMD_READ_SG :
3693 IPS_CMD_WRITE_SG;
3694 scb->cmd.basic_io.enhanced_sg =
3695 IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3696 scb->cmd.basic_io.sg_addr =
3697 cpu_to_le32(scb->sg_busaddr);
3698 }
3699
3700 scb->cmd.basic_io.segment_4G = 0;
3701 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3702 scb->cmd.basic_io.log_drv = scb->target_id;
3703 scb->cmd.basic_io.sg_count = scb->sg_len;
3704
3705 if (scb->cmd.basic_io.lba)
3706 scb->cmd.basic_io.lba =
3707 cpu_to_le32(le32_to_cpu
3708 (scb->cmd.basic_io.lba) +
3709 le16_to_cpu(scb->cmd.basic_io.
3710 sector_count));
3711 else
3712 scb->cmd.basic_io.lba =
3713 (((scb->scsi_cmd->
3714 cmnd[1] & 0x1f) << 16) | (scb->scsi_cmd->
3715 cmnd[2] << 8) |
3716 (scb->scsi_cmd->cmnd[3]));
3717
3718 scb->cmd.basic_io.sector_count =
3719 cpu_to_le16(scb->data_len / IPS_BLKSIZE);
3720
3721 if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0)
3722 scb->cmd.basic_io.sector_count =
3723 cpu_to_le16(256);
3724
3725 ret = IPS_SUCCESS;
3726 break;
3727
3728 case READ_10:
3729 case WRITE_10:
3730 if (!scb->sg_len) {
3731 scb->cmd.basic_io.op_code =
3732 (scb->scsi_cmd->cmnd[0] ==
3733 READ_10) ? IPS_CMD_READ : IPS_CMD_WRITE;
3734 scb->cmd.basic_io.enhanced_sg = 0;
3735 scb->cmd.basic_io.sg_addr =
3736 cpu_to_le32(scb->data_busaddr);
3737 } else {
3738 scb->cmd.basic_io.op_code =
3739 (scb->scsi_cmd->cmnd[0] ==
3740 READ_10) ? IPS_CMD_READ_SG :
3741 IPS_CMD_WRITE_SG;
3742 scb->cmd.basic_io.enhanced_sg =
3743 IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3744 scb->cmd.basic_io.sg_addr =
3745 cpu_to_le32(scb->sg_busaddr);
3746 }
3747
3748 scb->cmd.basic_io.segment_4G = 0;
3749 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3750 scb->cmd.basic_io.log_drv = scb->target_id;
3751 scb->cmd.basic_io.sg_count = scb->sg_len;
3752
3753 if (scb->cmd.basic_io.lba)
3754 scb->cmd.basic_io.lba =
3755 cpu_to_le32(le32_to_cpu
3756 (scb->cmd.basic_io.lba) +
3757 le16_to_cpu(scb->cmd.basic_io.
3758 sector_count));
3759 else
3760 scb->cmd.basic_io.lba =
3761 ((scb->scsi_cmd->cmnd[2] << 24) | (scb->
3762 scsi_cmd->
3763 cmnd[3]
3764 << 16) |
3765 (scb->scsi_cmd->cmnd[4] << 8) | scb->
3766 scsi_cmd->cmnd[5]);
3767
3768 scb->cmd.basic_io.sector_count =
3769 cpu_to_le16(scb->data_len / IPS_BLKSIZE);
3770
3771 if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) {
3772
3773
3774
3775
3776
3777 scb->scsi_cmd->result = DID_OK << 16;
3778 } else
3779 ret = IPS_SUCCESS;
3780
3781 break;
3782
3783 case RESERVE:
3784 case RELEASE:
3785 scb->scsi_cmd->result = DID_OK << 16;
3786 break;
3787
3788 case MODE_SENSE:
3789 scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
3790 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3791 scb->cmd.basic_io.segment_4G = 0;
3792 scb->cmd.basic_io.enhanced_sg = 0;
3793 scb->data_len = sizeof (*ha->enq);
3794 scb->cmd.basic_io.sg_addr = ha->enq_busaddr;
3795 ret = IPS_SUCCESS;
3796 break;
3797
3798 case READ_CAPACITY:
3799 scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
3800 scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
3801 scb->cmd.logical_info.reserved = 0;
3802 scb->cmd.logical_info.reserved2 = 0;
3803 scb->cmd.logical_info.reserved3 = 0;
3804 scb->data_len = sizeof (IPS_LD_INFO);
3805 scb->data_busaddr = ha->logical_drive_info_dma_addr;
3806 scb->flags = 0;
3807 scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
3808 ret = IPS_SUCCESS;
3809 break;
3810
3811 case SEND_DIAGNOSTIC:
3812 case REASSIGN_BLOCKS:
3813 case FORMAT_UNIT:
3814 case SEEK_10:
3815 case VERIFY:
3816 case READ_DEFECT_DATA:
3817 case READ_BUFFER:
3818 case WRITE_BUFFER:
3819 scb->scsi_cmd->result = DID_OK << 16;
3820 break;
3821
3822 default:
3823
3824
3825
3826 sp = (char *) scb->scsi_cmd->sense_buffer;
3827 memset(sp, 0, sizeof (scb->scsi_cmd->sense_buffer));
3828
3829 sp[0] = 0x70;
3830 sp[2] = ILLEGAL_REQUEST;
3831 sp[7] = 0x0A;
3832 sp[12] = 0x20;
3833 sp[13] = 0x00;
3834
3835 device_error = 2;
3836 scb->scsi_cmd->result = device_error | (DID_OK << 16);
3837 break;
3838 }
3839 }
3840
3841 if (ret == IPS_SUCCESS_IMM)
3842 return (ret);
3843
3844
3845 if (scb->bus > 0) {
3846
3847
3848
3849 if (ha->conf->dev[scb->bus - 1][scb->target_id].ucState == 0) {
3850 scb->scsi_cmd->result = DID_NO_CONNECT << 16;
3851 return (IPS_SUCCESS_IMM);
3852 }
3853
3854 ha->dcdb_active[scb->bus - 1] |= (1 << scb->target_id);
3855 scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb);
3856 scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
3857 (unsigned long) &scb->
3858 dcdb -
3859 (unsigned long) scb);
3860 scb->cmd.dcdb.reserved = 0;
3861 scb->cmd.dcdb.reserved2 = 0;
3862 scb->cmd.dcdb.reserved3 = 0;
3863 scb->cmd.dcdb.segment_4G = 0;
3864 scb->cmd.dcdb.enhanced_sg = 0;
3865
3866 TimeOut = scb->scsi_cmd->timeout_per_command;
3867
3868 if (ha->subsys->param[4] & 0x00100000) {
3869 if (!scb->sg_len) {
3870 scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB;
3871 } else {
3872 scb->cmd.dcdb.op_code =
3873 IPS_CMD_EXTENDED_DCDB_SG;
3874 scb->cmd.dcdb.enhanced_sg =
3875 IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3876 }
3877
3878 tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
3879 tapeDCDB->device_address =
3880 ((scb->bus - 1) << 4) | scb->target_id;
3881 tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED;
3882 tapeDCDB->cmd_attribute &= ~IPS_TRANSFER64K;
3883
3884 if (TimeOut) {
3885 if (TimeOut < (10 * HZ))
3886 tapeDCDB->cmd_attribute |= IPS_TIMEOUT10;
3887 else if (TimeOut < (60 * HZ))
3888 tapeDCDB->cmd_attribute |= IPS_TIMEOUT60;
3889 else if (TimeOut < (1200 * HZ))
3890 tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M;
3891 }
3892
3893 tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len;
3894 tapeDCDB->reserved_for_LUN = 0;
3895 tapeDCDB->transfer_length = scb->data_len;
3896 if (scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG)
3897 tapeDCDB->buffer_pointer =
3898 cpu_to_le32(scb->sg_busaddr);
3899 else
3900 tapeDCDB->buffer_pointer =
3901 cpu_to_le32(scb->data_busaddr);
3902 tapeDCDB->sg_count = scb->sg_len;
3903 tapeDCDB->sense_length = sizeof (tapeDCDB->sense_info);
3904 tapeDCDB->scsi_status = 0;
3905 tapeDCDB->reserved = 0;
3906 memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd,
3907 scb->scsi_cmd->cmd_len);
3908 } else {
3909 if (!scb->sg_len) {
3910 scb->cmd.dcdb.op_code = IPS_CMD_DCDB;
3911 } else {
3912 scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG;
3913 scb->cmd.dcdb.enhanced_sg =
3914 IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3915 }
3916
3917 scb->dcdb.device_address =
3918 ((scb->bus - 1) << 4) | scb->target_id;
3919 scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED;
3920
3921 if (TimeOut) {
3922 if (TimeOut < (10 * HZ))
3923 scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
3924 else if (TimeOut < (60 * HZ))
3925 scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
3926 else if (TimeOut < (1200 * HZ))
3927 scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
3928 }
3929
3930 scb->dcdb.transfer_length = scb->data_len;
3931 if (scb->dcdb.cmd_attribute & IPS_TRANSFER64K)
3932 scb->dcdb.transfer_length = 0;
3933 if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB_SG)
3934 scb->dcdb.buffer_pointer =
3935 cpu_to_le32(scb->sg_busaddr);
3936 else
3937 scb->dcdb.buffer_pointer =
3938 cpu_to_le32(scb->data_busaddr);
3939 scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len;
3940 scb->dcdb.sense_length = sizeof (scb->dcdb.sense_info);
3941 scb->dcdb.sg_count = scb->sg_len;
3942 scb->dcdb.reserved = 0;
3943 memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd,
3944 scb->scsi_cmd->cmd_len);
3945 scb->dcdb.scsi_status = 0;
3946 scb->dcdb.reserved2[0] = 0;
3947 scb->dcdb.reserved2[1] = 0;
3948 scb->dcdb.reserved2[2] = 0;
3949 }
3950 }
3951
3952 return ((*ha->func.issue) (ha, scb));
3953}
3954
3955
3956
3957
3958
3959
3960
3961
3962
3963
3964static void
3965ips_chkstatus(ips_ha_t * ha, IPS_STATUS * pstatus)
3966{
3967 ips_scb_t *scb;
3968 ips_stat_t *sp;
3969 uint8_t basic_status;
3970 uint8_t ext_status;
3971 int errcode;
3972 IPS_SCSI_INQ_DATA inquiryData;
3973
3974 METHOD_TRACE("ips_chkstatus", 1);
3975
3976 scb = &ha->scbs[pstatus->fields.command_id];
3977 scb->basic_status = basic_status =
3978 pstatus->fields.basic_status & IPS_BASIC_STATUS_MASK;
3979 scb->extended_status = ext_status = pstatus->fields.extended_status;
3980
3981 sp = &ha->sp;
3982 sp->residue_len = 0;
3983 sp->scb_addr = (void *) scb;
3984
3985
3986 ips_removeq_scb(&ha->scb_activelist, scb);
3987
3988 if (!scb->scsi_cmd)
3989
3990 return;
3991
3992 DEBUG_VAR(2, "(%s%d) ips_chkstatus: cmd 0x%X id %d (%d %d %d)",
3993 ips_name,
3994 ha->host_num,
3995 scb->cdb[0],
3996 scb->cmd.basic_io.command_id,
3997 scb->bus, scb->target_id, scb->lun);
3998
3999 if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd)))
4000
4001 return;
4002
4003 errcode = DID_OK;
4004
4005 if (((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_SUCCESS) ||
4006 ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR)) {
4007
4008 if (scb->bus == 0) {
4009 if ((basic_status & IPS_GSC_STATUS_MASK) ==
4010 IPS_CMD_RECOVERED_ERROR) {
4011 DEBUG_VAR(1,
4012 "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
4013 ips_name, ha->host_num,
4014 scb->cmd.basic_io.op_code,
4015 basic_status, ext_status);
4016 }
4017
4018 switch (scb->scsi_cmd->cmnd[0]) {
4019 case ALLOW_MEDIUM_REMOVAL:
4020 case REZERO_UNIT:
4021 case ERASE:
4022 case WRITE_FILEMARKS:
4023 case SPACE:
4024 errcode = DID_ERROR;
4025 break;
4026
4027 case START_STOP:
4028 break;
4029
4030 case TEST_UNIT_READY:
4031 if (!ips_online(ha, scb)) {
4032 errcode = DID_TIME_OUT;
4033 }
4034 break;
4035
4036 case INQUIRY:
4037 if (ips_online(ha, scb)) {
4038 ips_inquiry(ha, scb);
4039 } else {
4040 errcode = DID_TIME_OUT;
4041 }
4042 break;
4043
4044 case REQUEST_SENSE:
4045 ips_reqsen(ha, scb);
4046 break;
4047
4048 case READ_6:
4049 case WRITE_6:
4050 case READ_10:
4051 case WRITE_10:
4052 case RESERVE:
4053 case RELEASE:
4054 break;
4055
4056 case MODE_SENSE:
4057 if (!ips_online(ha, scb)
4058 || !ips_msense(ha, scb)) {
4059 errcode = DID_ERROR;
4060 }
4061 break;
4062
4063 case READ_CAPACITY:
4064 if (ips_online(ha, scb))
4065 ips_rdcap(ha, scb);
4066 else {
4067 errcode = DID_TIME_OUT;
4068 }
4069 break;
4070
4071 case SEND_DIAGNOSTIC:
4072 case REASSIGN_BLOCKS:
4073 break;
4074
4075 case FORMAT_UNIT:
4076 errcode = DID_ERROR;
4077 break;
4078
4079 case SEEK_10:
4080 case VERIFY:
4081 case READ_DEFECT_DATA:
4082 case READ_BUFFER:
4083 case WRITE_BUFFER:
4084 break;
4085
4086 default:
4087 errcode = DID_ERROR;
4088 }
4089
4090 scb->scsi_cmd->result = errcode << 16;
4091 } else {
4092
4093 if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
4094 ips_scmd_buf_read(scb->scsi_cmd,
4095 &inquiryData, sizeof (inquiryData));
4096 if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK)
4097 scb->scsi_cmd->result = DID_TIME_OUT << 16;
4098 }
4099 }
4100 } else {
4101 if (scb->bus == 0) {
4102 DEBUG_VAR(1,
4103 "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
4104 ips_name, ha->host_num,
4105 scb->cmd.basic_io.op_code, basic_status,
4106 ext_status);
4107 }
4108
4109 ips_map_status(ha, scb, sp);
4110 }
4111}
4112
4113
4114
4115
4116
4117
4118
4119
4120
4121
4122static int
4123ips_online(ips_ha_t * ha, ips_scb_t * scb)
4124{
4125 METHOD_TRACE("ips_online", 1);
4126
4127 if (scb->target_id >= IPS_MAX_LD)
4128 return (0);
4129
4130 if ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1) {
4131 memset(ha->logical_drive_info, 0, sizeof (IPS_LD_INFO));
4132 return (0);
4133 }
4134
4135 if (ha->logical_drive_info->drive_info[scb->target_id].state !=
4136 IPS_LD_OFFLINE
4137 && ha->logical_drive_info->drive_info[scb->target_id].state !=
4138 IPS_LD_FREE
4139 && ha->logical_drive_info->drive_info[scb->target_id].state !=
4140 IPS_LD_CRS
4141 && ha->logical_drive_info->drive_info[scb->target_id].state !=
4142 IPS_LD_SYS)
4143 return (1);
4144 else
4145 return (0);
4146}
4147
4148
4149
4150
4151
4152
4153
4154
4155
4156
4157static int
4158ips_inquiry(ips_ha_t * ha, ips_scb_t * scb)
4159{
4160 IPS_SCSI_INQ_DATA inquiry;
4161
4162 METHOD_TRACE("ips_inquiry", 1);
4163
4164 memset(&inquiry, 0, sizeof (IPS_SCSI_INQ_DATA));
4165
4166 inquiry.DeviceType = IPS_SCSI_INQ_TYPE_DASD;
4167 inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED;
4168 inquiry.Version = IPS_SCSI_INQ_REV2;
4169 inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2;
4170 inquiry.AdditionalLength = 31;
4171 inquiry.Flags[0] = IPS_SCSI_INQ_Address16;
4172 inquiry.Flags[1] =
4173 IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync | IPS_SCSI_INQ_CmdQue;
4174 strncpy(inquiry.VendorId, "IBM ", 8);
4175 strncpy(inquiry.ProductId, "SERVERAID ", 16);
4176 strncpy(inquiry.ProductRevisionLevel, "1.00", 4);
4177
4178 ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof (inquiry));
4179
4180 return (1);
4181}
4182
4183
4184
4185
4186
4187
4188
4189
4190
4191
4192static int
4193ips_rdcap(ips_ha_t * ha, ips_scb_t * scb)
4194{
4195 IPS_SCSI_CAPACITY cap;
4196
4197 METHOD_TRACE("ips_rdcap", 1);
4198
4199 if (scsi_bufflen(scb->scsi_cmd) < 8)
4200 return (0);
4201
4202 cap.lba =
4203 cpu_to_be32(le32_to_cpu
4204 (ha->logical_drive_info->
4205 drive_info[scb->target_id].sector_count) - 1);
4206 cap.len = cpu_to_be32((uint32_t) IPS_BLKSIZE);
4207
4208 ips_scmd_buf_write(scb->scsi_cmd, &cap, sizeof (cap));
4209
4210 return (1);
4211}
4212
4213
4214
4215
4216
4217
4218
4219
4220
4221
4222static int
4223ips_msense(ips_ha_t * ha, ips_scb_t * scb)
4224{
4225 uint16_t heads;
4226 uint16_t sectors;
4227 uint32_t cylinders;
4228 IPS_SCSI_MODE_PAGE_DATA mdata;
4229
4230 METHOD_TRACE("ips_msense", 1);
4231
4232 if (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) > 0x400000 &&
4233 (ha->enq->ucMiscFlag & 0x8) == 0) {
4234 heads = IPS_NORM_HEADS;
4235 sectors = IPS_NORM_SECTORS;
4236 } else {
4237 heads = IPS_COMP_HEADS;
4238 sectors = IPS_COMP_SECTORS;
4239 }
4240
4241 cylinders =
4242 (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) -
4243 1) / (heads * sectors);
4244
4245 memset(&mdata, 0, sizeof (IPS_SCSI_MODE_PAGE_DATA));
4246
4247 mdata.hdr.BlockDescLength = 8;
4248
4249 switch (scb->scsi_cmd->cmnd[2] & 0x3f) {
4250 case 0x03:
4251 mdata.pdata.pg3.PageCode = 3;
4252 mdata.pdata.pg3.PageLength = sizeof (IPS_SCSI_MODE_PAGE3);
4253 mdata.hdr.DataLength =
4254 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg3.PageLength;
4255 mdata.pdata.pg3.TracksPerZone = 0;
4256 mdata.pdata.pg3.AltSectorsPerZone = 0;
4257 mdata.pdata.pg3.AltTracksPerZone = 0;
4258 mdata.pdata.pg3.AltTracksPerVolume = 0;
4259 mdata.pdata.pg3.SectorsPerTrack = cpu_to_be16(sectors);
4260 mdata.pdata.pg3.BytesPerSector = cpu_to_be16(IPS_BLKSIZE);
4261 mdata.pdata.pg3.Interleave = cpu_to_be16(1);
4262 mdata.pdata.pg3.TrackSkew = 0;
4263 mdata.pdata.pg3.CylinderSkew = 0;
4264 mdata.pdata.pg3.flags = IPS_SCSI_MP3_SoftSector;
4265 break;
4266
4267 case 0x4:
4268 mdata.pdata.pg4.PageCode = 4;
4269 mdata.pdata.pg4.PageLength = sizeof (IPS_SCSI_MODE_PAGE4);
4270 mdata.hdr.DataLength =
4271 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg4.PageLength;
4272 mdata.pdata.pg4.CylindersHigh =
4273 cpu_to_be16((cylinders >> 8) & 0xFFFF);
4274 mdata.pdata.pg4.CylindersLow = (cylinders & 0xFF);
4275 mdata.pdata.pg4.Heads = heads;
4276 mdata.pdata.pg4.WritePrecompHigh = 0;
4277 mdata.pdata.pg4.WritePrecompLow = 0;
4278 mdata.pdata.pg4.ReducedWriteCurrentHigh = 0;
4279 mdata.pdata.pg4.ReducedWriteCurrentLow = 0;
4280 mdata.pdata.pg4.StepRate = cpu_to_be16(1);
4281 mdata.pdata.pg4.LandingZoneHigh = 0;
4282 mdata.pdata.pg4.LandingZoneLow = 0;
4283 mdata.pdata.pg4.flags = 0;
4284 mdata.pdata.pg4.RotationalOffset = 0;
4285 mdata.pdata.pg4.MediumRotationRate = 0;
4286 break;
4287 case 0x8:
4288 mdata.pdata.pg8.PageCode = 8;
4289 mdata.pdata.pg8.PageLength = sizeof (IPS_SCSI_MODE_PAGE8);
4290 mdata.hdr.DataLength =
4291 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg8.PageLength;
4292
4293 break;
4294
4295 default:
4296 return (0);
4297 }
4298
4299 ips_scmd_buf_write(scb->scsi_cmd, &mdata, sizeof (mdata));
4300
4301 return (1);
4302}
4303
4304
4305
4306
4307
4308
4309
4310
4311
4312
4313static int
4314ips_reqsen(ips_ha_t * ha, ips_scb_t * scb)
4315{
4316 IPS_SCSI_REQSEN reqsen;
4317
4318 METHOD_TRACE("ips_reqsen", 1);
4319
4320 memset(&reqsen, 0, sizeof (IPS_SCSI_REQSEN));
4321
4322 reqsen.ResponseCode =
4323 IPS_SCSI_REQSEN_VALID | IPS_SCSI_REQSEN_CURRENT_ERR;
4324 reqsen.AdditionalLength = 10;
4325 reqsen.AdditionalSenseCode = IPS_SCSI_REQSEN_NO_SENSE;
4326 reqsen.AdditionalSenseCodeQual = IPS_SCSI_REQSEN_NO_SENSE;
4327
4328 ips_scmd_buf_write(scb->scsi_cmd, &reqsen, sizeof (reqsen));
4329
4330 return (1);
4331}
4332
4333
4334
4335
4336
4337
4338
4339
4340
4341
4342static void
4343ips_free(ips_ha_t * ha)
4344{
4345
4346 METHOD_TRACE("ips_free", 1);
4347
4348 if (ha) {
4349 if (ha->enq) {
4350 pci_free_consistent(ha->pcidev, sizeof(IPS_ENQ),
4351 ha->enq, ha->enq_busaddr);
4352 ha->enq = NULL;
4353 }
4354
4355 kfree(ha->conf);
4356 ha->conf = NULL;
4357
4358 if (ha->adapt) {
4359 pci_free_consistent(ha->pcidev,
4360 sizeof (IPS_ADAPTER) +
4361 sizeof (IPS_IO_CMD), ha->adapt,
4362 ha->adapt->hw_status_start);
4363 ha->adapt = NULL;
4364 }
4365
4366 if (ha->logical_drive_info) {
4367 pci_free_consistent(ha->pcidev,
4368 sizeof (IPS_LD_INFO),
4369 ha->logical_drive_info,
4370 ha->logical_drive_info_dma_addr);
4371 ha->logical_drive_info = NULL;
4372 }
4373
4374 kfree(ha->nvram);
4375 ha->nvram = NULL;
4376
4377 kfree(ha->subsys);
4378 ha->subsys = NULL;
4379
4380 if (ha->ioctl_data) {
4381 pci_free_consistent(ha->pcidev, ha->ioctl_len,
4382 ha->ioctl_data, ha->ioctl_busaddr);
4383 ha->ioctl_data = NULL;
4384 ha->ioctl_datasize = 0;
4385 ha->ioctl_len = 0;
4386 }
4387 ips_deallocatescbs(ha, ha->max_cmds);
4388
4389
4390 if (ha->mem_ptr) {
4391 iounmap(ha->ioremap_ptr);
4392 ha->ioremap_ptr = NULL;
4393 ha->mem_ptr = NULL;
4394 }
4395
4396 if (ha->mem_addr)
4397 release_mem_region(ha->mem_addr, ha->mem_len);
4398 ha->mem_addr = 0;
4399
4400 }
4401}
4402
4403
4404
4405
4406
4407
4408
4409
4410
4411
4412static int
4413ips_deallocatescbs(ips_ha_t * ha, int cmds)
4414{
4415 if (ha->scbs) {
4416 pci_free_consistent(ha->pcidev,
4417 IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * cmds,
4418 ha->scbs->sg_list.list,
4419 ha->scbs->sg_busaddr);
4420 pci_free_consistent(ha->pcidev, sizeof (ips_scb_t) * cmds,
4421 ha->scbs, ha->scbs->scb_busaddr);
4422 ha->scbs = NULL;
4423 }
4424 return 1;
4425}
4426
4427
4428
4429
4430
4431
4432
4433
4434
4435
4436static int
4437ips_allocatescbs(ips_ha_t * ha)
4438{
4439 ips_scb_t *scb_p;
4440 IPS_SG_LIST ips_sg;
4441 int i;
4442 dma_addr_t command_dma, sg_dma;
4443
4444 METHOD_TRACE("ips_allocatescbs", 1);
4445
4446
4447 ha->scbs =
4448 pci_alloc_consistent(ha->pcidev, ha->max_cmds * sizeof (ips_scb_t),
4449 &command_dma);
4450 if (ha->scbs == NULL)
4451 return 0;
4452 ips_sg.list =
4453 pci_alloc_consistent(ha->pcidev,
4454 IPS_SGLIST_SIZE(ha) * IPS_MAX_SG *
4455 ha->max_cmds, &sg_dma);
4456 if (ips_sg.list == NULL) {
4457 pci_free_consistent(ha->pcidev,
4458 ha->max_cmds * sizeof (ips_scb_t), ha->scbs,
4459 command_dma);
4460 return 0;
4461 }
4462
4463 memset(ha->scbs, 0, ha->max_cmds * sizeof (ips_scb_t));
4464
4465 for (i = 0; i < ha->max_cmds; i++) {
4466 scb_p = &ha->scbs[i];
4467 scb_p->scb_busaddr = command_dma + sizeof (ips_scb_t) * i;
4468
4469 if (IPS_USE_ENH_SGLIST(ha)) {
4470 scb_p->sg_list.enh_list =
4471 ips_sg.enh_list + i * IPS_MAX_SG;
4472 scb_p->sg_busaddr =
4473 sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
4474 } else {
4475 scb_p->sg_list.std_list =
4476 ips_sg.std_list + i * IPS_MAX_SG;
4477 scb_p->sg_busaddr =
4478 sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
4479 }
4480
4481
4482 if (i < ha->max_cmds - 1) {
4483 scb_p->q_next = ha->scb_freelist;
4484 ha->scb_freelist = scb_p;
4485 }
4486 }
4487
4488
4489 return (1);
4490}
4491
4492
4493
4494
4495
4496
4497
4498
4499
4500
4501static void
4502ips_init_scb(ips_ha_t * ha, ips_scb_t * scb)
4503{
4504 IPS_SG_LIST sg_list;
4505 uint32_t cmd_busaddr, sg_busaddr;
4506 METHOD_TRACE("ips_init_scb", 1);
4507
4508 if (scb == NULL)
4509 return;
4510
4511 sg_list.list = scb->sg_list.list;
4512 cmd_busaddr = scb->scb_busaddr;
4513 sg_busaddr = scb->sg_busaddr;
4514
4515 memset(scb, 0, sizeof (ips_scb_t));
4516 memset(ha->dummy, 0, sizeof (IPS_IO_CMD));
4517
4518
4519 ha->dummy->op_code = 0xFF;
4520 ha->dummy->ccsar = cpu_to_le32(ha->adapt->hw_status_start
4521 + sizeof (IPS_ADAPTER));
4522 ha->dummy->command_id = IPS_MAX_CMDS;
4523
4524
4525 scb->scb_busaddr = cmd_busaddr;
4526 scb->sg_busaddr = sg_busaddr;
4527 scb->sg_list.list = sg_list.list;
4528
4529
4530 scb->cmd.basic_io.cccr = cpu_to_le32((uint32_t) IPS_BIT_ILE);
4531 scb->cmd.basic_io.ccsar = cpu_to_le32(ha->adapt->hw_status_start
4532 + sizeof (IPS_ADAPTER));
4533}
4534
4535
4536
4537
4538
4539
4540
4541
4542
4543
4544
4545
4546static ips_scb_t *
4547ips_getscb(ips_ha_t * ha)
4548{
4549 ips_scb_t *scb;
4550
4551 METHOD_TRACE("ips_getscb", 1);
4552
4553 if ((scb = ha->scb_freelist) == NULL) {
4554
4555 return (NULL);
4556 }
4557
4558 ha->scb_freelist = scb->q_next;
4559 scb->flags = 0;
4560 scb->q_next = NULL;
4561
4562 ips_init_scb(ha, scb);
4563
4564 return (scb);
4565}
4566
4567
4568
4569
4570
4571
4572
4573
4574
4575
4576
4577
4578static void
4579ips_freescb(ips_ha_t * ha, ips_scb_t * scb)
4580{
4581
4582 METHOD_TRACE("ips_freescb", 1);
4583 if (scb->flags & IPS_SCB_MAP_SG)
4584 scsi_dma_unmap(scb->scsi_cmd);
4585 else if (scb->flags & IPS_SCB_MAP_SINGLE)
4586 pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len,
4587 IPS_DMA_DIR(scb));
4588
4589
4590 if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) {
4591 scb->q_next = ha->scb_freelist;
4592 ha->scb_freelist = scb;
4593 }
4594}
4595
4596
4597
4598
4599
4600
4601
4602
4603
4604
4605static int
4606ips_isinit_copperhead(ips_ha_t * ha)
4607{
4608 uint8_t scpr;
4609 uint8_t isr;
4610
4611 METHOD_TRACE("ips_isinit_copperhead", 1);
4612
4613 isr = inb(ha->io_addr + IPS_REG_HISR);
4614 scpr = inb(ha->io_addr + IPS_REG_SCPR);
4615
4616 if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
4617 return (0);
4618 else
4619 return (1);
4620}
4621
4622
4623
4624
4625
4626
4627
4628
4629
4630
4631static int
4632ips_isinit_copperhead_memio(ips_ha_t * ha)
4633{
4634 uint8_t isr = 0;
4635 uint8_t scpr;
4636
4637 METHOD_TRACE("ips_is_init_copperhead_memio", 1);
4638
4639 isr = readb(ha->mem_ptr + IPS_REG_HISR);
4640 scpr = readb(ha->mem_ptr + IPS_REG_SCPR);
4641
4642 if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
4643 return (0);
4644 else
4645 return (1);
4646}
4647
4648
4649
4650
4651
4652
4653
4654
4655
4656
4657static int
4658ips_isinit_morpheus(ips_ha_t * ha)
4659{
4660 uint32_t post;
4661 uint32_t bits;
4662
4663 METHOD_TRACE("ips_is_init_morpheus", 1);
4664
4665 if (ips_isintr_morpheus(ha))
4666 ips_flush_and_reset(ha);
4667
4668 post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
4669 bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
4670
4671 if (post == 0)
4672 return (0);
4673 else if (bits & 0x3)
4674 return (0);
4675 else
4676 return (1);
4677}
4678
4679
4680
4681
4682
4683
4684
4685
4686
4687
4688
4689static void
4690ips_flush_and_reset(ips_ha_t *ha)
4691{
4692 ips_scb_t *scb;
4693 int ret;
4694 int time;
4695 int done;
4696 dma_addr_t command_dma;
4697
4698
4699 scb = pci_alloc_consistent(ha->pcidev, sizeof(ips_scb_t), &command_dma);
4700 if (scb) {
4701 memset(scb, 0, sizeof(ips_scb_t));
4702 ips_init_scb(ha, scb);
4703 scb->scb_busaddr = command_dma;
4704
4705 scb->timeout = ips_cmd_timeout;
4706 scb->cdb[0] = IPS_CMD_FLUSH;
4707
4708 scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
4709 scb->cmd.flush_cache.command_id = IPS_MAX_CMDS;
4710 scb->cmd.flush_cache.state = IPS_NORM_STATE;
4711 scb->cmd.flush_cache.reserved = 0;
4712 scb->cmd.flush_cache.reserved2 = 0;
4713 scb->cmd.flush_cache.reserved3 = 0;
4714 scb->cmd.flush_cache.reserved4 = 0;
4715
4716 ret = ips_send_cmd(ha, scb);
4717
4718 if (ret == IPS_SUCCESS) {
4719 time = 60 * IPS_ONE_SEC;
4720 done = 0;
4721
4722 while ((time > 0) && (!done)) {
4723 done = ips_poll_for_flush_complete(ha);
4724
4725 udelay(1000);
4726 time--;
4727 }
4728 }
4729 }
4730
4731
4732 (*ha->func.reset) (ha);
4733
4734 pci_free_consistent(ha->pcidev, sizeof(ips_scb_t), scb, command_dma);
4735 return;
4736}
4737
4738
4739
4740
4741
4742
4743
4744
4745
4746
4747
4748static int
4749ips_poll_for_flush_complete(ips_ha_t * ha)
4750{
4751 IPS_STATUS cstatus;
4752
4753 while (TRUE) {
4754 cstatus.value = (*ha->func.statupd) (ha);
4755
4756 if (cstatus.value == 0xffffffff)
4757 break;
4758
4759
4760 if (cstatus.fields.command_id == IPS_MAX_CMDS )
4761 return 1;
4762 }
4763
4764 return 0;
4765}
4766
4767
4768
4769
4770
4771
4772
4773
4774
4775static void
4776ips_enable_int_copperhead(ips_ha_t * ha)
4777{
4778 METHOD_TRACE("ips_enable_int_copperhead", 1);
4779
4780 outb(ha->io_addr + IPS_REG_HISR, IPS_BIT_EI);
4781 inb(ha->io_addr + IPS_REG_HISR);
4782}
4783
4784
4785
4786
4787
4788
4789
4790
4791
4792static void
4793ips_enable_int_copperhead_memio(ips_ha_t * ha)
4794{
4795 METHOD_TRACE("ips_enable_int_copperhead_memio", 1);
4796
4797 writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
4798 readb(ha->mem_ptr + IPS_REG_HISR);
4799}
4800
4801
4802
4803
4804
4805
4806
4807
4808
4809static void
4810ips_enable_int_morpheus(ips_ha_t * ha)
4811{
4812 uint32_t Oimr;
4813
4814 METHOD_TRACE("ips_enable_int_morpheus", 1);
4815
4816 Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
4817 Oimr &= ~0x08;
4818 writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
4819 readl(ha->mem_ptr + IPS_REG_I960_OIMR);
4820}
4821
4822
4823
4824
4825
4826
4827
4828
4829
4830
4831static int
4832ips_init_copperhead(ips_ha_t * ha)
4833{
4834 uint8_t Isr;
4835 uint8_t Cbsp;
4836 uint8_t PostByte[IPS_MAX_POST_BYTES];
4837 uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES];
4838 int i, j;
4839
4840 METHOD_TRACE("ips_init_copperhead", 1);
4841
4842 for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
4843 for (j = 0; j < 45; j++) {
4844 Isr = inb(ha->io_addr + IPS_REG_HISR);
4845 if (Isr & IPS_BIT_GHI)
4846 break;
4847
4848
4849 MDELAY(IPS_ONE_SEC);
4850 }
4851
4852 if (j >= 45)
4853
4854 return (0);
4855
4856 PostByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
4857 outb(Isr, ha->io_addr + IPS_REG_HISR);
4858 }
4859
4860 if (PostByte[0] < IPS_GOOD_POST_STATUS) {
4861 IPS_PRINTK(KERN_WARNING, ha->pcidev,
4862 "reset controller fails (post status %x %x).\n",
4863 PostByte[0], PostByte[1]);
4864
4865 return (0);
4866 }
4867
4868 for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
4869 for (j = 0; j < 240; j++) {
4870 Isr = inb(ha->io_addr + IPS_REG_HISR);
4871 if (Isr & IPS_BIT_GHI)
4872 break;
4873
4874
4875 MDELAY(IPS_ONE_SEC);
4876 }
4877
4878 if (j >= 240)
4879
4880 return (0);
4881
4882 ConfigByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
4883 outb(Isr, ha->io_addr + IPS_REG_HISR);
4884 }
4885
4886 for (i = 0; i < 240; i++) {
4887 Cbsp = inb(ha->io_addr + IPS_REG_CBSP);
4888
4889 if ((Cbsp & IPS_BIT_OP) == 0)
4890 break;
4891
4892
4893 MDELAY(IPS_ONE_SEC);
4894 }
4895
4896 if (i >= 240)
4897
4898 return (0);
4899
4900
4901 outl(cpu_to_le32(0x1010), ha->io_addr + IPS_REG_CCCR);
4902
4903
4904 outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR);
4905
4906 if (ha->revision_id == IPS_REVID_TROMBONE64)
4907
4908 outl(0, ha->io_addr + IPS_REG_NDAE);
4909
4910
4911 outb(IPS_BIT_EI, ha->io_addr + IPS_REG_HISR);
4912
4913 return (1);
4914}
4915
4916
4917
4918
4919
4920
4921
4922
4923
4924
4925static int
4926ips_init_copperhead_memio(ips_ha_t * ha)
4927{
4928 uint8_t Isr = 0;
4929 uint8_t Cbsp;
4930 uint8_t PostByte[IPS_MAX_POST_BYTES];
4931 uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES];
4932 int i, j;
4933
4934 METHOD_TRACE("ips_init_copperhead_memio", 1);
4935
4936 for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
4937 for (j = 0; j < 45; j++) {
4938 Isr = readb(ha->mem_ptr + IPS_REG_HISR);
4939 if (Isr & IPS_BIT_GHI)
4940 break;
4941
4942
4943 MDELAY(IPS_ONE_SEC);
4944 }
4945
4946 if (j >= 45)
4947
4948 return (0);
4949
4950 PostByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
4951 writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
4952 }
4953
4954 if (PostByte[0] < IPS_GOOD_POST_STATUS) {
4955 IPS_PRINTK(KERN_WARNING, ha->pcidev,
4956 "reset controller fails (post status %x %x).\n",
4957 PostByte[0], PostByte[1]);
4958
4959 return (0);
4960 }
4961
4962 for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
4963 for (j = 0; j < 240; j++) {
4964 Isr = readb(ha->mem_ptr + IPS_REG_HISR);
4965 if (Isr & IPS_BIT_GHI)
4966 break;
4967
4968
4969 MDELAY(IPS_ONE_SEC);
4970 }
4971
4972 if (j >= 240)
4973
4974 return (0);
4975
4976 ConfigByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
4977 writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
4978 }
4979
4980 for (i = 0; i < 240; i++) {
4981 Cbsp = readb(ha->mem_ptr + IPS_REG_CBSP);
4982
4983 if ((Cbsp & IPS_BIT_OP) == 0)
4984 break;
4985
4986
4987 MDELAY(IPS_ONE_SEC);
4988 }
4989
4990 if (i >= 240)
4991
4992 return (0);
4993
4994
4995 writel(0x1010, ha->mem_ptr + IPS_REG_CCCR);
4996
4997
4998 writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR);
4999
5000 if (ha->revision_id == IPS_REVID_TROMBONE64)
5001
5002 writel(0, ha->mem_ptr + IPS_REG_NDAE);
5003
5004
5005 writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
5006
5007
5008 return (1);
5009}
5010
5011
5012
5013
5014
5015
5016
5017
5018
5019
5020static int
5021ips_init_morpheus(ips_ha_t * ha)
5022{
5023 uint32_t Post;
5024 uint32_t Config;
5025 uint32_t Isr;
5026 uint32_t Oimr;
5027 int i;
5028
5029 METHOD_TRACE("ips_init_morpheus", 1);
5030
5031
5032 for (i = 0; i < 45; i++) {
5033 Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
5034
5035 if (Isr & IPS_BIT_I960_MSG0I)
5036 break;
5037
5038
5039 MDELAY(IPS_ONE_SEC);
5040 }
5041
5042 if (i >= 45) {
5043
5044 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5045 "timeout waiting for post.\n");
5046
5047 return (0);
5048 }
5049
5050 Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
5051
5052 if (Post == 0x4F00) {
5053 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5054 "Flashing Battery PIC, Please wait ...\n");
5055
5056
5057 Isr = (uint32_t) IPS_BIT_I960_MSG0I;
5058 writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
5059
5060 for (i = 0; i < 120; i++) {
5061 Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
5062 if (Post != 0x4F00)
5063 break;
5064
5065 MDELAY(IPS_ONE_SEC);
5066 }
5067
5068 if (i >= 120) {
5069 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5070 "timeout waiting for Battery PIC Flash\n");
5071 return (0);
5072 }
5073
5074 }
5075
5076
5077 Isr = (uint32_t) IPS_BIT_I960_MSG0I;
5078 writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
5079
5080 if (Post < (IPS_GOOD_POST_STATUS << 8)) {
5081 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5082 "reset controller fails (post status %x).\n", Post);
5083
5084 return (0);
5085 }
5086
5087
5088 for (i = 0; i < 240; i++) {
5089 Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
5090
5091 if (Isr & IPS_BIT_I960_MSG1I)
5092 break;
5093
5094
5095 MDELAY(IPS_ONE_SEC);
5096 }
5097
5098 if (i >= 240) {
5099
5100 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5101 "timeout waiting for config.\n");
5102
5103 return (0);
5104 }
5105
5106 Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
5107
5108
5109 Isr = (uint32_t) IPS_BIT_I960_MSG1I;
5110 writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
5111
5112
5113 Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
5114 Oimr &= ~0x8;
5115 writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
5116
5117
5118
5119
5120 if (Post == 0xEF10) {
5121 if ((Config == 0x000F) || (Config == 0x0009))
5122 ha->requires_esl = 1;
5123 }
5124
5125 return (1);
5126}
5127
5128
5129
5130
5131
5132
5133
5134
5135
5136
5137static int
5138ips_reset_copperhead(ips_ha_t * ha)
5139{
5140 int reset_counter;
5141
5142 METHOD_TRACE("ips_reset_copperhead", 1);
5143
5144 DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d",
5145 ips_name, ha->host_num, ha->io_addr, ha->irq);
5146
5147 reset_counter = 0;
5148
5149 while (reset_counter < 2) {
5150 reset_counter++;
5151
5152 outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR);
5153
5154
5155 MDELAY(IPS_ONE_SEC);
5156
5157 outb(0, ha->io_addr + IPS_REG_SCPR);
5158
5159
5160 MDELAY(IPS_ONE_SEC);
5161
5162 if ((*ha->func.init) (ha))
5163 break;
5164 else if (reset_counter >= 2) {
5165
5166 return (0);
5167 }
5168 }
5169
5170 return (1);
5171}
5172
5173
5174
5175
5176
5177
5178
5179
5180
5181
5182static int
5183ips_reset_copperhead_memio(ips_ha_t * ha)
5184{
5185 int reset_counter;
5186
5187 METHOD_TRACE("ips_reset_copperhead_memio", 1);
5188
5189 DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d",
5190 ips_name, ha->host_num, ha->mem_addr, ha->irq);
5191
5192 reset_counter = 0;
5193
5194 while (reset_counter < 2) {
5195 reset_counter++;
5196
5197 writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR);
5198
5199
5200 MDELAY(IPS_ONE_SEC);
5201
5202 writeb(0, ha->mem_ptr + IPS_REG_SCPR);
5203
5204
5205 MDELAY(IPS_ONE_SEC);
5206
5207 if ((*ha->func.init) (ha))
5208 break;
5209 else if (reset_counter >= 2) {
5210
5211 return (0);
5212 }
5213 }
5214
5215 return (1);
5216}
5217
5218
5219
5220
5221
5222
5223
5224
5225
5226
5227static int
5228ips_reset_morpheus(ips_ha_t * ha)
5229{
5230 int reset_counter;
5231 uint8_t junk;
5232
5233 METHOD_TRACE("ips_reset_morpheus", 1);
5234
5235 DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d",
5236 ips_name, ha->host_num, ha->mem_addr, ha->irq);
5237
5238 reset_counter = 0;
5239
5240 while (reset_counter < 2) {
5241 reset_counter++;
5242
5243 writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR);
5244
5245
5246 MDELAY(5 * IPS_ONE_SEC);
5247
5248
5249 pci_read_config_byte(ha->pcidev, 4, &junk);
5250
5251 if ((*ha->func.init) (ha))
5252 break;
5253 else if (reset_counter >= 2) {
5254
5255 return (0);
5256 }
5257 }
5258
5259 return (1);
5260}
5261
5262
5263
5264
5265
5266
5267
5268
5269
5270
5271static void
5272ips_statinit(ips_ha_t * ha)
5273{
5274 uint32_t phys_status_start;
5275
5276 METHOD_TRACE("ips_statinit", 1);
5277
5278 ha->adapt->p_status_start = ha->adapt->status;
5279 ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
5280 ha->adapt->p_status_tail = ha->adapt->status;
5281
5282 phys_status_start = ha->adapt->hw_status_start;
5283 outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQSR);
5284 outl(cpu_to_le32(phys_status_start + IPS_STATUS_Q_SIZE),
5285 ha->io_addr + IPS_REG_SQER);
5286 outl(cpu_to_le32(phys_status_start + IPS_STATUS_SIZE),
5287 ha->io_addr + IPS_REG_SQHR);
5288 outl(cpu_to_le32(phys_status_start), ha->io_addr + IPS_REG_SQTR);
5289
5290 ha->adapt->hw_status_tail = phys_status_start;
5291}
5292
5293
5294
5295
5296
5297
5298
5299
5300
5301
5302static void
5303ips_statinit_memio(ips_ha_t * ha)
5304{
5305 uint32_t phys_status_start;
5306
5307 METHOD_TRACE("ips_statinit_memio", 1);
5308
5309 ha->adapt->p_status_start = ha->adapt->status;
5310 ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
5311 ha->adapt->p_status_tail = ha->adapt->status;
5312
5313 phys_status_start = ha->adapt->hw_status_start;
5314 writel(phys_status_start, ha->mem_ptr + IPS_REG_SQSR);
5315 writel(phys_status_start + IPS_STATUS_Q_SIZE,
5316 ha->mem_ptr + IPS_REG_SQER);
5317 writel(phys_status_start + IPS_STATUS_SIZE, ha->mem_ptr + IPS_REG_SQHR);
5318 writel(phys_status_start, ha->mem_ptr + IPS_REG_SQTR);
5319
5320 ha->adapt->hw_status_tail = phys_status_start;
5321}
5322
5323
5324
5325
5326
5327
5328
5329
5330
5331
5332static uint32_t
5333ips_statupd_copperhead(ips_ha_t * ha)
5334{
5335 METHOD_TRACE("ips_statupd_copperhead", 1);
5336
5337 if (ha->adapt->p_status_tail != ha->adapt->p_status_end) {
5338 ha->adapt->p_status_tail++;
5339 ha->adapt->hw_status_tail += sizeof (IPS_STATUS);
5340 } else {
5341 ha->adapt->p_status_tail = ha->adapt->p_status_start;
5342 ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
5343 }
5344
5345 outl(cpu_to_le32(ha->adapt->hw_status_tail),
5346 ha->io_addr + IPS_REG_SQTR);
5347
5348 return (ha->adapt->p_status_tail->value);
5349}
5350
5351
5352
5353
5354
5355
5356
5357
5358
5359
5360static uint32_t
5361ips_statupd_copperhead_memio(ips_ha_t * ha)
5362{
5363 METHOD_TRACE("ips_statupd_copperhead_memio", 1);
5364
5365 if (ha->adapt->p_status_tail != ha->adapt->p_status_end) {
5366 ha->adapt->p_status_tail++;
5367 ha->adapt->hw_status_tail += sizeof (IPS_STATUS);
5368 } else {
5369 ha->adapt->p_status_tail = ha->adapt->p_status_start;
5370 ha->adapt->hw_status_tail = ha->adapt->hw_status_start;
5371 }
5372
5373 writel(ha->adapt->hw_status_tail, ha->mem_ptr + IPS_REG_SQTR);
5374
5375 return (ha->adapt->p_status_tail->value);
5376}
5377
5378
5379
5380
5381
5382
5383
5384
5385
5386
5387static uint32_t
5388ips_statupd_morpheus(ips_ha_t * ha)
5389{
5390 uint32_t val;
5391
5392 METHOD_TRACE("ips_statupd_morpheus", 1);
5393
5394 val = readl(ha->mem_ptr + IPS_REG_I2O_OUTMSGQ);
5395
5396 return (val);
5397}
5398
5399
5400
5401
5402
5403
5404
5405
5406
5407
5408static int
5409ips_issue_copperhead(ips_ha_t * ha, ips_scb_t * scb)
5410{
5411 uint32_t TimeOut;
5412 uint32_t val;
5413
5414 METHOD_TRACE("ips_issue_copperhead", 1);
5415
5416 if (scb->scsi_cmd) {
5417 DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
5418 ips_name,
5419 ha->host_num,
5420 scb->cdb[0],
5421 scb->cmd.basic_io.command_id,
5422 scb->bus, scb->target_id, scb->lun);
5423 } else {
5424 DEBUG_VAR(2, KERN_NOTICE "(%s%d) ips_issue: logical cmd id %d",
5425 ips_name, ha->host_num, scb->cmd.basic_io.command_id);
5426 }
5427
5428 TimeOut = 0;
5429
5430 while ((val =
5431 le32_to_cpu(inl(ha->io_addr + IPS_REG_CCCR))) & IPS_BIT_SEM) {
5432 udelay(1000);
5433
5434 if (++TimeOut >= IPS_SEM_TIMEOUT) {
5435 if (!(val & IPS_BIT_START_STOP))
5436 break;
5437
5438 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5439 "ips_issue val [0x%x].\n", val);
5440 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5441 "ips_issue semaphore chk timeout.\n");
5442
5443 return (IPS_FAILURE);
5444 }
5445 }
5446
5447 outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_CCSAR);
5448 outw(cpu_to_le32(IPS_BIT_START_CMD), ha->io_addr + IPS_REG_CCCR);
5449
5450 return (IPS_SUCCESS);
5451}
5452
5453
5454
5455
5456
5457
5458
5459
5460
5461
5462static int
5463ips_issue_copperhead_memio(ips_ha_t * ha, ips_scb_t * scb)
5464{
5465 uint32_t TimeOut;
5466 uint32_t val;
5467
5468 METHOD_TRACE("ips_issue_copperhead_memio", 1);
5469
5470 if (scb->scsi_cmd) {
5471 DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
5472 ips_name,
5473 ha->host_num,
5474 scb->cdb[0],
5475 scb->cmd.basic_io.command_id,
5476 scb->bus, scb->target_id, scb->lun);
5477 } else {
5478 DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
5479 ips_name, ha->host_num, scb->cmd.basic_io.command_id);
5480 }
5481
5482 TimeOut = 0;
5483
5484 while ((val = readl(ha->mem_ptr + IPS_REG_CCCR)) & IPS_BIT_SEM) {
5485 udelay(1000);
5486
5487 if (++TimeOut >= IPS_SEM_TIMEOUT) {
5488 if (!(val & IPS_BIT_START_STOP))
5489 break;
5490
5491 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5492 "ips_issue val [0x%x].\n", val);
5493 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5494 "ips_issue semaphore chk timeout.\n");
5495
5496 return (IPS_FAILURE);
5497 }
5498 }
5499
5500 writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_CCSAR);
5501 writel(IPS_BIT_START_CMD, ha->mem_ptr + IPS_REG_CCCR);
5502
5503 return (IPS_SUCCESS);
5504}
5505
5506
5507
5508
5509
5510
5511
5512
5513
5514
5515static int
5516ips_issue_i2o(ips_ha_t * ha, ips_scb_t * scb)
5517{
5518
5519 METHOD_TRACE("ips_issue_i2o", 1);
5520
5521 if (scb->scsi_cmd) {
5522 DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
5523 ips_name,
5524 ha->host_num,
5525 scb->cdb[0],
5526 scb->cmd.basic_io.command_id,
5527 scb->bus, scb->target_id, scb->lun);
5528 } else {
5529 DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
5530 ips_name, ha->host_num, scb->cmd.basic_io.command_id);
5531 }
5532
5533 outl(cpu_to_le32(scb->scb_busaddr), ha->io_addr + IPS_REG_I2O_INMSGQ);
5534
5535 return (IPS_SUCCESS);
5536}
5537
5538
5539
5540
5541
5542
5543
5544
5545
5546
5547static int
5548ips_issue_i2o_memio(ips_ha_t * ha, ips_scb_t * scb)
5549{
5550
5551 METHOD_TRACE("ips_issue_i2o_memio", 1);
5552
5553 if (scb->scsi_cmd) {
5554 DEBUG_VAR(2, "(%s%d) ips_issue: cmd 0x%X id %d (%d %d %d)",
5555 ips_name,
5556 ha->host_num,
5557 scb->cdb[0],
5558 scb->cmd.basic_io.command_id,
5559 scb->bus, scb->target_id, scb->lun);
5560 } else {
5561 DEBUG_VAR(2, "(%s%d) ips_issue: logical cmd id %d",
5562 ips_name, ha->host_num, scb->cmd.basic_io.command_id);
5563 }
5564
5565 writel(scb->scb_busaddr, ha->mem_ptr + IPS_REG_I2O_INMSGQ);
5566
5567 return (IPS_SUCCESS);
5568}
5569
5570
5571
5572
5573
5574
5575
5576
5577
5578
5579static int
5580ips_isintr_copperhead(ips_ha_t * ha)
5581{
5582 uint8_t Isr;
5583
5584 METHOD_TRACE("ips_isintr_copperhead", 2);
5585
5586 Isr = inb(ha->io_addr + IPS_REG_HISR);
5587
5588 if (Isr == 0xFF)
5589
5590 return (0);
5591
5592 if (Isr & IPS_BIT_SCE)
5593 return (1);
5594 else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) {
5595
5596
5597 outb(Isr, ha->io_addr + IPS_REG_HISR);
5598 }
5599
5600 return (0);
5601}
5602
5603
5604
5605
5606
5607
5608
5609
5610
5611
5612static int
5613ips_isintr_copperhead_memio(ips_ha_t * ha)
5614{
5615 uint8_t Isr;
5616
5617 METHOD_TRACE("ips_isintr_memio", 2);
5618
5619 Isr = readb(ha->mem_ptr + IPS_REG_HISR);
5620
5621 if (Isr == 0xFF)
5622
5623 return (0);
5624
5625 if (Isr & IPS_BIT_SCE)
5626 return (1);
5627 else if (Isr & (IPS_BIT_SQO | IPS_BIT_GHI)) {
5628
5629
5630 writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
5631 }
5632
5633 return (0);
5634}
5635
5636
5637
5638
5639
5640
5641
5642
5643
5644
5645static int
5646ips_isintr_morpheus(ips_ha_t * ha)
5647{
5648 uint32_t Isr;
5649
5650 METHOD_TRACE("ips_isintr_morpheus", 2);
5651
5652 Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
5653
5654 if (Isr & IPS_BIT_I2O_OPQI)
5655 return (1);
5656 else
5657 return (0);
5658}
5659
5660
5661
5662
5663
5664
5665
5666
5667
5668
5669static int
5670ips_wait(ips_ha_t * ha, int time, int intr)
5671{
5672 int ret;
5673 int done;
5674
5675 METHOD_TRACE("ips_wait", 1);
5676
5677 ret = IPS_FAILURE;
5678 done = FALSE;
5679
5680 time *= IPS_ONE_SEC;
5681
5682 while ((time > 0) && (!done)) {
5683 if (intr == IPS_INTR_ON) {
5684 if (ha->waitflag == FALSE) {
5685 ret = IPS_SUCCESS;
5686 done = TRUE;
5687 break;
5688 }
5689 } else if (intr == IPS_INTR_IORL) {
5690 if (ha->waitflag == FALSE) {
5691
5692
5693
5694
5695
5696 ret = IPS_SUCCESS;
5697 done = TRUE;
5698 break;
5699 }
5700
5701
5702
5703
5704
5705
5706
5707 (*ha->func.intr) (ha);
5708 }
5709
5710
5711 udelay(1000);
5712 time--;
5713 }
5714
5715 return (ret);
5716}
5717
5718
5719
5720
5721
5722
5723
5724
5725
5726
5727static int
5728ips_write_driver_status(ips_ha_t * ha, int intr)
5729{
5730 METHOD_TRACE("ips_write_driver_status", 1);
5731
5732 if (!ips_readwrite_page5(ha, FALSE, intr)) {
5733 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5734 "unable to read NVRAM page 5.\n");
5735
5736 return (0);
5737 }
5738
5739
5740
5741 if (le32_to_cpu(ha->nvram->signature) != IPS_NVRAM_P5_SIG) {
5742 DEBUG_VAR(1,
5743 "(%s%d) NVRAM page 5 has an invalid signature: %X.",
5744 ips_name, ha->host_num, ha->nvram->signature);
5745 ha->nvram->signature = IPS_NVRAM_P5_SIG;
5746 }
5747
5748 DEBUG_VAR(2,
5749 "(%s%d) Ad Type: %d, Ad Slot: %d, BIOS: %c%c%c%c %c%c%c%c.",
5750 ips_name, ha->host_num, le16_to_cpu(ha->nvram->adapter_type),
5751 ha->nvram->adapter_slot, ha->nvram->bios_high[0],
5752 ha->nvram->bios_high[1], ha->nvram->bios_high[2],
5753 ha->nvram->bios_high[3], ha->nvram->bios_low[0],
5754 ha->nvram->bios_low[1], ha->nvram->bios_low[2],
5755 ha->nvram->bios_low[3]);
5756
5757 ips_get_bios_version(ha, intr);
5758
5759
5760 ha->nvram->operating_system = IPS_OS_LINUX;
5761 ha->nvram->adapter_type = ha->ad_type;
5762 strncpy((char *) ha->nvram->driver_high, IPS_VERSION_HIGH, 4);
5763 strncpy((char *) ha->nvram->driver_low, IPS_VERSION_LOW, 4);
5764 strncpy((char *) ha->nvram->bios_high, ha->bios_version, 4);
5765 strncpy((char *) ha->nvram->bios_low, ha->bios_version + 4, 4);
5766
5767 ha->nvram->versioning = 0;
5768
5769
5770 if (!ips_readwrite_page5(ha, TRUE, intr)) {
5771 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5772 "unable to write NVRAM page 5.\n");
5773
5774 return (0);
5775 }
5776
5777
5778 ha->slot_num = ha->nvram->adapter_slot;
5779
5780 return (1);
5781}
5782
5783
5784
5785
5786
5787
5788
5789
5790
5791
5792static int
5793ips_read_adapter_status(ips_ha_t * ha, int intr)
5794{
5795 ips_scb_t *scb;
5796 int ret;
5797
5798 METHOD_TRACE("ips_read_adapter_status", 1);
5799
5800 scb = &ha->scbs[ha->max_cmds - 1];
5801
5802 ips_init_scb(ha, scb);
5803
5804 scb->timeout = ips_cmd_timeout;
5805 scb->cdb[0] = IPS_CMD_ENQUIRY;
5806
5807 scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
5808 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
5809 scb->cmd.basic_io.sg_count = 0;
5810 scb->cmd.basic_io.lba = 0;
5811 scb->cmd.basic_io.sector_count = 0;
5812 scb->cmd.basic_io.log_drv = 0;
5813 scb->data_len = sizeof (*ha->enq);
5814 scb->cmd.basic_io.sg_addr = ha->enq_busaddr;
5815
5816
5817 if (((ret =
5818 ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
5819 || (ret == IPS_SUCCESS_IMM)
5820 || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
5821 return (0);
5822
5823 return (1);
5824}
5825
5826
5827
5828
5829
5830
5831
5832
5833
5834
5835static int
5836ips_read_subsystem_parameters(ips_ha_t * ha, int intr)
5837{
5838 ips_scb_t *scb;
5839 int ret;
5840
5841 METHOD_TRACE("ips_read_subsystem_parameters", 1);
5842
5843 scb = &ha->scbs[ha->max_cmds - 1];
5844
5845 ips_init_scb(ha, scb);
5846
5847 scb->timeout = ips_cmd_timeout;
5848 scb->cdb[0] = IPS_CMD_GET_SUBSYS;
5849
5850 scb->cmd.basic_io.op_code = IPS_CMD_GET_SUBSYS;
5851 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
5852 scb->cmd.basic_io.sg_count = 0;
5853 scb->cmd.basic_io.lba = 0;
5854 scb->cmd.basic_io.sector_count = 0;
5855 scb->cmd.basic_io.log_drv = 0;
5856 scb->data_len = sizeof (*ha->subsys);
5857 scb->cmd.basic_io.sg_addr = ha->ioctl_busaddr;
5858
5859
5860 if (((ret =
5861 ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
5862 || (ret == IPS_SUCCESS_IMM)
5863 || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
5864 return (0);
5865
5866 memcpy(ha->subsys, ha->ioctl_data, sizeof(*ha->subsys));
5867 return (1);
5868}
5869
5870
5871
5872
5873
5874
5875
5876
5877
5878
5879static int
5880ips_read_config(ips_ha_t * ha, int intr)
5881{
5882 ips_scb_t *scb;
5883 int i;
5884 int ret;
5885
5886 METHOD_TRACE("ips_read_config", 1);
5887
5888
5889 for (i = 0; i < 4; i++)
5890 ha->conf->init_id[i] = 7;
5891
5892 scb = &ha->scbs[ha->max_cmds - 1];
5893
5894 ips_init_scb(ha, scb);
5895
5896 scb->timeout = ips_cmd_timeout;
5897 scb->cdb[0] = IPS_CMD_READ_CONF;
5898
5899 scb->cmd.basic_io.op_code = IPS_CMD_READ_CONF;
5900 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
5901 scb->data_len = sizeof (*ha->conf);
5902 scb->cmd.basic_io.sg_addr = ha->ioctl_busaddr;
5903
5904
5905 if (((ret =
5906 ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
5907 || (ret == IPS_SUCCESS_IMM)
5908 || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
5909
5910 memset(ha->conf, 0, sizeof (IPS_CONF));
5911
5912
5913 for (i = 0; i < 4; i++)
5914 ha->conf->init_id[i] = 7;
5915
5916
5917 if ((scb->basic_status & IPS_GSC_STATUS_MASK) ==
5918 IPS_CMD_CMPLT_WERROR)
5919 return (1);
5920
5921 return (0);
5922 }
5923
5924 memcpy(ha->conf, ha->ioctl_data, sizeof(*ha->conf));
5925 return (1);
5926}
5927
5928
5929
5930
5931
5932
5933
5934
5935
5936
5937static int
5938ips_readwrite_page5(ips_ha_t * ha, int write, int intr)
5939{
5940 ips_scb_t *scb;
5941 int ret;
5942
5943 METHOD_TRACE("ips_readwrite_page5", 1);
5944
5945 scb = &ha->scbs[ha->max_cmds - 1];
5946
5947 ips_init_scb(ha, scb);
5948
5949 scb->timeout = ips_cmd_timeout;
5950 scb->cdb[0] = IPS_CMD_RW_NVRAM_PAGE;
5951
5952 scb->cmd.nvram.op_code = IPS_CMD_RW_NVRAM_PAGE;
5953 scb->cmd.nvram.command_id = IPS_COMMAND_ID(ha, scb);
5954 scb->cmd.nvram.page = 5;
5955 scb->cmd.nvram.write = write;
5956 scb->cmd.nvram.reserved = 0;
5957 scb->cmd.nvram.reserved2 = 0;
5958 scb->data_len = sizeof (*ha->nvram);
5959 scb->cmd.nvram.buffer_addr = ha->ioctl_busaddr;
5960 if (write)
5961 memcpy(ha->ioctl_data, ha->nvram, sizeof(*ha->nvram));
5962
5963
5964 if (((ret =
5965 ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
5966 || (ret == IPS_SUCCESS_IMM)
5967 || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
5968
5969 memset(ha->nvram, 0, sizeof (IPS_NVRAM_P5));
5970
5971 return (0);
5972 }
5973 if (!write)
5974 memcpy(ha->nvram, ha->ioctl_data, sizeof(*ha->nvram));
5975 return (1);
5976}
5977
5978
5979
5980
5981
5982
5983
5984
5985
5986
5987static int
5988ips_clear_adapter(ips_ha_t * ha, int intr)
5989{
5990 ips_scb_t *scb;
5991 int ret;
5992
5993 METHOD_TRACE("ips_clear_adapter", 1);
5994
5995 scb = &ha->scbs[ha->max_cmds - 1];
5996
5997 ips_init_scb(ha, scb);
5998
5999 scb->timeout = ips_reset_timeout;
6000 scb->cdb[0] = IPS_CMD_CONFIG_SYNC;
6001
6002 scb->cmd.config_sync.op_code = IPS_CMD_CONFIG_SYNC;
6003 scb->cmd.config_sync.command_id = IPS_COMMAND_ID(ha, scb);
6004 scb->cmd.config_sync.channel = 0;
6005 scb->cmd.config_sync.source_target = IPS_POCL;
6006 scb->cmd.config_sync.reserved = 0;
6007 scb->cmd.config_sync.reserved2 = 0;
6008 scb->cmd.config_sync.reserved3 = 0;
6009
6010
6011 if (((ret =
6012 ips_send_wait(ha, scb, ips_reset_timeout, intr)) == IPS_FAILURE)
6013 || (ret == IPS_SUCCESS_IMM)
6014 || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
6015 return (0);
6016
6017
6018 ips_init_scb(ha, scb);
6019
6020 scb->cdb[0] = IPS_CMD_ERROR_TABLE;
6021 scb->timeout = ips_reset_timeout;
6022
6023 scb->cmd.unlock_stripe.op_code = IPS_CMD_ERROR_TABLE;
6024 scb->cmd.unlock_stripe.command_id = IPS_COMMAND_ID(ha, scb);
6025 scb->cmd.unlock_stripe.log_drv = 0;
6026 scb->cmd.unlock_stripe.control = IPS_CSL;
6027 scb->cmd.unlock_stripe.reserved = 0;
6028 scb->cmd.unlock_stripe.reserved2 = 0;
6029 scb->cmd.unlock_stripe.reserved3 = 0;
6030
6031
6032 if (((ret =
6033 ips_send_wait(ha, scb, ips_cmd_timeout, intr)) == IPS_FAILURE)
6034 || (ret == IPS_SUCCESS_IMM)
6035 || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1))
6036 return (0);
6037
6038 return (1);
6039}
6040
6041
6042
6043
6044
6045
6046
6047
6048
6049
6050static void
6051ips_ffdc_reset(ips_ha_t * ha, int intr)
6052{
6053 ips_scb_t *scb;
6054
6055 METHOD_TRACE("ips_ffdc_reset", 1);
6056
6057 scb = &ha->scbs[ha->max_cmds - 1];
6058
6059 ips_init_scb(ha, scb);
6060
6061 scb->timeout = ips_cmd_timeout;
6062 scb->cdb[0] = IPS_CMD_FFDC;
6063 scb->cmd.ffdc.op_code = IPS_CMD_FFDC;
6064 scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb);
6065 scb->cmd.ffdc.reset_count = ha->reset_count;
6066 scb->cmd.ffdc.reset_type = 0x80;
6067
6068
6069 ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
6070
6071
6072 ips_send_wait(ha, scb, ips_cmd_timeout, intr);
6073}
6074
6075
6076
6077
6078
6079
6080
6081
6082
6083
6084static void
6085ips_ffdc_time(ips_ha_t * ha)
6086{
6087 ips_scb_t *scb;
6088
6089 METHOD_TRACE("ips_ffdc_time", 1);
6090
6091 DEBUG_VAR(1, "(%s%d) Sending time update.", ips_name, ha->host_num);
6092
6093 scb = &ha->scbs[ha->max_cmds - 1];
6094
6095 ips_init_scb(ha, scb);
6096
6097 scb->timeout = ips_cmd_timeout;
6098 scb->cdb[0] = IPS_CMD_FFDC;
6099 scb->cmd.ffdc.op_code = IPS_CMD_FFDC;
6100 scb->cmd.ffdc.command_id = IPS_COMMAND_ID(ha, scb);
6101 scb->cmd.ffdc.reset_count = 0;
6102 scb->cmd.ffdc.reset_type = 0;
6103
6104
6105 ips_fix_ffdc_time(ha, scb, ha->last_ffdc);
6106
6107
6108 ips_send_wait(ha, scb, ips_cmd_timeout, IPS_FFDC);
6109}
6110
6111
6112
6113
6114
6115
6116
6117
6118
6119static void
6120ips_fix_ffdc_time(ips_ha_t * ha, ips_scb_t * scb, time_t current_time)
6121{
6122 long days;
6123 long rem;
6124 int i;
6125 int year;
6126 int yleap;
6127 int year_lengths[2] = { IPS_DAYS_NORMAL_YEAR, IPS_DAYS_LEAP_YEAR };
6128 int month_lengths[12][2] = { {31, 31},
6129 {28, 29},
6130 {31, 31},
6131 {30, 30},
6132 {31, 31},
6133 {30, 30},
6134 {31, 31},
6135 {31, 31},
6136 {30, 30},
6137 {31, 31},
6138 {30, 30},
6139 {31, 31}
6140 };
6141
6142 METHOD_TRACE("ips_fix_ffdc_time", 1);
6143
6144 days = current_time / IPS_SECS_DAY;
6145 rem = current_time % IPS_SECS_DAY;
6146
6147 scb->cmd.ffdc.hour = (rem / IPS_SECS_HOUR);
6148 rem = rem % IPS_SECS_HOUR;
6149 scb->cmd.ffdc.minute = (rem / IPS_SECS_MIN);
6150 scb->cmd.ffdc.second = (rem % IPS_SECS_MIN);
6151
6152 year = IPS_EPOCH_YEAR;
6153 while (days < 0 || days >= year_lengths[yleap = IPS_IS_LEAP_YEAR(year)]) {
6154 int newy;
6155
6156 newy = year + (days / IPS_DAYS_NORMAL_YEAR);
6157 if (days < 0)
6158 --newy;
6159 days -= (newy - year) * IPS_DAYS_NORMAL_YEAR +
6160 IPS_NUM_LEAP_YEARS_THROUGH(newy - 1) -
6161 IPS_NUM_LEAP_YEARS_THROUGH(year - 1);
6162 year = newy;
6163 }
6164
6165 scb->cmd.ffdc.yearH = year / 100;
6166 scb->cmd.ffdc.yearL = year % 100;
6167
6168 for (i = 0; days >= month_lengths[i][yleap]; ++i)
6169 days -= month_lengths[i][yleap];
6170
6171 scb->cmd.ffdc.month = i + 1;
6172 scb->cmd.ffdc.day = days + 1;
6173}
6174
6175
6176
6177
6178
6179
6180
6181
6182
6183
6184
6185
6186
6187static int
6188ips_erase_bios(ips_ha_t * ha)
6189{
6190 int timeout;
6191 uint8_t status = 0;
6192
6193 METHOD_TRACE("ips_erase_bios", 1);
6194
6195 status = 0;
6196
6197
6198 outl(0, ha->io_addr + IPS_REG_FLAP);
6199 if (ha->revision_id == IPS_REVID_TROMBONE64)
6200 udelay(25);
6201
6202 outb(0x50, ha->io_addr + IPS_REG_FLDP);
6203 if (ha->revision_id == IPS_REVID_TROMBONE64)
6204 udelay(25);
6205
6206
6207 outb(0x20, ha->io_addr + IPS_REG_FLDP);
6208 if (ha->revision_id == IPS_REVID_TROMBONE64)
6209 udelay(25);
6210
6211
6212 outb(0xD0, ha->io_addr + IPS_REG_FLDP);
6213 if (ha->revision_id == IPS_REVID_TROMBONE64)
6214 udelay(25);
6215
6216
6217 outb(0x70, ha->io_addr + IPS_REG_FLDP);
6218 if (ha->revision_id == IPS_REVID_TROMBONE64)
6219 udelay(25);
6220
6221 timeout = 80000;
6222
6223 while (timeout > 0) {
6224 if (ha->revision_id == IPS_REVID_TROMBONE64) {
6225 outl(0, ha->io_addr + IPS_REG_FLAP);
6226 udelay(25);
6227 }
6228
6229 status = inb(ha->io_addr + IPS_REG_FLDP);
6230
6231 if (status & 0x80)
6232 break;
6233
6234 MDELAY(1);
6235 timeout--;
6236 }
6237
6238
6239 if (timeout <= 0) {
6240
6241
6242
6243 outb(0xB0, ha->io_addr + IPS_REG_FLDP);
6244 if (ha->revision_id == IPS_REVID_TROMBONE64)
6245 udelay(25);
6246
6247
6248 timeout = 10000;
6249 while (timeout > 0) {
6250 if (ha->revision_id == IPS_REVID_TROMBONE64) {
6251 outl(0, ha->io_addr + IPS_REG_FLAP);
6252 udelay(25);
6253 }
6254
6255 status = inb(ha->io_addr + IPS_REG_FLDP);
6256
6257 if (status & 0xC0)
6258 break;
6259
6260 MDELAY(1);
6261 timeout--;
6262 }
6263
6264 return (1);
6265 }
6266
6267
6268 if (status & 0x08)
6269
6270 return (1);
6271
6272
6273 if (status & 0x30)
6274
6275 return (1);
6276
6277
6278
6279 outb(0x50, ha->io_addr + IPS_REG_FLDP);
6280 if (ha->revision_id == IPS_REVID_TROMBONE64)
6281 udelay(25);
6282
6283
6284 outb(0xFF, ha->io_addr + IPS_REG_FLDP);
6285 if (ha->revision_id == IPS_REVID_TROMBONE64)
6286 udelay(25);
6287
6288 return (0);
6289}
6290
6291
6292
6293
6294
6295
6296
6297
6298
6299static int
6300ips_erase_bios_memio(ips_ha_t * ha)
6301{
6302 int timeout;
6303 uint8_t status;
6304
6305 METHOD_TRACE("ips_erase_bios_memio", 1);
6306
6307 status = 0;
6308
6309
6310 writel(0, ha->mem_ptr + IPS_REG_FLAP);
6311 if (ha->revision_id == IPS_REVID_TROMBONE64)
6312 udelay(25);
6313
6314 writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
6315 if (ha->revision_id == IPS_REVID_TROMBONE64)
6316 udelay(25);
6317
6318
6319 writeb(0x20, ha->mem_ptr + IPS_REG_FLDP);
6320 if (ha->revision_id == IPS_REVID_TROMBONE64)
6321 udelay(25);
6322
6323
6324 writeb(0xD0, ha->mem_ptr + IPS_REG_FLDP);
6325 if (ha->revision_id == IPS_REVID_TROMBONE64)
6326 udelay(25);
6327
6328
6329 writeb(0x70, ha->mem_ptr + IPS_REG_FLDP);
6330 if (ha->revision_id == IPS_REVID_TROMBONE64)
6331 udelay(25);
6332
6333 timeout = 80000;
6334
6335 while (timeout > 0) {
6336 if (ha->revision_id == IPS_REVID_TROMBONE64) {
6337 writel(0, ha->mem_ptr + IPS_REG_FLAP);
6338 udelay(25);
6339 }
6340
6341 status = readb(ha->mem_ptr + IPS_REG_FLDP);
6342
6343 if (status & 0x80)
6344 break;
6345
6346 MDELAY(1);
6347 timeout--;
6348 }
6349
6350
6351 if (timeout <= 0) {
6352
6353
6354
6355 writeb(0xB0, ha->mem_ptr + IPS_REG_FLDP);
6356 if (ha->revision_id == IPS_REVID_TROMBONE64)
6357 udelay(25);
6358
6359
6360 timeout = 10000;
6361 while (timeout > 0) {
6362 if (ha->revision_id == IPS_REVID_TROMBONE64) {
6363 writel(0, ha->mem_ptr + IPS_REG_FLAP);
6364 udelay(25);
6365 }
6366
6367 status = readb(ha->mem_ptr + IPS_REG_FLDP);
6368
6369 if (status & 0xC0)
6370 break;
6371
6372 MDELAY(1);
6373 timeout--;
6374 }
6375
6376 return (1);
6377 }
6378
6379
6380 if (status & 0x08)
6381
6382 return (1);
6383
6384
6385 if (status & 0x30)
6386
6387 return (1);
6388
6389
6390
6391 writeb(0x50, ha->mem_ptr + IPS_REG_FLDP);
6392 if (ha->revision_id == IPS_REVID_TROMBONE64)
6393 udelay(25);
6394
6395
6396 writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
6397 if (ha->revision_id == IPS_REVID_TROMBONE64)
6398 udelay(25);
6399
6400 return (0);
6401}
6402
6403
6404
6405
6406
6407
6408
6409
6410
6411static int
6412ips_program_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize,
6413 uint32_t offset)
6414{
6415 int i;
6416 int timeout;
6417 uint8_t status = 0;
6418
6419 METHOD_TRACE("ips_program_bios", 1);
6420
6421 status = 0;
6422
6423 for (i = 0; i < buffersize; i++) {
6424
6425 outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
6426 if (ha->revision_id == IPS_REVID_TROMBONE64)
6427 udelay(25);
6428
6429 outb(0x40, ha->io_addr + IPS_REG_FLDP);
6430 if (ha->revision_id == IPS_REVID_TROMBONE64)
6431 udelay(25);
6432
6433 outb(buffer[i], ha->io_addr + IPS_REG_FLDP);
6434 if (ha->revision_id == IPS_REVID_TROMBONE64)
6435 udelay(25);
6436
6437
6438 timeout = 1000;
6439 while (timeout > 0) {
6440 if (ha->revision_id == IPS_REVID_TROMBONE64) {
6441 outl(0, ha->io_addr + IPS_REG_FLAP);
6442 udelay(25);
6443 }
6444
6445 status = inb(ha->io_addr + IPS_REG_FLDP);
6446
6447 if (status & 0x80)
6448 break;
6449
6450 MDELAY(1);
6451 timeout--;
6452 }
6453
6454 if (timeout == 0) {
6455
6456 outl(0, ha->io_addr + IPS_REG_FLAP);
6457 if (ha->revision_id == IPS_REVID_TROMBONE64)
6458 udelay(25);
6459
6460 outb(0xFF, ha->io_addr + IPS_REG_FLDP);
6461 if (ha->revision_id == IPS_REVID_TROMBONE64)
6462 udelay(25);
6463
6464 return (1);
6465 }
6466
6467
6468 if (status & 0x18) {
6469
6470 outl(0, ha->io_addr + IPS_REG_FLAP);
6471 if (ha->revision_id == IPS_REVID_TROMBONE64)
6472 udelay(25);
6473
6474 outb(0xFF, ha->io_addr + IPS_REG_FLDP);
6475 if (ha->revision_id == IPS_REVID_TROMBONE64)
6476 udelay(25);
6477
6478 return (1);
6479 }
6480 }
6481
6482
6483 outl(0, ha->io_addr + IPS_REG_FLAP);
6484 if (ha->revision_id == IPS_REVID_TROMBONE64)
6485 udelay(25);
6486
6487 outb(0xFF, ha->io_addr + IPS_REG_FLDP);
6488 if (ha->revision_id == IPS_REVID_TROMBONE64)
6489 udelay(25);
6490
6491 return (0);
6492}
6493
6494
6495
6496
6497
6498
6499
6500
6501
6502static int
6503ips_program_bios_memio(ips_ha_t * ha, char *buffer, uint32_t buffersize,
6504 uint32_t offset)
6505{
6506 int i;
6507 int timeout;
6508 uint8_t status = 0;
6509
6510 METHOD_TRACE("ips_program_bios_memio", 1);
6511
6512 status = 0;
6513
6514 for (i = 0; i < buffersize; i++) {
6515
6516 writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
6517 if (ha->revision_id == IPS_REVID_TROMBONE64)
6518 udelay(25);
6519
6520 writeb(0x40, ha->mem_ptr + IPS_REG_FLDP);
6521 if (ha->revision_id == IPS_REVID_TROMBONE64)
6522 udelay(25);
6523
6524 writeb(buffer[i], ha->mem_ptr + IPS_REG_FLDP);
6525 if (ha->revision_id == IPS_REVID_TROMBONE64)
6526 udelay(25);
6527
6528
6529 timeout = 1000;
6530 while (timeout > 0) {
6531 if (ha->revision_id == IPS_REVID_TROMBONE64) {
6532 writel(0, ha->mem_ptr + IPS_REG_FLAP);
6533 udelay(25);
6534 }
6535
6536 status = readb(ha->mem_ptr + IPS_REG_FLDP);
6537
6538 if (status & 0x80)
6539 break;
6540
6541 MDELAY(1);
6542 timeout--;
6543 }
6544
6545 if (timeout == 0) {
6546
6547 writel(0, ha->mem_ptr + IPS_REG_FLAP);
6548 if (ha->revision_id == IPS_REVID_TROMBONE64)
6549 udelay(25);
6550
6551 writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
6552 if (ha->revision_id == IPS_REVID_TROMBONE64)
6553 udelay(25);
6554
6555 return (1);
6556 }
6557
6558
6559 if (status & 0x18) {
6560
6561 writel(0, ha->mem_ptr + IPS_REG_FLAP);
6562 if (ha->revision_id == IPS_REVID_TROMBONE64)
6563 udelay(25);
6564
6565 writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
6566 if (ha->revision_id == IPS_REVID_TROMBONE64)
6567 udelay(25);
6568
6569 return (1);
6570 }
6571 }
6572
6573
6574 writel(0, ha->mem_ptr + IPS_REG_FLAP);
6575 if (ha->revision_id == IPS_REVID_TROMBONE64)
6576 udelay(25);
6577
6578 writeb(0xFF, ha->mem_ptr + IPS_REG_FLDP);
6579 if (ha->revision_id == IPS_REVID_TROMBONE64)
6580 udelay(25);
6581
6582 return (0);
6583}
6584
6585
6586
6587
6588
6589
6590
6591
6592
6593static int
6594ips_verify_bios(ips_ha_t * ha, char *buffer, uint32_t buffersize,
6595 uint32_t offset)
6596{
6597 uint8_t checksum;
6598 int i;
6599
6600 METHOD_TRACE("ips_verify_bios", 1);
6601
6602
6603 outl(0, ha->io_addr + IPS_REG_FLAP);
6604 if (ha->revision_id == IPS_REVID_TROMBONE64)
6605 udelay(25);
6606
6607 if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
6608 return (1);
6609
6610 outl(cpu_to_le32(1), ha->io_addr + IPS_REG_FLAP);
6611 if (ha->revision_id == IPS_REVID_TROMBONE64)
6612 udelay(25);
6613 if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
6614 return (1);
6615
6616 checksum = 0xff;
6617 for (i = 2; i < buffersize; i++) {
6618
6619 outl(cpu_to_le32(i + offset), ha->io_addr + IPS_REG_FLAP);
6620 if (ha->revision_id == IPS_REVID_TROMBONE64)
6621 udelay(25);
6622
6623 checksum = (uint8_t) checksum + inb(ha->io_addr + IPS_REG_FLDP);
6624 }
6625
6626 if (checksum != 0)
6627
6628 return (1);
6629 else
6630
6631 return (0);
6632}
6633
6634
6635
6636
6637
6638
6639
6640
6641
6642static int
6643ips_verify_bios_memio(ips_ha_t * ha, char *buffer, uint32_t buffersize,
6644 uint32_t offset)
6645{
6646 uint8_t checksum;
6647 int i;
6648
6649 METHOD_TRACE("ips_verify_bios_memio", 1);
6650
6651
6652 writel(0, ha->mem_ptr + IPS_REG_FLAP);
6653 if (ha->revision_id == IPS_REVID_TROMBONE64)
6654 udelay(25);
6655
6656 if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
6657 return (1);
6658
6659 writel(1, ha->mem_ptr + IPS_REG_FLAP);
6660 if (ha->revision_id == IPS_REVID_TROMBONE64)
6661 udelay(25);
6662 if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
6663 return (1);
6664
6665 checksum = 0xff;
6666 for (i = 2; i < buffersize; i++) {
6667
6668 writel(i + offset, ha->mem_ptr + IPS_REG_FLAP);
6669 if (ha->revision_id == IPS_REVID_TROMBONE64)
6670 udelay(25);
6671
6672 checksum =
6673 (uint8_t) checksum + readb(ha->mem_ptr + IPS_REG_FLDP);
6674 }
6675
6676 if (checksum != 0)
6677
6678 return (1);
6679 else
6680
6681 return (0);
6682}
6683
6684
6685
6686
6687
6688
6689
6690
6691static int
6692ips_abort_init(ips_ha_t * ha, int index)
6693{
6694 ha->active = 0;
6695 ips_free(ha);
6696 ips_ha[index] = NULL;
6697 ips_sh[index] = NULL;
6698 return -1;
6699}
6700
6701
6702
6703
6704
6705
6706
6707
6708static void
6709ips_shift_controllers(int lowindex, int highindex)
6710{
6711 ips_ha_t *ha_sav = ips_ha[highindex];
6712 struct Scsi_Host *sh_sav = ips_sh[highindex];
6713 int i;
6714
6715 for (i = highindex; i > lowindex; i--) {
6716 ips_ha[i] = ips_ha[i - 1];
6717 ips_sh[i] = ips_sh[i - 1];
6718 ips_ha[i]->host_num = i;
6719 }
6720 ha_sav->host_num = lowindex;
6721 ips_ha[lowindex] = ha_sav;
6722 ips_sh[lowindex] = sh_sav;
6723}
6724
6725
6726
6727
6728
6729
6730
6731
6732static void
6733ips_order_controllers(void)
6734{
6735 int i, j, tmp, position = 0;
6736 IPS_NVRAM_P5 *nvram;
6737 if (!ips_ha[0])
6738 return;
6739 nvram = ips_ha[0]->nvram;
6740
6741 if (nvram->adapter_order[0]) {
6742 for (i = 1; i <= nvram->adapter_order[0]; i++) {
6743 for (j = position; j < ips_num_controllers; j++) {
6744 switch (ips_ha[j]->ad_type) {
6745 case IPS_ADTYPE_SERVERAID6M:
6746 case IPS_ADTYPE_SERVERAID7M:
6747 if (nvram->adapter_order[i] == 'M') {
6748 ips_shift_controllers(position,
6749 j);
6750 position++;
6751 }
6752 break;
6753 case IPS_ADTYPE_SERVERAID4L:
6754 case IPS_ADTYPE_SERVERAID4M:
6755 case IPS_ADTYPE_SERVERAID4MX:
6756 case IPS_ADTYPE_SERVERAID4LX:
6757 if (nvram->adapter_order[i] == 'N') {
6758 ips_shift_controllers(position,
6759 j);
6760 position++;
6761 }
6762 break;
6763 case IPS_ADTYPE_SERVERAID6I:
6764 case IPS_ADTYPE_SERVERAID5I2:
6765 case IPS_ADTYPE_SERVERAID5I1:
6766 case IPS_ADTYPE_SERVERAID7k:
6767 if (nvram->adapter_order[i] == 'S') {
6768 ips_shift_controllers(position,
6769 j);
6770 position++;
6771 }
6772 break;
6773 case IPS_ADTYPE_SERVERAID:
6774 case IPS_ADTYPE_SERVERAID2:
6775 case IPS_ADTYPE_NAVAJO:
6776 case IPS_ADTYPE_KIOWA:
6777 case IPS_ADTYPE_SERVERAID3L:
6778 case IPS_ADTYPE_SERVERAID3:
6779 case IPS_ADTYPE_SERVERAID4H:
6780 if (nvram->adapter_order[i] == 'A') {
6781 ips_shift_controllers(position,
6782 j);
6783 position++;
6784 }
6785 break;
6786 default:
6787 break;
6788 }
6789 }
6790 }
6791
6792 return;
6793 }
6794
6795 tmp = 0;
6796 for (i = position; i < ips_num_controllers; i++) {
6797 if (ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID5I2 ||
6798 ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID5I1) {
6799 ips_shift_controllers(position, i);
6800 position++;
6801 tmp = 1;
6802 }
6803 }
6804
6805 if (!tmp)
6806 return;
6807 for (i = position; i < ips_num_controllers; i++) {
6808 if (ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4L ||
6809 ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4M ||
6810 ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4LX ||
6811 ips_ha[i]->ad_type == IPS_ADTYPE_SERVERAID4MX) {
6812 ips_shift_controllers(position, i);
6813 position++;
6814 }
6815 }
6816
6817 return;
6818}
6819
6820
6821
6822
6823
6824
6825
6826
6827static int
6828ips_register_scsi(int index)
6829{
6830 struct Scsi_Host *sh;
6831 ips_ha_t *ha, *oldha = ips_ha[index];
6832 sh = scsi_host_alloc(&ips_driver_template, sizeof (ips_ha_t));
6833 if (!sh) {
6834 IPS_PRINTK(KERN_WARNING, oldha->pcidev,
6835 "Unable to register controller with SCSI subsystem\n");
6836 return -1;
6837 }
6838 ha = IPS_HA(sh);
6839 memcpy(ha, oldha, sizeof (ips_ha_t));
6840 free_irq(oldha->irq, oldha);
6841
6842 if (request_irq(ha->irq, do_ipsintr, IRQF_SHARED, ips_name, ha)) {
6843 IPS_PRINTK(KERN_WARNING, ha->pcidev,
6844 "Unable to install interrupt handler\n");
6845 scsi_host_put(sh);
6846 return -1;
6847 }
6848
6849 kfree(oldha);
6850 ips_sh[index] = sh;
6851 ips_ha[index] = ha;
6852
6853
6854 sh->io_port = ha->io_addr;
6855 sh->n_io_port = ha->io_addr ? 255 : 0;
6856 sh->unique_id = (ha->io_addr) ? ha->io_addr : ha->mem_addr;
6857 sh->irq = ha->irq;
6858 sh->sg_tablesize = sh->hostt->sg_tablesize;
6859 sh->can_queue = sh->hostt->can_queue;
6860 sh->cmd_per_lun = sh->hostt->cmd_per_lun;
6861 sh->unchecked_isa_dma = sh->hostt->unchecked_isa_dma;
6862 sh->use_clustering = sh->hostt->use_clustering;
6863 sh->max_sectors = 128;
6864
6865 sh->max_id = ha->ntargets;
6866 sh->max_lun = ha->nlun;
6867 sh->max_channel = ha->nbus - 1;
6868 sh->can_queue = ha->max_cmds - 1;
6869
6870 scsi_add_host(sh, NULL);
6871 scsi_scan_host(sh);
6872
6873 return 0;
6874}
6875
6876
6877
6878
6879
6880
6881
6882static void __devexit
6883ips_remove_device(struct pci_dev *pci_dev)
6884{
6885 int i;
6886 struct Scsi_Host *sh;
6887 ips_ha_t *ha;
6888
6889 for (i = 0; i < IPS_MAX_ADAPTERS; i++) {
6890 ha = ips_ha[i];
6891 if (ha) {
6892 if ((pci_dev->bus->number == ha->pcidev->bus->number) &&
6893 (pci_dev->devfn == ha->pcidev->devfn)) {
6894 sh = ips_sh[i];
6895 ips_release(sh);
6896 }
6897 }
6898 }
6899}
6900
6901
6902
6903
6904
6905
6906
6907
6908static int __init
6909ips_module_init(void)
6910{
6911 if (pci_register_driver(&ips_pci_driver) < 0)
6912 return -ENODEV;
6913 ips_driver_template.module = THIS_MODULE;
6914 ips_order_controllers();
6915 if (!ips_detect(&ips_driver_template)) {
6916 pci_unregister_driver(&ips_pci_driver);
6917 return -ENODEV;
6918 }
6919 register_reboot_notifier(&ips_notifier);
6920 return 0;
6921}
6922
6923
6924
6925
6926
6927
6928
6929
6930static void __exit
6931ips_module_exit(void)
6932{
6933 pci_unregister_driver(&ips_pci_driver);
6934 unregister_reboot_notifier(&ips_notifier);
6935}
6936
6937module_init(ips_module_init);
6938module_exit(ips_module_exit);
6939
6940
6941
6942
6943
6944
6945
6946
6947
6948
6949static int __devinit
6950ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent)
6951{
6952 int uninitialized_var(index);
6953 int rc;
6954
6955 METHOD_TRACE("ips_insert_device", 1);
6956 if (pci_enable_device(pci_dev))
6957 return -1;
6958
6959 rc = ips_init_phase1(pci_dev, &index);
6960 if (rc == SUCCESS)
6961 rc = ips_init_phase2(index);
6962
6963 if (ips_hotplug)
6964 if (ips_register_scsi(index)) {
6965 ips_free(ips_ha[index]);
6966 rc = -1;
6967 }
6968
6969 if (rc == SUCCESS)
6970 ips_num_controllers++;
6971
6972 ips_next_controller = ips_num_controllers;
6973 return rc;
6974}
6975
6976
6977
6978
6979
6980
6981
6982
6983
6984
6985static int
6986ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr)
6987{
6988 ips_ha_t *ha;
6989 uint32_t io_addr;
6990 uint32_t mem_addr;
6991 uint32_t io_len;
6992 uint32_t mem_len;
6993 uint8_t bus;
6994 uint8_t func;
6995 uint8_t irq;
6996 uint16_t subdevice_id;
6997 int j;
6998 int index;
6999 dma_addr_t dma_address;
7000 char __iomem *ioremap_ptr;
7001 char __iomem *mem_ptr;
7002 uint32_t IsDead;
7003
7004 METHOD_TRACE("ips_init_phase1", 1);
7005 index = IPS_MAX_ADAPTERS;
7006 for (j = 0; j < IPS_MAX_ADAPTERS; j++) {
7007 if (ips_ha[j] == 0) {
7008 index = j;
7009 break;
7010 }
7011 }
7012
7013 if (index >= IPS_MAX_ADAPTERS)
7014 return -1;
7015
7016
7017 irq = pci_dev->irq;
7018 bus = pci_dev->bus->number;
7019 func = pci_dev->devfn;
7020
7021
7022 mem_addr = 0;
7023 io_addr = 0;
7024 mem_len = 0;
7025 io_len = 0;
7026
7027 for (j = 0; j < 2; j++) {
7028 if (!pci_resource_start(pci_dev, j))
7029 break;
7030
7031 if (pci_resource_flags(pci_dev, j) & IORESOURCE_IO) {
7032 io_addr = pci_resource_start(pci_dev, j);
7033 io_len = pci_resource_len(pci_dev, j);
7034 } else {
7035 mem_addr = pci_resource_start(pci_dev, j);
7036 mem_len = pci_resource_len(pci_dev, j);
7037 }
7038 }
7039
7040
7041 if (mem_addr) {
7042 uint32_t base;
7043 uint32_t offs;
7044
7045 if (!request_mem_region(mem_addr, mem_len, "ips")) {
7046 IPS_PRINTK(KERN_WARNING, pci_dev,
7047 "Couldn't allocate IO Memory space %x len %d.\n",
7048 mem_addr, mem_len);
7049 return -1;
7050 }
7051
7052 base = mem_addr & PAGE_MASK;
7053 offs = mem_addr - base;
7054 ioremap_ptr = ioremap(base, PAGE_SIZE);
7055 mem_ptr = ioremap_ptr + offs;
7056 } else {
7057 ioremap_ptr = NULL;
7058 mem_ptr = NULL;
7059 }
7060
7061
7062 if (io_addr) {
7063 if (!request_region(io_addr, io_len, "ips")) {
7064 IPS_PRINTK(KERN_WARNING, pci_dev,
7065 "Couldn't allocate IO space %x len %d.\n",
7066 io_addr, io_len);
7067 return -1;
7068 }
7069 }
7070
7071 subdevice_id = pci_dev->subsystem_device;
7072
7073
7074 ha = kzalloc(sizeof (ips_ha_t), GFP_KERNEL);
7075 if (ha == NULL) {
7076 IPS_PRINTK(KERN_WARNING, pci_dev,
7077 "Unable to allocate temporary ha struct\n");
7078 return -1;
7079 }
7080
7081
7082 ips_sh[index] = NULL;
7083 ips_ha[index] = ha;
7084 ha->active = 1;
7085
7086
7087 ha->irq = irq;
7088 ha->io_addr = io_addr;
7089 ha->io_len = io_len;
7090 ha->mem_addr = mem_addr;
7091 ha->mem_len = mem_len;
7092 ha->mem_ptr = mem_ptr;
7093 ha->ioremap_ptr = ioremap_ptr;
7094 ha->host_num = (uint32_t) index;
7095 ha->revision_id = pci_dev->revision;
7096 ha->slot_num = PCI_SLOT(pci_dev->devfn);
7097 ha->device_id = pci_dev->device;
7098 ha->subdevice_id = subdevice_id;
7099 ha->pcidev = pci_dev;
7100
7101
7102
7103
7104
7105
7106
7107 if (IPS_ENABLE_DMA64 && IPS_HAS_ENH_SGLIST(ha) &&
7108 !pci_set_dma_mask(ha->pcidev, DMA_64BIT_MASK)) {
7109 (ha)->flags |= IPS_HA_ENH_SG;
7110 } else {
7111 if (pci_set_dma_mask(ha->pcidev, DMA_32BIT_MASK) != 0) {
7112 printk(KERN_WARNING "Unable to set DMA Mask\n");
7113 return ips_abort_init(ha, index);
7114 }
7115 }
7116 if(ips_cd_boot && !ips_FlashData){
7117 ips_FlashData = pci_alloc_consistent(pci_dev, PAGE_SIZE << 7,
7118 &ips_flashbusaddr);
7119 }
7120
7121 ha->enq = pci_alloc_consistent(pci_dev, sizeof (IPS_ENQ),
7122 &ha->enq_busaddr);
7123 if (!ha->enq) {
7124 IPS_PRINTK(KERN_WARNING, pci_dev,
7125 "Unable to allocate host inquiry structure\n");
7126 return ips_abort_init(ha, index);
7127 }
7128
7129 ha->adapt = pci_alloc_consistent(pci_dev, sizeof (IPS_ADAPTER) +
7130 sizeof (IPS_IO_CMD), &dma_address);
7131 if (!ha->adapt) {
7132 IPS_PRINTK(KERN_WARNING, pci_dev,
7133 "Unable to allocate host adapt & dummy structures\n");
7134 return ips_abort_init(ha, index);
7135 }
7136 ha->adapt->hw_status_start = dma_address;
7137 ha->dummy = (void *) (ha->adapt + 1);
7138
7139
7140
7141 ha->logical_drive_info = pci_alloc_consistent(pci_dev, sizeof (IPS_LD_INFO), &dma_address);
7142 if (!ha->logical_drive_info) {
7143 IPS_PRINTK(KERN_WARNING, pci_dev,
7144 "Unable to allocate logical drive info structure\n");
7145 return ips_abort_init(ha, index);
7146 }
7147 ha->logical_drive_info_dma_addr = dma_address;
7148
7149
7150 ha->conf = kmalloc(sizeof (IPS_CONF), GFP_KERNEL);
7151
7152 if (!ha->conf) {
7153 IPS_PRINTK(KERN_WARNING, pci_dev,
7154 "Unable to allocate host conf structure\n");
7155 return ips_abort_init(ha, index);
7156 }
7157
7158 ha->nvram = kmalloc(sizeof (IPS_NVRAM_P5), GFP_KERNEL);
7159
7160 if (!ha->nvram) {
7161 IPS_PRINTK(KERN_WARNING, pci_dev,
7162 "Unable to allocate host NVRAM structure\n");
7163 return ips_abort_init(ha, index);
7164 }
7165
7166 ha->subsys = kmalloc(sizeof (IPS_SUBSYS), GFP_KERNEL);
7167
7168 if (!ha->subsys) {
7169 IPS_PRINTK(KERN_WARNING, pci_dev,
7170 "Unable to allocate host subsystem structure\n");
7171 return ips_abort_init(ha, index);
7172 }
7173
7174
7175
7176 if (ips_ioctlsize < PAGE_SIZE)
7177 ips_ioctlsize = PAGE_SIZE;
7178
7179 ha->ioctl_data = pci_alloc_consistent(pci_dev, ips_ioctlsize,
7180 &ha->ioctl_busaddr);
7181 ha->ioctl_len = ips_ioctlsize;
7182 if (!ha->ioctl_data) {
7183 IPS_PRINTK(KERN_WARNING, pci_dev,
7184 "Unable to allocate IOCTL data\n");
7185 return ips_abort_init(ha, index);
7186 }
7187
7188
7189
7190
7191 ips_setup_funclist(ha);
7192
7193 if ((IPS_IS_MORPHEUS(ha)) || (IPS_IS_MARCO(ha))) {
7194
7195 IsDead = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
7196 if (IsDead == 0xDEADBEEF) {
7197 ips_reset_morpheus(ha);
7198 }
7199 }
7200
7201
7202
7203
7204
7205 if (!(*ha->func.isinit) (ha)) {
7206 if (!(*ha->func.init) (ha)) {
7207
7208
7209
7210 IPS_PRINTK(KERN_WARNING, pci_dev,
7211 "Unable to initialize controller\n");
7212 return ips_abort_init(ha, index);
7213 }
7214 }
7215
7216 *indexPtr = index;
7217 return SUCCESS;
7218}
7219
7220
7221
7222
7223
7224
7225
7226
7227
7228
7229static int
7230ips_init_phase2(int index)
7231{
7232 ips_ha_t *ha;
7233
7234 ha = ips_ha[index];
7235
7236 METHOD_TRACE("ips_init_phase2", 1);
7237 if (!ha->active) {
7238 ips_ha[index] = NULL;
7239 return -1;
7240 }
7241
7242
7243 if (request_irq(ha->irq, do_ipsintr, IRQF_SHARED, ips_name, ha)) {
7244 IPS_PRINTK(KERN_WARNING, ha->pcidev,
7245 "Unable to install interrupt handler\n");
7246 return ips_abort_init(ha, index);
7247 }
7248
7249
7250
7251
7252 ha->max_cmds = 1;
7253 if (!ips_allocatescbs(ha)) {
7254 IPS_PRINTK(KERN_WARNING, ha->pcidev,
7255 "Unable to allocate a CCB\n");
7256 free_irq(ha->irq, ha);
7257 return ips_abort_init(ha, index);
7258 }
7259
7260 if (!ips_hainit(ha)) {
7261 IPS_PRINTK(KERN_WARNING, ha->pcidev,
7262 "Unable to initialize controller\n");
7263 free_irq(ha->irq, ha);
7264 return ips_abort_init(ha, index);
7265 }
7266
7267 ips_deallocatescbs(ha, 1);
7268
7269
7270 if (!ips_allocatescbs(ha)) {
7271 IPS_PRINTK(KERN_WARNING, ha->pcidev,
7272 "Unable to allocate CCBs\n");
7273 free_irq(ha->irq, ha);
7274 return ips_abort_init(ha, index);
7275 }
7276
7277 return SUCCESS;
7278}
7279
7280MODULE_LICENSE("GPL");
7281MODULE_DESCRIPTION("IBM ServeRAID Adapter Driver " IPS_VER_STRING);
7282MODULE_VERSION(IPS_VER_STRING);
7283
7284
7285
7286
7287
7288
7289
7290
7291
7292
7293
7294
7295
7296
7297
7298
7299
7300
7301
7302
7303