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/string.h>
169#include <linux/errno.h>
170#include <linux/kernel.h>
171#include <linux/ioport.h>
172#include <linux/slab.h>
173#include <linux/delay.h>
174#include <linux/pci.h>
175#include <linux/proc_fs.h>
176#include <linux/reboot.h>
177#include <linux/interrupt.h>
178
179#include <linux/blkdev.h>
180#include <linux/types.h>
181#include <linux/dma-mapping.h>
182
183#include <scsi/sg.h>
184#include "scsi.h"
185#include <scsi/scsi_host.h>
186
187#include "ips.h"
188
189#include <linux/module.h>
190
191#include <linux/stat.h>
192
193#include <linux/spinlock.h>
194#include <linux/init.h>
195
196#include <linux/smp.h>
197
198#ifdef MODULE
199static char *ips = NULL;
200module_param(ips, charp, 0);
201#endif
202
203
204
205
206#define IPS_VERSION_HIGH IPS_VER_MAJOR_STRING "." IPS_VER_MINOR_STRING
207#define IPS_VERSION_LOW "." IPS_VER_BUILD_STRING " "
208
209#if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__)
210#warning "This driver has only been tested on the x86/ia64/x86_64 platforms"
211#endif
212
213#define IPS_DMA_DIR(scb) ((!scb->scsi_cmd || ips_is_passthru(scb->scsi_cmd) || \
214 DMA_NONE == scb->scsi_cmd->sc_data_direction) ? \
215 PCI_DMA_BIDIRECTIONAL : \
216 scb->scsi_cmd->sc_data_direction)
217
218#ifdef IPS_DEBUG
219#define METHOD_TRACE(s, i) if (ips_debug >= (i+10)) printk(KERN_NOTICE s "\n");
220#define DEBUG(i, s) if (ips_debug >= i) printk(KERN_NOTICE s "\n");
221#define DEBUG_VAR(i, s, v...) if (ips_debug >= i) printk(KERN_NOTICE s "\n", v);
222#else
223#define METHOD_TRACE(s, i)
224#define DEBUG(i, s)
225#define DEBUG_VAR(i, s, v...)
226#endif
227
228
229
230
231static int ips_detect(struct scsi_host_template *);
232static int ips_release(struct Scsi_Host *);
233static int ips_eh_abort(struct scsi_cmnd *);
234static int ips_eh_reset(struct scsi_cmnd *);
235static int ips_queue(struct scsi_cmnd *, void (*)(struct scsi_cmnd *));
236static const char *ips_info(struct Scsi_Host *);
237static irqreturn_t do_ipsintr(int, void *);
238static int ips_hainit(ips_ha_t *);
239static int ips_map_status(ips_ha_t *, ips_scb_t *, ips_stat_t *);
240static int ips_send_wait(ips_ha_t *, ips_scb_t *, int, int);
241static int ips_send_cmd(ips_ha_t *, ips_scb_t *);
242static int ips_online(ips_ha_t *, ips_scb_t *);
243static int ips_inquiry(ips_ha_t *, ips_scb_t *);
244static int ips_rdcap(ips_ha_t *, ips_scb_t *);
245static int ips_msense(ips_ha_t *, ips_scb_t *);
246static int ips_reqsen(ips_ha_t *, ips_scb_t *);
247static int ips_deallocatescbs(ips_ha_t *, int);
248static int ips_allocatescbs(ips_ha_t *);
249static int ips_reset_copperhead(ips_ha_t *);
250static int ips_reset_copperhead_memio(ips_ha_t *);
251static int ips_reset_morpheus(ips_ha_t *);
252static int ips_issue_copperhead(ips_ha_t *, ips_scb_t *);
253static int ips_issue_copperhead_memio(ips_ha_t *, ips_scb_t *);
254static int ips_issue_i2o(ips_ha_t *, ips_scb_t *);
255static int ips_issue_i2o_memio(ips_ha_t *, ips_scb_t *);
256static int ips_isintr_copperhead(ips_ha_t *);
257static int ips_isintr_copperhead_memio(ips_ha_t *);
258static int ips_isintr_morpheus(ips_ha_t *);
259static int ips_wait(ips_ha_t *, int, int);
260static int ips_write_driver_status(ips_ha_t *, int);
261static int ips_read_adapter_status(ips_ha_t *, int);
262static int ips_read_subsystem_parameters(ips_ha_t *, int);
263static int ips_read_config(ips_ha_t *, int);
264static int ips_clear_adapter(ips_ha_t *, int);
265static int ips_readwrite_page5(ips_ha_t *, int, int);
266static int ips_init_copperhead(ips_ha_t *);
267static int ips_init_copperhead_memio(ips_ha_t *);
268static int ips_init_morpheus(ips_ha_t *);
269static int ips_isinit_copperhead(ips_ha_t *);
270static int ips_isinit_copperhead_memio(ips_ha_t *);
271static int ips_isinit_morpheus(ips_ha_t *);
272static int ips_erase_bios(ips_ha_t *);
273static int ips_program_bios(ips_ha_t *, char *, uint32_t, uint32_t);
274static int ips_verify_bios(ips_ha_t *, char *, uint32_t, uint32_t);
275static int ips_erase_bios_memio(ips_ha_t *);
276static int ips_program_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
277static int ips_verify_bios_memio(ips_ha_t *, char *, uint32_t, uint32_t);
278static int ips_flash_copperhead(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
279static int ips_flash_bios(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
280static int ips_flash_firmware(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
281static void ips_free_flash_copperhead(ips_ha_t * ha);
282static void ips_get_bios_version(ips_ha_t *, int);
283static void ips_identify_controller(ips_ha_t *);
284static void ips_chkstatus(ips_ha_t *, IPS_STATUS *);
285static void ips_enable_int_copperhead(ips_ha_t *);
286static void ips_enable_int_copperhead_memio(ips_ha_t *);
287static void ips_enable_int_morpheus(ips_ha_t *);
288static int ips_intr_copperhead(ips_ha_t *);
289static int ips_intr_morpheus(ips_ha_t *);
290static void ips_next(ips_ha_t *, int);
291static void ipsintr_blocking(ips_ha_t *, struct ips_scb *);
292static void ipsintr_done(ips_ha_t *, struct ips_scb *);
293static void ips_done(ips_ha_t *, ips_scb_t *);
294static void ips_free(ips_ha_t *);
295static void ips_init_scb(ips_ha_t *, ips_scb_t *);
296static void ips_freescb(ips_ha_t *, ips_scb_t *);
297static void ips_setup_funclist(ips_ha_t *);
298static void ips_statinit(ips_ha_t *);
299static void ips_statinit_memio(ips_ha_t *);
300static void ips_fix_ffdc_time(ips_ha_t *, ips_scb_t *, time_t);
301static void ips_ffdc_reset(ips_ha_t *, int);
302static void ips_ffdc_time(ips_ha_t *);
303static uint32_t ips_statupd_copperhead(ips_ha_t *);
304static uint32_t ips_statupd_copperhead_memio(ips_ha_t *);
305static uint32_t ips_statupd_morpheus(ips_ha_t *);
306static ips_scb_t *ips_getscb(ips_ha_t *);
307static void ips_putq_scb_head(ips_scb_queue_t *, ips_scb_t *);
308static void ips_putq_wait_tail(ips_wait_queue_t *, struct scsi_cmnd *);
309static void ips_putq_copp_tail(ips_copp_queue_t *,
310 ips_copp_wait_item_t *);
311static ips_scb_t *ips_removeq_scb_head(ips_scb_queue_t *);
312static ips_scb_t *ips_removeq_scb(ips_scb_queue_t *, ips_scb_t *);
313static struct scsi_cmnd *ips_removeq_wait_head(ips_wait_queue_t *);
314static struct scsi_cmnd *ips_removeq_wait(ips_wait_queue_t *,
315 struct scsi_cmnd *);
316static ips_copp_wait_item_t *ips_removeq_copp(ips_copp_queue_t *,
317 ips_copp_wait_item_t *);
318static ips_copp_wait_item_t *ips_removeq_copp_head(ips_copp_queue_t *);
319
320static int ips_is_passthru(struct scsi_cmnd *);
321static int ips_make_passthru(ips_ha_t *, struct scsi_cmnd *, ips_scb_t *, int);
322static int ips_usrcmd(ips_ha_t *, ips_passthru_t *, ips_scb_t *);
323static void ips_cleanup_passthru(ips_ha_t *, ips_scb_t *);
324static void ips_scmd_buf_write(struct scsi_cmnd * scmd, void *data,
325 unsigned int count);
326static void ips_scmd_buf_read(struct scsi_cmnd * scmd, void *data,
327 unsigned int count);
328
329static int ips_proc_info(struct Scsi_Host *, char *, char **, off_t, int, int);
330static int ips_host_info(ips_ha_t *, char *, off_t, int);
331static void copy_mem_info(IPS_INFOSTR *, char *, int);
332static int copy_info(IPS_INFOSTR *, char *, ...);
333static int ips_abort_init(ips_ha_t * ha, int index);
334static int ips_init_phase2(int index);
335
336static int ips_init_phase1(struct pci_dev *pci_dev, int *indexPtr);
337static int ips_register_scsi(int index);
338
339static int ips_poll_for_flush_complete(ips_ha_t * ha);
340static void ips_flush_and_reset(ips_ha_t *ha);
341
342
343
344
345static const char ips_name[] = "ips";
346static struct Scsi_Host *ips_sh[IPS_MAX_ADAPTERS];
347static ips_ha_t *ips_ha[IPS_MAX_ADAPTERS];
348static unsigned int ips_next_controller;
349static unsigned int ips_num_controllers;
350static unsigned int ips_released_controllers;
351static int ips_hotplug;
352static int ips_cmd_timeout = 60;
353static int ips_reset_timeout = 60 * 5;
354static int ips_force_memio = 1;
355static int ips_force_i2o = 1;
356static int ips_ioctlsize = IPS_IOCTL_SIZE;
357static int ips_cd_boot;
358static char *ips_FlashData = NULL;
359static dma_addr_t ips_flashbusaddr;
360static long ips_FlashDataInUse;
361static uint32_t MaxLiteCmds = 32;
362static struct scsi_host_template ips_driver_template = {
363 .detect = ips_detect,
364 .release = ips_release,
365 .info = ips_info,
366 .queuecommand = ips_queue,
367 .eh_abort_handler = ips_eh_abort,
368 .eh_host_reset_handler = ips_eh_reset,
369 .proc_name = "ips",
370 .proc_info = ips_proc_info,
371 .slave_configure = ips_slave_configure,
372 .bios_param = ips_biosparam,
373 .this_id = -1,
374 .sg_tablesize = IPS_MAX_SG,
375 .cmd_per_lun = 3,
376 .use_clustering = ENABLE_CLUSTERING,
377};
378
379
380
381static struct pci_device_id ips_pci_table[] = {
382 { 0x1014, 0x002E, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
383 { 0x1014, 0x01BD, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
384 { 0x9005, 0x0250, PCI_ANY_ID, PCI_ANY_ID, 0, 0 },
385 { 0, }
386};
387
388MODULE_DEVICE_TABLE( pci, ips_pci_table );
389
390static char ips_hot_plug_name[] = "ips";
391
392static int __devinit ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent);
393static void __devexit ips_remove_device(struct pci_dev *pci_dev);
394
395static struct pci_driver ips_pci_driver = {
396 .name = ips_hot_plug_name,
397 .id_table = ips_pci_table,
398 .probe = ips_insert_device,
399 .remove = __devexit_p(ips_remove_device),
400};
401
402
403
404
405
406static int ips_halt(struct notifier_block *nb, ulong event, void *buf);
407
408#define MAX_ADAPTER_NAME 15
409
410static char ips_adapter_name[][30] = {
411 "ServeRAID",
412 "ServeRAID II",
413 "ServeRAID on motherboard",
414 "ServeRAID on motherboard",
415 "ServeRAID 3H",
416 "ServeRAID 3L",
417 "ServeRAID 4H",
418 "ServeRAID 4M",
419 "ServeRAID 4L",
420 "ServeRAID 4Mx",
421 "ServeRAID 4Lx",
422 "ServeRAID 5i",
423 "ServeRAID 5i",
424 "ServeRAID 6M",
425 "ServeRAID 6i",
426 "ServeRAID 7t",
427 "ServeRAID 7k",
428 "ServeRAID 7M"
429};
430
431static struct notifier_block ips_notifier = {
432 ips_halt, NULL, 0
433};
434
435
436
437
438static char ips_command_direction[] = {
439 IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT,
440 IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK,
441 IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
442 IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
443 IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_OUT,
444 IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_OUT,
445 IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_IN,
446 IPS_DATA_UNK, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
447 IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_UNK,
448 IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
449 IPS_DATA_OUT, IPS_DATA_NONE, IPS_DATA_IN, IPS_DATA_NONE, IPS_DATA_NONE,
450 IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT,
451 IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_OUT,
452 IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_IN, IPS_DATA_NONE,
453 IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_NONE, IPS_DATA_UNK,
454 IPS_DATA_NONE, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK,
455 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
456 IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
457 IPS_DATA_IN, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
458 IPS_DATA_UNK, 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_NONE, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_NONE,
473 IPS_DATA_OUT, IPS_DATA_UNK, IPS_DATA_NONE, IPS_DATA_UNK, IPS_DATA_OUT,
474 IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_OUT, IPS_DATA_NONE,
475 IPS_DATA_UNK, IPS_DATA_IN, IPS_DATA_OUT, IPS_DATA_IN, IPS_DATA_IN,
476 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
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_OUT,
486 IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK, IPS_DATA_UNK,
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};
491
492
493
494
495
496
497
498
499
500
501
502static int
503ips_setup(char *ips_str)
504{
505
506 int i;
507 char *key;
508 char *value;
509 IPS_OPTION options[] = {
510 {"noi2o", &ips_force_i2o, 0},
511 {"nommap", &ips_force_memio, 0},
512 {"ioctlsize", &ips_ioctlsize, IPS_IOCTL_SIZE},
513 {"cdboot", &ips_cd_boot, 0},
514 {"maxcmds", &MaxLiteCmds, 32},
515 };
516
517
518
519 while ((key = strsep(&ips_str, ",."))) {
520 if (!*key)
521 continue;
522 value = strchr(key, ':');
523 if (value)
524 *value++ = '\0';
525
526
527
528
529 for (i = 0; i < ARRAY_SIZE(options); i++) {
530 if (strnicmp
531 (key, options[i].option_name,
532 strlen(options[i].option_name)) == 0) {
533 if (value)
534 *options[i].option_flag =
535 simple_strtoul(value, NULL, 0);
536 else
537 *options[i].option_flag =
538 options[i].option_value;
539 break;
540 }
541 }
542 }
543
544 return (1);
545}
546
547__setup("ips=", ips_setup);
548
549
550
551
552
553
554
555
556
557
558
559
560static int
561ips_detect(struct scsi_host_template * SHT)
562{
563 int i;
564
565 METHOD_TRACE("ips_detect", 1);
566
567#ifdef MODULE
568 if (ips)
569 ips_setup(ips);
570#endif
571
572 for (i = 0; i < ips_num_controllers; i++) {
573 if (ips_register_scsi(i))
574 ips_free(ips_ha[i]);
575 ips_released_controllers++;
576 }
577 ips_hotplug = 1;
578 return (ips_num_controllers);
579}
580
581
582
583
584
585static void
586ips_setup_funclist(ips_ha_t * ha)
587{
588
589
590
591
592 if (IPS_IS_MORPHEUS(ha) || IPS_IS_MARCO(ha)) {
593
594 ha->func.isintr = ips_isintr_morpheus;
595 ha->func.isinit = ips_isinit_morpheus;
596 ha->func.issue = ips_issue_i2o_memio;
597 ha->func.init = ips_init_morpheus;
598 ha->func.statupd = ips_statupd_morpheus;
599 ha->func.reset = ips_reset_morpheus;
600 ha->func.intr = ips_intr_morpheus;
601 ha->func.enableint = ips_enable_int_morpheus;
602 } else if (IPS_USE_MEMIO(ha)) {
603
604 ha->func.isintr = ips_isintr_copperhead_memio;
605 ha->func.isinit = ips_isinit_copperhead_memio;
606 ha->func.init = ips_init_copperhead_memio;
607 ha->func.statupd = ips_statupd_copperhead_memio;
608 ha->func.statinit = ips_statinit_memio;
609 ha->func.reset = ips_reset_copperhead_memio;
610 ha->func.intr = ips_intr_copperhead;
611 ha->func.erasebios = ips_erase_bios_memio;
612 ha->func.programbios = ips_program_bios_memio;
613 ha->func.verifybios = ips_verify_bios_memio;
614 ha->func.enableint = ips_enable_int_copperhead_memio;
615 if (IPS_USE_I2O_DELIVER(ha))
616 ha->func.issue = ips_issue_i2o_memio;
617 else
618 ha->func.issue = ips_issue_copperhead_memio;
619 } else {
620
621 ha->func.isintr = ips_isintr_copperhead;
622 ha->func.isinit = ips_isinit_copperhead;
623 ha->func.init = ips_init_copperhead;
624 ha->func.statupd = ips_statupd_copperhead;
625 ha->func.statinit = ips_statinit;
626 ha->func.reset = ips_reset_copperhead;
627 ha->func.intr = ips_intr_copperhead;
628 ha->func.erasebios = ips_erase_bios;
629 ha->func.programbios = ips_program_bios;
630 ha->func.verifybios = ips_verify_bios;
631 ha->func.enableint = ips_enable_int_copperhead;
632
633 if (IPS_USE_I2O_DELIVER(ha))
634 ha->func.issue = ips_issue_i2o;
635 else
636 ha->func.issue = ips_issue_copperhead;
637 }
638}
639
640
641
642
643
644
645
646
647
648
649static int
650ips_release(struct Scsi_Host *sh)
651{
652 ips_scb_t *scb;
653 ips_ha_t *ha;
654 int i;
655
656 METHOD_TRACE("ips_release", 1);
657
658 scsi_remove_host(sh);
659
660 for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++) ;
661
662 if (i == IPS_MAX_ADAPTERS) {
663 printk(KERN_WARNING
664 "(%s) release, invalid Scsi_Host pointer.\n", ips_name);
665 BUG();
666 return (FALSE);
667 }
668
669 ha = IPS_HA(sh);
670
671 if (!ha)
672 return (FALSE);
673
674
675 scb = &ha->scbs[ha->max_cmds - 1];
676
677 ips_init_scb(ha, scb);
678
679 scb->timeout = ips_cmd_timeout;
680 scb->cdb[0] = IPS_CMD_FLUSH;
681
682 scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
683 scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
684 scb->cmd.flush_cache.state = IPS_NORM_STATE;
685 scb->cmd.flush_cache.reserved = 0;
686 scb->cmd.flush_cache.reserved2 = 0;
687 scb->cmd.flush_cache.reserved3 = 0;
688 scb->cmd.flush_cache.reserved4 = 0;
689
690 IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n");
691
692
693 if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) == IPS_FAILURE)
694 IPS_PRINTK(KERN_WARNING, ha->pcidev, "Incomplete Flush.\n");
695
696 IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Complete.\n");
697
698 ips_sh[i] = NULL;
699 ips_ha[i] = NULL;
700
701
702 ips_free(ha);
703
704
705 free_irq(ha->pcidev->irq, ha);
706
707 scsi_host_put(sh);
708
709 ips_released_controllers++;
710
711 return (FALSE);
712}
713
714
715
716
717
718
719
720
721
722
723static int
724ips_halt(struct notifier_block *nb, ulong event, void *buf)
725{
726 ips_scb_t *scb;
727 ips_ha_t *ha;
728 int i;
729
730 if ((event != SYS_RESTART) && (event != SYS_HALT) &&
731 (event != SYS_POWER_OFF))
732 return (NOTIFY_DONE);
733
734 for (i = 0; i < ips_next_controller; i++) {
735 ha = (ips_ha_t *) ips_ha[i];
736
737 if (!ha)
738 continue;
739
740 if (!ha->active)
741 continue;
742
743
744 scb = &ha->scbs[ha->max_cmds - 1];
745
746 ips_init_scb(ha, scb);
747
748 scb->timeout = ips_cmd_timeout;
749 scb->cdb[0] = IPS_CMD_FLUSH;
750
751 scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
752 scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
753 scb->cmd.flush_cache.state = IPS_NORM_STATE;
754 scb->cmd.flush_cache.reserved = 0;
755 scb->cmd.flush_cache.reserved2 = 0;
756 scb->cmd.flush_cache.reserved3 = 0;
757 scb->cmd.flush_cache.reserved4 = 0;
758
759 IPS_PRINTK(KERN_WARNING, ha->pcidev, "Flushing Cache.\n");
760
761
762 if (ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_ON) ==
763 IPS_FAILURE)
764 IPS_PRINTK(KERN_WARNING, ha->pcidev,
765 "Incomplete Flush.\n");
766 else
767 IPS_PRINTK(KERN_WARNING, ha->pcidev,
768 "Flushing Complete.\n");
769 }
770
771 return (NOTIFY_OK);
772}
773
774
775
776
777
778
779
780
781
782
783int ips_eh_abort(struct scsi_cmnd *SC)
784{
785 ips_ha_t *ha;
786 ips_copp_wait_item_t *item;
787 int ret;
788 struct Scsi_Host *host;
789
790 METHOD_TRACE("ips_eh_abort", 1);
791
792 if (!SC)
793 return (FAILED);
794
795 host = SC->device->host;
796 ha = (ips_ha_t *) SC->device->host->hostdata;
797
798 if (!ha)
799 return (FAILED);
800
801 if (!ha->active)
802 return (FAILED);
803
804 spin_lock(host->host_lock);
805
806
807 item = ha->copp_waitlist.head;
808 while ((item) && (item->scsi_cmd != SC))
809 item = item->next;
810
811 if (item) {
812
813 ips_removeq_copp(&ha->copp_waitlist, item);
814 ret = (SUCCESS);
815
816
817 } else if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
818
819 ret = (SUCCESS);
820 } else {
821
822 ret = (FAILED);
823 }
824
825 spin_unlock(host->host_lock);
826 return ret;
827}
828
829
830
831
832
833
834
835
836
837
838
839
840static int __ips_eh_reset(struct scsi_cmnd *SC)
841{
842 int ret;
843 int i;
844 ips_ha_t *ha;
845 ips_scb_t *scb;
846 ips_copp_wait_item_t *item;
847
848 METHOD_TRACE("ips_eh_reset", 1);
849
850#ifdef NO_IPS_RESET
851 return (FAILED);
852#else
853
854 if (!SC) {
855 DEBUG(1, "Reset called with NULL scsi command");
856
857 return (FAILED);
858 }
859
860 ha = (ips_ha_t *) SC->device->host->hostdata;
861
862 if (!ha) {
863 DEBUG(1, "Reset called with NULL ha struct");
864
865 return (FAILED);
866 }
867
868 if (!ha->active)
869 return (FAILED);
870
871
872 item = ha->copp_waitlist.head;
873 while ((item) && (item->scsi_cmd != SC))
874 item = item->next;
875
876 if (item) {
877
878 ips_removeq_copp(&ha->copp_waitlist, item);
879 return (SUCCESS);
880 }
881
882
883 if (ips_removeq_wait(&ha->scb_waitlist, SC)) {
884
885 return (SUCCESS);
886 }
887
888
889
890
891
892
893
894
895
896
897
898 if (ha->ioctl_reset == 0) {
899 scb = &ha->scbs[ha->max_cmds - 1];
900
901 ips_init_scb(ha, scb);
902
903 scb->timeout = ips_cmd_timeout;
904 scb->cdb[0] = IPS_CMD_FLUSH;
905
906 scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
907 scb->cmd.flush_cache.command_id = IPS_COMMAND_ID(ha, scb);
908 scb->cmd.flush_cache.state = IPS_NORM_STATE;
909 scb->cmd.flush_cache.reserved = 0;
910 scb->cmd.flush_cache.reserved2 = 0;
911 scb->cmd.flush_cache.reserved3 = 0;
912 scb->cmd.flush_cache.reserved4 = 0;
913
914
915 ret = ips_send_wait(ha, scb, ips_cmd_timeout, IPS_INTR_IORL);
916 if (ret == IPS_SUCCESS) {
917 IPS_PRINTK(KERN_NOTICE, ha->pcidev,
918 "Reset Request - Flushed Cache\n");
919 return (SUCCESS);
920 }
921 }
922
923
924
925
926 ha->ioctl_reset = 0;
927
928
929
930
931
932 IPS_PRINTK(KERN_NOTICE, ha->pcidev, "Resetting controller.\n");
933 ret = (*ha->func.reset) (ha);
934
935 if (!ret) {
936 struct scsi_cmnd *scsi_cmd;
937
938 IPS_PRINTK(KERN_NOTICE, ha->pcidev,
939 "Controller reset failed - controller now offline.\n");
940
941
942 DEBUG_VAR(1, "(%s%d) Failing active commands",
943 ips_name, ha->host_num);
944
945 while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
946 scb->scsi_cmd->result = DID_ERROR << 16;
947 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
948 ips_freescb(ha, scb);
949 }
950
951
952 DEBUG_VAR(1, "(%s%d) Failing pending commands",
953 ips_name, ha->host_num);
954
955 while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
956 scsi_cmd->result = DID_ERROR;
957 scsi_cmd->scsi_done(scsi_cmd);
958 }
959
960 ha->active = FALSE;
961 return (FAILED);
962 }
963
964 if (!ips_clear_adapter(ha, IPS_INTR_IORL)) {
965 struct scsi_cmnd *scsi_cmd;
966
967 IPS_PRINTK(KERN_NOTICE, ha->pcidev,
968 "Controller reset failed - controller now offline.\n");
969
970
971 DEBUG_VAR(1, "(%s%d) Failing active commands",
972 ips_name, ha->host_num);
973
974 while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
975 scb->scsi_cmd->result = DID_ERROR << 16;
976 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
977 ips_freescb(ha, scb);
978 }
979
980
981 DEBUG_VAR(1, "(%s%d) Failing pending commands",
982 ips_name, ha->host_num);
983
984 while ((scsi_cmd = ips_removeq_wait_head(&ha->scb_waitlist))) {
985 scsi_cmd->result = DID_ERROR << 16;
986 scsi_cmd->scsi_done(scsi_cmd);
987 }
988
989 ha->active = FALSE;
990 return (FAILED);
991 }
992
993
994 if (le32_to_cpu(ha->subsys->param[3]) & 0x300000) {
995 struct timeval tv;
996
997 do_gettimeofday(&tv);
998 ha->last_ffdc = tv.tv_sec;
999 ha->reset_count++;
1000 ips_ffdc_reset(ha, IPS_INTR_IORL);
1001 }
1002
1003
1004 DEBUG_VAR(1, "(%s%d) Failing active commands", ips_name, ha->host_num);
1005
1006 while ((scb = ips_removeq_scb_head(&ha->scb_activelist))) {
1007 scb->scsi_cmd->result =
1008 (DID_RESET << 16) | (SUGGEST_RETRY << 24);
1009 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
1010 ips_freescb(ha, scb);
1011 }
1012
1013
1014 for (i = 1; i < ha->nbus; i++)
1015 ha->dcdb_active[i - 1] = 0;
1016
1017
1018 ha->num_ioctl = 0;
1019
1020 ips_next(ha, IPS_INTR_IORL);
1021
1022 return (SUCCESS);
1023#endif
1024
1025}
1026
1027static int ips_eh_reset(struct scsi_cmnd *SC)
1028{
1029 int rc;
1030
1031 spin_lock_irq(SC->device->host->host_lock);
1032 rc = __ips_eh_reset(SC);
1033 spin_unlock_irq(SC->device->host->host_lock);
1034
1035 return rc;
1036}
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050static int ips_queue(struct scsi_cmnd *SC, void (*done) (struct scsi_cmnd *))
1051{
1052 ips_ha_t *ha;
1053 ips_passthru_t *pt;
1054
1055 METHOD_TRACE("ips_queue", 1);
1056
1057 ha = (ips_ha_t *) SC->device->host->hostdata;
1058
1059 if (!ha)
1060 return (1);
1061
1062 if (!ha->active)
1063 return (DID_ERROR);
1064
1065 if (ips_is_passthru(SC)) {
1066 if (ha->copp_waitlist.count == IPS_MAX_IOCTL_QUEUE) {
1067 SC->result = DID_BUS_BUSY << 16;
1068 done(SC);
1069
1070 return (0);
1071 }
1072 } else if (ha->scb_waitlist.count == IPS_MAX_QUEUE) {
1073 SC->result = DID_BUS_BUSY << 16;
1074 done(SC);
1075
1076 return (0);
1077 }
1078
1079 SC->scsi_done = done;
1080
1081 DEBUG_VAR(2, "(%s%d): ips_queue: cmd 0x%X (%d %d %d)",
1082 ips_name,
1083 ha->host_num,
1084 SC->cmnd[0],
1085 SC->device->channel, SC->device->id, SC->device->lun);
1086
1087
1088 if ((scmd_channel(SC) > 0)
1089 && (scmd_id(SC) == ha->ha_id[scmd_channel(SC)])) {
1090 SC->result = DID_NO_CONNECT << 16;
1091 done(SC);
1092
1093 return (0);
1094 }
1095
1096 if (ips_is_passthru(SC)) {
1097
1098 ips_copp_wait_item_t *scratch;
1099
1100
1101
1102
1103 pt = (ips_passthru_t *) scsi_sglist(SC);
1104 if ((pt->CoppCP.cmd.reset.op_code == IPS_CMD_RESET_CHANNEL) &&
1105 (pt->CoppCP.cmd.reset.adapter_flag == 1)) {
1106 if (ha->scb_activelist.count != 0) {
1107 SC->result = DID_BUS_BUSY << 16;
1108 done(SC);
1109 return (0);
1110 }
1111 ha->ioctl_reset = 1;
1112 __ips_eh_reset(SC);
1113 SC->result = DID_OK << 16;
1114 SC->scsi_done(SC);
1115 return (0);
1116 }
1117
1118
1119 scratch = kmalloc(sizeof (ips_copp_wait_item_t), GFP_ATOMIC);
1120
1121 if (!scratch) {
1122 SC->result = DID_ERROR << 16;
1123 done(SC);
1124
1125 return (0);
1126 }
1127
1128 scratch->scsi_cmd = SC;
1129 scratch->next = NULL;
1130
1131 ips_putq_copp_tail(&ha->copp_waitlist, scratch);
1132 } else {
1133 ips_putq_wait_tail(&ha->scb_waitlist, SC);
1134 }
1135
1136 ips_next(ha, IPS_INTR_IORL);
1137
1138 return (0);
1139}
1140
1141
1142
1143
1144
1145
1146
1147
1148
1149
1150static int ips_biosparam(struct scsi_device *sdev, struct block_device *bdev,
1151 sector_t capacity, int geom[])
1152{
1153 ips_ha_t *ha = (ips_ha_t *) sdev->host->hostdata;
1154 int heads;
1155 int sectors;
1156 int cylinders;
1157
1158 METHOD_TRACE("ips_biosparam", 1);
1159
1160 if (!ha)
1161
1162 return (0);
1163
1164 if (!ha->active)
1165 return (0);
1166
1167 if (!ips_read_adapter_status(ha, IPS_INTR_ON))
1168
1169 return (0);
1170
1171 if ((capacity > 0x400000) && ((ha->enq->ucMiscFlag & 0x8) == 0)) {
1172 heads = IPS_NORM_HEADS;
1173 sectors = IPS_NORM_SECTORS;
1174 } else {
1175 heads = IPS_COMP_HEADS;
1176 sectors = IPS_COMP_SECTORS;
1177 }
1178
1179 cylinders = (unsigned long) capacity / (heads * sectors);
1180
1181 DEBUG_VAR(2, "Geometry: heads: %d, sectors: %d, cylinders: %d",
1182 heads, sectors, cylinders);
1183
1184 geom[0] = heads;
1185 geom[1] = sectors;
1186 geom[2] = cylinders;
1187
1188 return (0);
1189}
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199
1200static int
1201ips_slave_configure(struct scsi_device * SDptr)
1202{
1203 ips_ha_t *ha;
1204 int min;
1205
1206 ha = IPS_HA(SDptr->host);
1207 if (SDptr->tagged_supported && SDptr->type == TYPE_DISK) {
1208 min = ha->max_cmds / 2;
1209 if (ha->enq->ucLogDriveCount <= 2)
1210 min = ha->max_cmds - 1;
1211 scsi_adjust_queue_depth(SDptr, MSG_ORDERED_TAG, min);
1212 }
1213
1214 SDptr->skip_ms_page_8 = 1;
1215 SDptr->skip_ms_page_3f = 1;
1216 return 0;
1217}
1218
1219
1220
1221
1222
1223
1224
1225
1226
1227
1228static irqreturn_t
1229do_ipsintr(int irq, void *dev_id)
1230{
1231 ips_ha_t *ha;
1232 struct Scsi_Host *host;
1233 int irqstatus;
1234
1235 METHOD_TRACE("do_ipsintr", 2);
1236
1237 ha = (ips_ha_t *) dev_id;
1238 if (!ha)
1239 return IRQ_NONE;
1240 host = ips_sh[ha->host_num];
1241
1242 if (!host) {
1243 (*ha->func.intr) (ha);
1244 return IRQ_HANDLED;
1245 }
1246
1247 spin_lock(host->host_lock);
1248
1249 if (!ha->active) {
1250 spin_unlock(host->host_lock);
1251 return IRQ_HANDLED;
1252 }
1253
1254 irqstatus = (*ha->func.intr) (ha);
1255
1256 spin_unlock(host->host_lock);
1257
1258
1259 ips_next(ha, IPS_INTR_ON);
1260 return IRQ_RETVAL(irqstatus);
1261}
1262
1263
1264
1265
1266
1267
1268
1269
1270
1271
1272
1273
1274int
1275ips_intr_copperhead(ips_ha_t * ha)
1276{
1277 ips_stat_t *sp;
1278 ips_scb_t *scb;
1279 IPS_STATUS cstatus;
1280 int intrstatus;
1281
1282 METHOD_TRACE("ips_intr", 2);
1283
1284 if (!ha)
1285 return 0;
1286
1287 if (!ha->active)
1288 return 0;
1289
1290 intrstatus = (*ha->func.isintr) (ha);
1291
1292 if (!intrstatus) {
1293
1294
1295
1296
1297 return 0;
1298 }
1299
1300 while (TRUE) {
1301 sp = &ha->sp;
1302
1303 intrstatus = (*ha->func.isintr) (ha);
1304
1305 if (!intrstatus)
1306 break;
1307 else
1308 cstatus.value = (*ha->func.statupd) (ha);
1309
1310 if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
1311
1312 continue;
1313 }
1314
1315 ips_chkstatus(ha, &cstatus);
1316 scb = (ips_scb_t *) sp->scb_addr;
1317
1318
1319
1320
1321
1322 (*scb->callback) (ha, scb);
1323 }
1324 return 1;
1325}
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338int
1339ips_intr_morpheus(ips_ha_t * ha)
1340{
1341 ips_stat_t *sp;
1342 ips_scb_t *scb;
1343 IPS_STATUS cstatus;
1344 int intrstatus;
1345
1346 METHOD_TRACE("ips_intr_morpheus", 2);
1347
1348 if (!ha)
1349 return 0;
1350
1351 if (!ha->active)
1352 return 0;
1353
1354 intrstatus = (*ha->func.isintr) (ha);
1355
1356 if (!intrstatus) {
1357
1358
1359
1360
1361 return 0;
1362 }
1363
1364 while (TRUE) {
1365 sp = &ha->sp;
1366
1367 intrstatus = (*ha->func.isintr) (ha);
1368
1369 if (!intrstatus)
1370 break;
1371 else
1372 cstatus.value = (*ha->func.statupd) (ha);
1373
1374 if (cstatus.value == 0xffffffff)
1375
1376 break;
1377
1378 if (cstatus.fields.command_id > (IPS_MAX_CMDS - 1)) {
1379 IPS_PRINTK(KERN_WARNING, ha->pcidev,
1380 "Spurious interrupt; no ccb.\n");
1381
1382 continue;
1383 }
1384
1385 ips_chkstatus(ha, &cstatus);
1386 scb = (ips_scb_t *) sp->scb_addr;
1387
1388
1389
1390
1391
1392 (*scb->callback) (ha, scb);
1393 }
1394 return 1;
1395}
1396
1397
1398
1399
1400
1401
1402
1403
1404
1405
1406static const char *
1407ips_info(struct Scsi_Host *SH)
1408{
1409 static char buffer[256];
1410 char *bp;
1411 ips_ha_t *ha;
1412
1413 METHOD_TRACE("ips_info", 1);
1414
1415 ha = IPS_HA(SH);
1416
1417 if (!ha)
1418 return (NULL);
1419
1420 bp = &buffer[0];
1421 memset(bp, 0, sizeof (buffer));
1422
1423 sprintf(bp, "%s%s%s Build %d", "IBM PCI ServeRAID ",
1424 IPS_VERSION_HIGH, IPS_VERSION_LOW, IPS_BUILD_IDENT);
1425
1426 if (ha->ad_type > 0 && ha->ad_type <= MAX_ADAPTER_NAME) {
1427 strcat(bp, " <");
1428 strcat(bp, ips_adapter_name[ha->ad_type - 1]);
1429 strcat(bp, ">");
1430 }
1431
1432 return (bp);
1433}
1434
1435
1436
1437
1438
1439
1440
1441
1442
1443
1444static int
1445ips_proc_info(struct Scsi_Host *host, char *buffer, char **start, off_t offset,
1446 int length, int func)
1447{
1448 int i;
1449 int ret;
1450 ips_ha_t *ha = NULL;
1451
1452 METHOD_TRACE("ips_proc_info", 1);
1453
1454
1455 for (i = 0; i < ips_next_controller; i++) {
1456 if (ips_sh[i]) {
1457 if (ips_sh[i] == host) {
1458 ha = (ips_ha_t *) ips_sh[i]->hostdata;
1459 break;
1460 }
1461 }
1462 }
1463
1464 if (!ha)
1465 return (-EINVAL);
1466
1467 if (func) {
1468
1469 return (0);
1470 } else {
1471
1472 if (start)
1473 *start = buffer;
1474
1475 ret = ips_host_info(ha, buffer, offset, length);
1476
1477 return (ret);
1478 }
1479}
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494static int ips_is_passthru(struct scsi_cmnd *SC)
1495{
1496 unsigned long flags;
1497
1498 METHOD_TRACE("ips_is_passthru", 1);
1499
1500 if (!SC)
1501 return (0);
1502
1503 if ((SC->cmnd[0] == IPS_IOCTL_COMMAND) &&
1504 (SC->device->channel == 0) &&
1505 (SC->device->id == IPS_ADAPTER_ID) &&
1506 (SC->device->lun == 0) && scsi_sglist(SC)) {
1507 struct scatterlist *sg = scsi_sglist(SC);
1508 char *buffer;
1509
1510
1511
1512 local_irq_save(flags);
1513 buffer = kmap_atomic(sg_page(sg), KM_IRQ0) + sg->offset;
1514 if (buffer && buffer[0] == 'C' && buffer[1] == 'O' &&
1515 buffer[2] == 'P' && buffer[3] == 'P') {
1516 kunmap_atomic(buffer - sg->offset, KM_IRQ0);
1517 local_irq_restore(flags);
1518 return 1;
1519 }
1520 kunmap_atomic(buffer - sg->offset, KM_IRQ0);
1521 local_irq_restore(flags);
1522 }
1523 return 0;
1524}
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534static int
1535ips_alloc_passthru_buffer(ips_ha_t * ha, int length)
1536{
1537 void *bigger_buf;
1538 dma_addr_t dma_busaddr;
1539
1540 if (ha->ioctl_data && length <= ha->ioctl_len)
1541 return 0;
1542
1543 bigger_buf = pci_alloc_consistent(ha->pcidev, length, &dma_busaddr);
1544 if (bigger_buf) {
1545
1546 pci_free_consistent(ha->pcidev, ha->ioctl_len, ha->ioctl_data,
1547 ha->ioctl_busaddr);
1548
1549 ha->ioctl_data = (char *) bigger_buf;
1550 ha->ioctl_len = length;
1551 ha->ioctl_busaddr = dma_busaddr;
1552 } else {
1553 return -1;
1554 }
1555 return 0;
1556}
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567static int
1568ips_make_passthru(ips_ha_t *ha, struct scsi_cmnd *SC, ips_scb_t *scb, int intr)
1569{
1570 ips_passthru_t *pt;
1571 int length = 0;
1572 int i, ret;
1573 struct scatterlist *sg = scsi_sglist(SC);
1574
1575 METHOD_TRACE("ips_make_passthru", 1);
1576
1577 scsi_for_each_sg(SC, sg, scsi_sg_count(SC), i)
1578 length += sg->length;
1579
1580 if (length < sizeof (ips_passthru_t)) {
1581
1582 DEBUG_VAR(1, "(%s%d) Passthru structure wrong size",
1583 ips_name, ha->host_num);
1584 return (IPS_FAILURE);
1585 }
1586 if (ips_alloc_passthru_buffer(ha, length)) {
1587
1588
1589 if (ha->ioctl_data) {
1590 pt = (ips_passthru_t *) ha->ioctl_data;
1591 ips_scmd_buf_read(SC, pt, sizeof (ips_passthru_t));
1592 pt->BasicStatus = 0x0B;
1593 pt->ExtendedStatus = 0x00;
1594 ips_scmd_buf_write(SC, pt, sizeof (ips_passthru_t));
1595 }
1596 return IPS_FAILURE;
1597 }
1598 ha->ioctl_datasize = length;
1599
1600 ips_scmd_buf_read(SC, ha->ioctl_data, ha->ioctl_datasize);
1601 pt = (ips_passthru_t *) ha->ioctl_data;
1602
1603
1604
1605
1606
1607
1608
1609
1610
1611
1612
1613 switch (pt->CoppCmd) {
1614 case IPS_NUMCTRLS:
1615 memcpy(ha->ioctl_data + sizeof (ips_passthru_t),
1616 &ips_num_controllers, sizeof (int));
1617 ips_scmd_buf_write(SC, ha->ioctl_data,
1618 sizeof (ips_passthru_t) + sizeof (int));
1619 SC->result = DID_OK << 16;
1620
1621 return (IPS_SUCCESS_IMM);
1622
1623 case IPS_COPPUSRCMD:
1624 case IPS_COPPIOCCMD:
1625 if (SC->cmnd[0] == IPS_IOCTL_COMMAND) {
1626 if (length < (sizeof (ips_passthru_t) + pt->CmdBSize)) {
1627
1628 DEBUG_VAR(1,
1629 "(%s%d) Passthru structure wrong size",
1630 ips_name, ha->host_num);
1631
1632 return (IPS_FAILURE);
1633 }
1634
1635 if (ha->pcidev->device == IPS_DEVICEID_COPPERHEAD &&
1636 pt->CoppCP.cmd.flashfw.op_code ==
1637 IPS_CMD_RW_BIOSFW) {
1638 ret = ips_flash_copperhead(ha, pt, scb);
1639 ips_scmd_buf_write(SC, ha->ioctl_data,
1640 sizeof (ips_passthru_t));
1641 return ret;
1642 }
1643 if (ips_usrcmd(ha, pt, scb))
1644 return (IPS_SUCCESS);
1645 else
1646 return (IPS_FAILURE);
1647 }
1648
1649 break;
1650
1651 }
1652
1653 return (IPS_FAILURE);
1654}
1655
1656
1657
1658
1659
1660
1661static int
1662ips_flash_copperhead(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1663{
1664 int datasize;
1665
1666
1667
1668 if (IPS_IS_TROMBONE(ha) && pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE) {
1669 if (ips_usrcmd(ha, pt, scb))
1670 return IPS_SUCCESS;
1671 else
1672 return IPS_FAILURE;
1673 }
1674 pt->BasicStatus = 0x0B;
1675 pt->ExtendedStatus = 0;
1676 scb->scsi_cmd->result = DID_OK << 16;
1677
1678
1679 if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1680 pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) {
1681 pt->BasicStatus = 0;
1682 return ips_flash_bios(ha, pt, scb);
1683 } else if (pt->CoppCP.cmd.flashfw.packet_num == 0) {
1684 if (ips_FlashData && !test_and_set_bit(0, &ips_FlashDataInUse)){
1685 ha->flash_data = ips_FlashData;
1686 ha->flash_busaddr = ips_flashbusaddr;
1687 ha->flash_len = PAGE_SIZE << 7;
1688 ha->flash_datasize = 0;
1689 } else if (!ha->flash_data) {
1690 datasize = pt->CoppCP.cmd.flashfw.total_packets *
1691 pt->CoppCP.cmd.flashfw.count;
1692 ha->flash_data = pci_alloc_consistent(ha->pcidev,
1693 datasize,
1694 &ha->flash_busaddr);
1695 if (!ha->flash_data){
1696 printk(KERN_WARNING "Unable to allocate a flash buffer\n");
1697 return IPS_FAILURE;
1698 }
1699 ha->flash_datasize = 0;
1700 ha->flash_len = datasize;
1701 } else
1702 return IPS_FAILURE;
1703 } else {
1704 if (pt->CoppCP.cmd.flashfw.count + ha->flash_datasize >
1705 ha->flash_len) {
1706 ips_free_flash_copperhead(ha);
1707 IPS_PRINTK(KERN_WARNING, ha->pcidev,
1708 "failed size sanity check\n");
1709 return IPS_FAILURE;
1710 }
1711 }
1712 if (!ha->flash_data)
1713 return IPS_FAILURE;
1714 pt->BasicStatus = 0;
1715 memcpy(&ha->flash_data[ha->flash_datasize], pt + 1,
1716 pt->CoppCP.cmd.flashfw.count);
1717 ha->flash_datasize += pt->CoppCP.cmd.flashfw.count;
1718 if (pt->CoppCP.cmd.flashfw.packet_num ==
1719 pt->CoppCP.cmd.flashfw.total_packets - 1) {
1720 if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE)
1721 return ips_flash_bios(ha, pt, scb);
1722 else if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE)
1723 return ips_flash_firmware(ha, pt, scb);
1724 }
1725 return IPS_SUCCESS_IMM;
1726}
1727
1728
1729
1730
1731
1732
1733static int
1734ips_flash_bios(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1735{
1736
1737 if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1738 pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_BIOS) {
1739 if ((!ha->func.programbios) || (!ha->func.erasebios) ||
1740 (!ha->func.verifybios))
1741 goto error;
1742 if ((*ha->func.erasebios) (ha)) {
1743 DEBUG_VAR(1,
1744 "(%s%d) flash bios failed - unable to erase flash",
1745 ips_name, ha->host_num);
1746 goto error;
1747 } else
1748 if ((*ha->func.programbios) (ha,
1749 ha->flash_data +
1750 IPS_BIOS_HEADER,
1751 ha->flash_datasize -
1752 IPS_BIOS_HEADER, 0)) {
1753 DEBUG_VAR(1,
1754 "(%s%d) flash bios failed - unable to flash",
1755 ips_name, ha->host_num);
1756 goto error;
1757 } else
1758 if ((*ha->func.verifybios) (ha,
1759 ha->flash_data +
1760 IPS_BIOS_HEADER,
1761 ha->flash_datasize -
1762 IPS_BIOS_HEADER, 0)) {
1763 DEBUG_VAR(1,
1764 "(%s%d) flash bios failed - unable to verify flash",
1765 ips_name, ha->host_num);
1766 goto error;
1767 }
1768 ips_free_flash_copperhead(ha);
1769 return IPS_SUCCESS_IMM;
1770 } else if (pt->CoppCP.cmd.flashfw.type == IPS_BIOS_IMAGE &&
1771 pt->CoppCP.cmd.flashfw.direction == IPS_ERASE_BIOS) {
1772 if (!ha->func.erasebios)
1773 goto error;
1774 if ((*ha->func.erasebios) (ha)) {
1775 DEBUG_VAR(1,
1776 "(%s%d) flash bios failed - unable to erase flash",
1777 ips_name, ha->host_num);
1778 goto error;
1779 }
1780 return IPS_SUCCESS_IMM;
1781 }
1782 error:
1783 pt->BasicStatus = 0x0B;
1784 pt->ExtendedStatus = 0x00;
1785 ips_free_flash_copperhead(ha);
1786 return IPS_FAILURE;
1787}
1788
1789
1790
1791
1792
1793
1794
1795
1796
1797static int
1798ips_fill_scb_sg_single(ips_ha_t * ha, dma_addr_t busaddr,
1799 ips_scb_t * scb, int indx, unsigned int e_len)
1800{
1801
1802 int ret_val = 0;
1803
1804 if ((scb->data_len + e_len) > ha->max_xfer) {
1805 e_len = ha->max_xfer - scb->data_len;
1806 scb->breakup = indx;
1807 ++scb->sg_break;
1808 ret_val = -1;
1809 } else {
1810 scb->breakup = 0;
1811 scb->sg_break = 0;
1812 }
1813 if (IPS_USE_ENH_SGLIST(ha)) {
1814 scb->sg_list.enh_list[indx].address_lo =
1815 cpu_to_le32(pci_dma_lo32(busaddr));
1816 scb->sg_list.enh_list[indx].address_hi =
1817 cpu_to_le32(pci_dma_hi32(busaddr));
1818 scb->sg_list.enh_list[indx].length = cpu_to_le32(e_len);
1819 } else {
1820 scb->sg_list.std_list[indx].address =
1821 cpu_to_le32(pci_dma_lo32(busaddr));
1822 scb->sg_list.std_list[indx].length = cpu_to_le32(e_len);
1823 }
1824
1825 ++scb->sg_len;
1826 scb->data_len += e_len;
1827 return ret_val;
1828}
1829
1830
1831
1832
1833
1834
1835static int
1836ips_flash_firmware(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1837{
1838 IPS_SG_LIST sg_list;
1839 uint32_t cmd_busaddr;
1840
1841 if (pt->CoppCP.cmd.flashfw.type == IPS_FW_IMAGE &&
1842 pt->CoppCP.cmd.flashfw.direction == IPS_WRITE_FW) {
1843 memset(&pt->CoppCP.cmd, 0, sizeof (IPS_HOST_COMMAND));
1844 pt->CoppCP.cmd.flashfw.op_code = IPS_CMD_DOWNLOAD;
1845 pt->CoppCP.cmd.flashfw.count = cpu_to_le32(ha->flash_datasize);
1846 } else {
1847 pt->BasicStatus = 0x0B;
1848 pt->ExtendedStatus = 0x00;
1849 ips_free_flash_copperhead(ha);
1850 return IPS_FAILURE;
1851 }
1852
1853 sg_list.list = scb->sg_list.list;
1854 cmd_busaddr = scb->scb_busaddr;
1855
1856 memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD));
1857
1858 scb->sg_list.list = sg_list.list;
1859 scb->scb_busaddr = cmd_busaddr;
1860 scb->bus = scb->scsi_cmd->device->channel;
1861 scb->target_id = scb->scsi_cmd->device->id;
1862 scb->lun = scb->scsi_cmd->device->lun;
1863 scb->sg_len = 0;
1864 scb->data_len = 0;
1865 scb->flags = 0;
1866 scb->op_code = 0;
1867 scb->callback = ipsintr_done;
1868 scb->timeout = ips_cmd_timeout;
1869
1870 scb->data_len = ha->flash_datasize;
1871 scb->data_busaddr =
1872 pci_map_single(ha->pcidev, ha->flash_data, scb->data_len,
1873 IPS_DMA_DIR(scb));
1874 scb->flags |= IPS_SCB_MAP_SINGLE;
1875 scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
1876 scb->cmd.flashfw.buffer_addr = cpu_to_le32(scb->data_busaddr);
1877 if (pt->TimeOut)
1878 scb->timeout = pt->TimeOut;
1879 scb->scsi_cmd->result = DID_OK << 16;
1880 return IPS_SUCCESS;
1881}
1882
1883
1884
1885
1886
1887
1888static void
1889ips_free_flash_copperhead(ips_ha_t * ha)
1890{
1891 if (ha->flash_data == ips_FlashData)
1892 test_and_clear_bit(0, &ips_FlashDataInUse);
1893 else if (ha->flash_data)
1894 pci_free_consistent(ha->pcidev, ha->flash_len, ha->flash_data,
1895 ha->flash_busaddr);
1896 ha->flash_data = NULL;
1897}
1898
1899
1900
1901
1902
1903
1904
1905
1906
1907
1908static int
1909ips_usrcmd(ips_ha_t * ha, ips_passthru_t * pt, ips_scb_t * scb)
1910{
1911 IPS_SG_LIST sg_list;
1912 uint32_t cmd_busaddr;
1913
1914 METHOD_TRACE("ips_usrcmd", 1);
1915
1916 if ((!scb) || (!pt) || (!ha))
1917 return (0);
1918
1919
1920 sg_list.list = scb->sg_list.list;
1921 cmd_busaddr = scb->scb_busaddr;
1922
1923 memcpy(&scb->cmd, &pt->CoppCP.cmd, sizeof (IPS_IOCTL_CMD));
1924 memcpy(&scb->dcdb, &pt->CoppCP.dcdb, sizeof (IPS_DCDB_TABLE));
1925
1926
1927 scb->sg_list.list = sg_list.list;
1928 scb->scb_busaddr = cmd_busaddr;
1929 scb->bus = scb->scsi_cmd->device->channel;
1930 scb->target_id = scb->scsi_cmd->device->id;
1931 scb->lun = scb->scsi_cmd->device->lun;
1932 scb->sg_len = 0;
1933 scb->data_len = 0;
1934 scb->flags = 0;
1935 scb->op_code = 0;
1936 scb->callback = ipsintr_done;
1937 scb->timeout = ips_cmd_timeout;
1938 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
1939
1940
1941 if ((scb->cmd.basic_io.op_code == IPS_CMD_READ_SG) ||
1942 (scb->cmd.basic_io.op_code == IPS_CMD_WRITE_SG) ||
1943 (scb->cmd.basic_io.op_code == IPS_CMD_DCDB_SG))
1944 return (0);
1945
1946 if (pt->CmdBSize) {
1947 scb->data_len = pt->CmdBSize;
1948 scb->data_busaddr = ha->ioctl_busaddr + sizeof (ips_passthru_t);
1949 } else {
1950 scb->data_busaddr = 0L;
1951 }
1952
1953 if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
1954 scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
1955 (unsigned long) &scb->
1956 dcdb -
1957 (unsigned long) scb);
1958
1959 if (pt->CmdBSize) {
1960 if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
1961 scb->dcdb.buffer_pointer =
1962 cpu_to_le32(scb->data_busaddr);
1963 else
1964 scb->cmd.basic_io.sg_addr =
1965 cpu_to_le32(scb->data_busaddr);
1966 }
1967
1968
1969 if (pt->TimeOut) {
1970 scb->timeout = pt->TimeOut;
1971
1972 if (pt->TimeOut <= 10)
1973 scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
1974 else if (pt->TimeOut <= 60)
1975 scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
1976 else
1977 scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
1978 }
1979
1980
1981 scb->scsi_cmd->result = DID_OK << 16;
1982
1983
1984 return (1);
1985}
1986
1987
1988
1989
1990
1991
1992
1993
1994
1995
1996static void
1997ips_cleanup_passthru(ips_ha_t * ha, ips_scb_t * scb)
1998{
1999 ips_passthru_t *pt;
2000
2001 METHOD_TRACE("ips_cleanup_passthru", 1);
2002
2003 if ((!scb) || (!scb->scsi_cmd) || (!scsi_sglist(scb->scsi_cmd))) {
2004 DEBUG_VAR(1, "(%s%d) couldn't cleanup after passthru",
2005 ips_name, ha->host_num);
2006
2007 return;
2008 }
2009 pt = (ips_passthru_t *) ha->ioctl_data;
2010
2011
2012 if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB)
2013 memcpy(&pt->CoppCP.dcdb, &scb->dcdb, sizeof (IPS_DCDB_TABLE));
2014
2015 pt->BasicStatus = scb->basic_status;
2016 pt->ExtendedStatus = scb->extended_status;
2017 pt->AdapterType = ha->ad_type;
2018
2019 if (ha->pcidev->device == IPS_DEVICEID_COPPERHEAD &&
2020 (scb->cmd.flashfw.op_code == IPS_CMD_DOWNLOAD ||
2021 scb->cmd.flashfw.op_code == IPS_CMD_RW_BIOSFW))
2022 ips_free_flash_copperhead(ha);
2023
2024 ips_scmd_buf_write(scb->scsi_cmd, ha->ioctl_data, ha->ioctl_datasize);
2025}
2026
2027
2028
2029
2030
2031
2032
2033
2034
2035
2036static int
2037ips_host_info(ips_ha_t * ha, char *ptr, off_t offset, int len)
2038{
2039 IPS_INFOSTR info;
2040
2041 METHOD_TRACE("ips_host_info", 1);
2042
2043 info.buffer = ptr;
2044 info.length = len;
2045 info.offset = offset;
2046 info.pos = 0;
2047 info.localpos = 0;
2048
2049 copy_info(&info, "\nIBM ServeRAID General Information:\n\n");
2050
2051 if ((le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) &&
2052 (le16_to_cpu(ha->nvram->adapter_type) != 0))
2053 copy_info(&info, "\tController Type : %s\n",
2054 ips_adapter_name[ha->ad_type - 1]);
2055 else
2056 copy_info(&info,
2057 "\tController Type : Unknown\n");
2058
2059 if (ha->io_addr)
2060 copy_info(&info,
2061 "\tIO region : 0x%lx (%d bytes)\n",
2062 ha->io_addr, ha->io_len);
2063
2064 if (ha->mem_addr) {
2065 copy_info(&info,
2066 "\tMemory region : 0x%lx (%d bytes)\n",
2067 ha->mem_addr, ha->mem_len);
2068 copy_info(&info,
2069 "\tShared memory address : 0x%lx\n",
2070 ha->mem_ptr);
2071 }
2072
2073 copy_info(&info, "\tIRQ number : %d\n", ha->pcidev->irq);
2074
2075
2076
2077
2078 if (le32_to_cpu(ha->nvram->signature) == IPS_NVRAM_P5_SIG) {
2079 if (ha->nvram->bios_low[3] == 0) {
2080 copy_info(&info,
2081 "\tBIOS Version : %c%c%c%c%c%c%c\n",
2082 ha->nvram->bios_high[0], ha->nvram->bios_high[1],
2083 ha->nvram->bios_high[2], ha->nvram->bios_high[3],
2084 ha->nvram->bios_low[0], ha->nvram->bios_low[1],
2085 ha->nvram->bios_low[2]);
2086
2087 } else {
2088 copy_info(&info,
2089 "\tBIOS Version : %c%c%c%c%c%c%c%c\n",
2090 ha->nvram->bios_high[0], ha->nvram->bios_high[1],
2091 ha->nvram->bios_high[2], ha->nvram->bios_high[3],
2092 ha->nvram->bios_low[0], ha->nvram->bios_low[1],
2093 ha->nvram->bios_low[2], ha->nvram->bios_low[3]);
2094 }
2095
2096 }
2097
2098 if (ha->enq->CodeBlkVersion[7] == 0) {
2099 copy_info(&info,
2100 "\tFirmware Version : %c%c%c%c%c%c%c\n",
2101 ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
2102 ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
2103 ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
2104 ha->enq->CodeBlkVersion[6]);
2105 } else {
2106 copy_info(&info,
2107 "\tFirmware Version : %c%c%c%c%c%c%c%c\n",
2108 ha->enq->CodeBlkVersion[0], ha->enq->CodeBlkVersion[1],
2109 ha->enq->CodeBlkVersion[2], ha->enq->CodeBlkVersion[3],
2110 ha->enq->CodeBlkVersion[4], ha->enq->CodeBlkVersion[5],
2111 ha->enq->CodeBlkVersion[6], ha->enq->CodeBlkVersion[7]);
2112 }
2113
2114 if (ha->enq->BootBlkVersion[7] == 0) {
2115 copy_info(&info,
2116 "\tBoot Block Version : %c%c%c%c%c%c%c\n",
2117 ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
2118 ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
2119 ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
2120 ha->enq->BootBlkVersion[6]);
2121 } else {
2122 copy_info(&info,
2123 "\tBoot Block Version : %c%c%c%c%c%c%c%c\n",
2124 ha->enq->BootBlkVersion[0], ha->enq->BootBlkVersion[1],
2125 ha->enq->BootBlkVersion[2], ha->enq->BootBlkVersion[3],
2126 ha->enq->BootBlkVersion[4], ha->enq->BootBlkVersion[5],
2127 ha->enq->BootBlkVersion[6], ha->enq->BootBlkVersion[7]);
2128 }
2129
2130 copy_info(&info, "\tDriver Version : %s%s\n",
2131 IPS_VERSION_HIGH, IPS_VERSION_LOW);
2132
2133 copy_info(&info, "\tDriver Build : %d\n",
2134 IPS_BUILD_IDENT);
2135
2136 copy_info(&info, "\tMax Physical Devices : %d\n",
2137 ha->enq->ucMaxPhysicalDevices);
2138 copy_info(&info, "\tMax Active Commands : %d\n",
2139 ha->max_cmds);
2140 copy_info(&info, "\tCurrent Queued Commands : %d\n",
2141 ha->scb_waitlist.count);
2142 copy_info(&info, "\tCurrent Active Commands : %d\n",
2143 ha->scb_activelist.count - ha->num_ioctl);
2144 copy_info(&info, "\tCurrent Queued PT Commands : %d\n",
2145 ha->copp_waitlist.count);
2146 copy_info(&info, "\tCurrent Active PT Commands : %d\n",
2147 ha->num_ioctl);
2148
2149 copy_info(&info, "\n");
2150
2151 return (info.localpos);
2152}
2153
2154
2155
2156
2157
2158
2159
2160
2161
2162
2163static void
2164copy_mem_info(IPS_INFOSTR * info, char *data, int len)
2165{
2166 METHOD_TRACE("copy_mem_info", 1);
2167
2168 if (info->pos + len < info->offset) {
2169 info->pos += len;
2170 return;
2171 }
2172
2173 if (info->pos < info->offset) {
2174 data += (info->offset - info->pos);
2175 len -= (info->offset - info->pos);
2176 info->pos += (info->offset - info->pos);
2177 }
2178
2179 if (info->localpos + len > info->length)
2180 len = info->length - info->localpos;
2181
2182 if (len > 0) {
2183 memcpy(info->buffer + info->localpos, data, len);
2184 info->pos += len;
2185 info->localpos += len;
2186 }
2187}
2188
2189
2190
2191
2192
2193
2194
2195
2196
2197
2198static int
2199copy_info(IPS_INFOSTR * info, char *fmt, ...)
2200{
2201 va_list args;
2202 char buf[128];
2203 int len;
2204
2205 METHOD_TRACE("copy_info", 1);
2206
2207 va_start(args, fmt);
2208 len = vsprintf(buf, fmt, args);
2209 va_end(args);
2210
2211 copy_mem_info(info, buf, len);
2212
2213 return (len);
2214}
2215
2216
2217
2218
2219
2220
2221
2222
2223
2224
2225static void
2226ips_identify_controller(ips_ha_t * ha)
2227{
2228 METHOD_TRACE("ips_identify_controller", 1);
2229
2230 switch (ha->pcidev->device) {
2231 case IPS_DEVICEID_COPPERHEAD:
2232 if (ha->pcidev->revision <= IPS_REVID_SERVERAID) {
2233 ha->ad_type = IPS_ADTYPE_SERVERAID;
2234 } else if (ha->pcidev->revision == IPS_REVID_SERVERAID2) {
2235 ha->ad_type = IPS_ADTYPE_SERVERAID2;
2236 } else if (ha->pcidev->revision == IPS_REVID_NAVAJO) {
2237 ha->ad_type = IPS_ADTYPE_NAVAJO;
2238 } else if ((ha->pcidev->revision == IPS_REVID_SERVERAID2)
2239 && (ha->slot_num == 0)) {
2240 ha->ad_type = IPS_ADTYPE_KIOWA;
2241 } else if ((ha->pcidev->revision >= IPS_REVID_CLARINETP1) &&
2242 (ha->pcidev->revision <= IPS_REVID_CLARINETP3)) {
2243 if (ha->enq->ucMaxPhysicalDevices == 15)
2244 ha->ad_type = IPS_ADTYPE_SERVERAID3L;
2245 else
2246 ha->ad_type = IPS_ADTYPE_SERVERAID3;
2247 } else if ((ha->pcidev->revision >= IPS_REVID_TROMBONE32) &&
2248 (ha->pcidev->revision <= IPS_REVID_TROMBONE64)) {
2249 ha->ad_type = IPS_ADTYPE_SERVERAID4H;
2250 }
2251 break;
2252
2253 case IPS_DEVICEID_MORPHEUS:
2254 switch (ha->pcidev->subsystem_device) {
2255 case IPS_SUBDEVICEID_4L:
2256 ha->ad_type = IPS_ADTYPE_SERVERAID4L;
2257 break;
2258
2259 case IPS_SUBDEVICEID_4M:
2260 ha->ad_type = IPS_ADTYPE_SERVERAID4M;
2261 break;
2262
2263 case IPS_SUBDEVICEID_4MX:
2264 ha->ad_type = IPS_ADTYPE_SERVERAID4MX;
2265 break;
2266
2267 case IPS_SUBDEVICEID_4LX:
2268 ha->ad_type = IPS_ADTYPE_SERVERAID4LX;
2269 break;
2270
2271 case IPS_SUBDEVICEID_5I2:
2272 ha->ad_type = IPS_ADTYPE_SERVERAID5I2;
2273 break;
2274
2275 case IPS_SUBDEVICEID_5I1:
2276 ha->ad_type = IPS_ADTYPE_SERVERAID5I1;
2277 break;
2278 }
2279
2280 break;
2281
2282 case IPS_DEVICEID_MARCO:
2283 switch (ha->pcidev->subsystem_device) {
2284 case IPS_SUBDEVICEID_6M:
2285 ha->ad_type = IPS_ADTYPE_SERVERAID6M;
2286 break;
2287 case IPS_SUBDEVICEID_6I:
2288 ha->ad_type = IPS_ADTYPE_SERVERAID6I;
2289 break;
2290 case IPS_SUBDEVICEID_7k:
2291 ha->ad_type = IPS_ADTYPE_SERVERAID7k;
2292 break;
2293 case IPS_SUBDEVICEID_7M:
2294 ha->ad_type = IPS_ADTYPE_SERVERAID7M;
2295 break;
2296 }
2297 break;
2298 }
2299}
2300
2301
2302
2303
2304
2305
2306
2307
2308
2309
2310static void
2311ips_get_bios_version(ips_ha_t * ha, int intr)
2312{
2313 ips_scb_t *scb;
2314 int ret;
2315 uint8_t major;
2316 uint8_t minor;
2317 uint8_t subminor;
2318 uint8_t *buffer;
2319 char hexDigits[] =
2320 { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C',
2321 'D', 'E', 'F' };
2322
2323 METHOD_TRACE("ips_get_bios_version", 1);
2324
2325 major = 0;
2326 minor = 0;
2327
2328 strncpy(ha->bios_version, " ?", 8);
2329
2330 if (ha->pcidev->device == IPS_DEVICEID_COPPERHEAD) {
2331 if (IPS_USE_MEMIO(ha)) {
2332
2333
2334
2335 writel(0, ha->mem_ptr + IPS_REG_FLAP);
2336 if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2337 udelay(25);
2338
2339 if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0x55)
2340 return;
2341
2342 writel(1, ha->mem_ptr + IPS_REG_FLAP);
2343 if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2344 udelay(25);
2345
2346 if (readb(ha->mem_ptr + IPS_REG_FLDP) != 0xAA)
2347 return;
2348
2349
2350 writel(0x1FF, ha->mem_ptr + IPS_REG_FLAP);
2351 if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2352 udelay(25);
2353
2354 major = readb(ha->mem_ptr + IPS_REG_FLDP);
2355
2356
2357 writel(0x1FE, ha->mem_ptr + IPS_REG_FLAP);
2358 if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2359 udelay(25);
2360 minor = readb(ha->mem_ptr + IPS_REG_FLDP);
2361
2362
2363 writel(0x1FD, ha->mem_ptr + IPS_REG_FLAP);
2364 if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2365 udelay(25);
2366 subminor = readb(ha->mem_ptr + IPS_REG_FLDP);
2367
2368 } else {
2369
2370
2371
2372 outl(0, ha->io_addr + IPS_REG_FLAP);
2373 if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2374 udelay(25);
2375
2376 if (inb(ha->io_addr + IPS_REG_FLDP) != 0x55)
2377 return;
2378
2379 outl(1, ha->io_addr + IPS_REG_FLAP);
2380 if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2381 udelay(25);
2382
2383 if (inb(ha->io_addr + IPS_REG_FLDP) != 0xAA)
2384 return;
2385
2386
2387 outl(0x1FF, ha->io_addr + IPS_REG_FLAP);
2388 if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2389 udelay(25);
2390
2391 major = inb(ha->io_addr + IPS_REG_FLDP);
2392
2393
2394 outl(0x1FE, ha->io_addr + IPS_REG_FLAP);
2395 if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2396 udelay(25);
2397
2398 minor = inb(ha->io_addr + IPS_REG_FLDP);
2399
2400
2401 outl(0x1FD, ha->io_addr + IPS_REG_FLAP);
2402 if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
2403 udelay(25);
2404
2405 subminor = inb(ha->io_addr + IPS_REG_FLDP);
2406
2407 }
2408 } else {
2409
2410
2411 buffer = ha->ioctl_data;
2412
2413 memset(buffer, 0, 0x1000);
2414
2415 scb = &ha->scbs[ha->max_cmds - 1];
2416
2417 ips_init_scb(ha, scb);
2418
2419 scb->timeout = ips_cmd_timeout;
2420 scb->cdb[0] = IPS_CMD_RW_BIOSFW;
2421
2422 scb->cmd.flashfw.op_code = IPS_CMD_RW_BIOSFW;
2423 scb->cmd.flashfw.command_id = IPS_COMMAND_ID(ha, scb);
2424 scb->cmd.flashfw.type = 1;
2425 scb->cmd.flashfw.direction = 0;
2426 scb->cmd.flashfw.count = cpu_to_le32(0x800);
2427 scb->cmd.flashfw.total_packets = 1;
2428 scb->cmd.flashfw.packet_num = 0;
2429 scb->data_len = 0x1000;
2430 scb->cmd.flashfw.buffer_addr = ha->ioctl_busaddr;
2431
2432
2433 if (((ret =
2434 ips_send_wait(ha, scb, ips_cmd_timeout,
2435 intr)) == IPS_FAILURE)
2436 || (ret == IPS_SUCCESS_IMM)
2437 || ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1)) {
2438
2439
2440 return;
2441 }
2442
2443 if ((buffer[0xC0] == 0x55) && (buffer[0xC1] == 0xAA)) {
2444 major = buffer[0x1ff + 0xC0];
2445 minor = buffer[0x1fe + 0xC0];
2446 subminor = buffer[0x1fd + 0xC0];
2447 } else {
2448 return;
2449 }
2450 }
2451
2452 ha->bios_version[0] = hexDigits[(major & 0xF0) >> 4];
2453 ha->bios_version[1] = '.';
2454 ha->bios_version[2] = hexDigits[major & 0x0F];
2455 ha->bios_version[3] = hexDigits[subminor];
2456 ha->bios_version[4] = '.';
2457 ha->bios_version[5] = hexDigits[(minor & 0xF0) >> 4];
2458 ha->bios_version[6] = hexDigits[minor & 0x0F];
2459 ha->bios_version[7] = 0;
2460}
2461
2462
2463
2464
2465
2466
2467
2468
2469
2470
2471
2472
2473static int
2474ips_hainit(ips_ha_t * ha)
2475{
2476 int i;
2477 struct timeval tv;
2478
2479 METHOD_TRACE("ips_hainit", 1);
2480
2481 if (!ha)
2482 return (0);
2483
2484 if (ha->func.statinit)
2485 (*ha->func.statinit) (ha);
2486
2487 if (ha->func.enableint)
2488 (*ha->func.enableint) (ha);
2489
2490
2491 ha->reset_count = 1;
2492 do_gettimeofday(&tv);
2493 ha->last_ffdc = tv.tv_sec;
2494 ips_ffdc_reset(ha, IPS_INTR_IORL);
2495
2496 if (!ips_read_config(ha, IPS_INTR_IORL)) {
2497 IPS_PRINTK(KERN_WARNING, ha->pcidev,
2498 "unable to read config from controller.\n");
2499
2500 return (0);
2501 }
2502
2503 if (!ips_read_adapter_status(ha, IPS_INTR_IORL)) {
2504 IPS_PRINTK(KERN_WARNING, ha->pcidev,
2505 "unable to read controller status.\n");
2506
2507 return (0);
2508 }
2509
2510
2511 ips_identify_controller(ha);
2512
2513 if (!ips_read_subsystem_parameters(ha, IPS_INTR_IORL)) {
2514 IPS_PRINTK(KERN_WARNING, ha->pcidev,
2515 "unable to read subsystem parameters.\n");
2516
2517 return (0);
2518 }
2519
2520
2521 if (!ips_write_driver_status(ha, IPS_INTR_IORL)) {
2522 IPS_PRINTK(KERN_WARNING, ha->pcidev,
2523 "unable to write driver info to controller.\n");
2524
2525 return (0);
2526 }
2527
2528
2529 if ((ha->conf->ucLogDriveCount > 0) && (ha->requires_esl == 1))
2530 ips_clear_adapter(ha, IPS_INTR_IORL);
2531
2532
2533 ha->ntargets = IPS_MAX_TARGETS + 1;
2534 ha->nlun = 1;
2535 ha->nbus = (ha->enq->ucMaxPhysicalDevices / IPS_MAX_TARGETS) + 1;
2536
2537 switch (ha->conf->logical_drive[0].ucStripeSize) {
2538 case 4:
2539 ha->max_xfer = 0x10000;
2540 break;
2541
2542 case 5:
2543 ha->max_xfer = 0x20000;
2544 break;
2545
2546 case 6:
2547 ha->max_xfer = 0x40000;
2548 break;
2549
2550 case 7:
2551 default:
2552 ha->max_xfer = 0x80000;
2553 break;
2554 }
2555
2556
2557 if (le32_to_cpu(ha->subsys->param[4]) & 0x1) {
2558
2559 ha->max_cmds = ha->enq->ucConcurrentCmdCount;
2560 } else {
2561
2562 switch (ha->conf->logical_drive[0].ucStripeSize) {
2563 case 4:
2564 ha->max_cmds = 32;
2565 break;
2566
2567 case 5:
2568 ha->max_cmds = 16;
2569 break;
2570
2571 case 6:
2572 ha->max_cmds = 8;
2573 break;
2574
2575 case 7:
2576 default:
2577 ha->max_cmds = 4;
2578 break;
2579 }
2580 }
2581
2582
2583 if ((ha->ad_type == IPS_ADTYPE_SERVERAID3L) ||
2584 (ha->ad_type == IPS_ADTYPE_SERVERAID4L) ||
2585 (ha->ad_type == IPS_ADTYPE_SERVERAID4LX)) {
2586 if ((ha->max_cmds > MaxLiteCmds) && (MaxLiteCmds))
2587 ha->max_cmds = MaxLiteCmds;
2588 }
2589
2590
2591 ha->ha_id[0] = IPS_ADAPTER_ID;
2592 for (i = 1; i < ha->nbus; i++) {
2593 ha->ha_id[i] = ha->conf->init_id[i - 1] & 0x1f;
2594 ha->dcdb_active[i - 1] = 0;
2595 }
2596
2597 return (1);
2598}
2599
2600
2601
2602
2603
2604
2605
2606
2607
2608
2609static void
2610ips_next(ips_ha_t * ha, int intr)
2611{
2612 ips_scb_t *scb;
2613 struct scsi_cmnd *SC;
2614 struct scsi_cmnd *p;
2615 struct scsi_cmnd *q;
2616 ips_copp_wait_item_t *item;
2617 int ret;
2618 struct Scsi_Host *host;
2619 METHOD_TRACE("ips_next", 1);
2620
2621 if (!ha)
2622 return;
2623 host = ips_sh[ha->host_num];
2624
2625
2626
2627
2628 if (intr == IPS_INTR_ON)
2629 spin_lock(host->host_lock);
2630
2631 if ((ha->subsys->param[3] & 0x300000)
2632 && (ha->scb_activelist.count == 0)) {
2633 struct timeval tv;
2634
2635 do_gettimeofday(&tv);
2636
2637 if (tv.tv_sec - ha->last_ffdc > IPS_SECS_8HOURS) {
2638 ha->last_ffdc = tv.tv_sec;
2639 ips_ffdc_time(ha);
2640 }
2641 }
2642
2643
2644
2645
2646
2647
2648
2649
2650 while ((ha->num_ioctl < IPS_MAX_IOCTL) &&
2651 (ha->copp_waitlist.head) && (scb = ips_getscb(ha))) {
2652
2653 item = ips_removeq_copp_head(&ha->copp_waitlist);
2654 ha->num_ioctl++;
2655 if (intr == IPS_INTR_ON)
2656 spin_unlock(host->host_lock);
2657 scb->scsi_cmd = item->scsi_cmd;
2658 kfree(item);
2659
2660 ret = ips_make_passthru(ha, scb->scsi_cmd, scb, intr);
2661
2662 if (intr == IPS_INTR_ON)
2663 spin_lock(host->host_lock);
2664 switch (ret) {
2665 case IPS_FAILURE:
2666 if (scb->scsi_cmd) {
2667 scb->scsi_cmd->result = DID_ERROR << 16;
2668 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2669 }
2670
2671 ips_freescb(ha, scb);
2672 break;
2673 case IPS_SUCCESS_IMM:
2674 if (scb->scsi_cmd) {
2675 scb->scsi_cmd->result = DID_OK << 16;
2676 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2677 }
2678
2679 ips_freescb(ha, scb);
2680 break;
2681 default:
2682 break;
2683 }
2684
2685 if (ret != IPS_SUCCESS) {
2686 ha->num_ioctl--;
2687 continue;
2688 }
2689
2690 ret = ips_send_cmd(ha, scb);
2691
2692 if (ret == IPS_SUCCESS)
2693 ips_putq_scb_head(&ha->scb_activelist, scb);
2694 else
2695 ha->num_ioctl--;
2696
2697 switch (ret) {
2698 case IPS_FAILURE:
2699 if (scb->scsi_cmd) {
2700 scb->scsi_cmd->result = DID_ERROR << 16;
2701 }
2702
2703 ips_freescb(ha, scb);
2704 break;
2705 case IPS_SUCCESS_IMM:
2706 ips_freescb(ha, scb);
2707 break;
2708 default:
2709 break;
2710 }
2711
2712 }
2713
2714
2715
2716
2717
2718 p = ha->scb_waitlist.head;
2719 while ((p) && (scb = ips_getscb(ha))) {
2720 if ((scmd_channel(p) > 0)
2721 && (ha->
2722 dcdb_active[scmd_channel(p) -
2723 1] & (1 << scmd_id(p)))) {
2724 ips_freescb(ha, scb);
2725 p = (struct scsi_cmnd *) p->host_scribble;
2726 continue;
2727 }
2728
2729 q = p;
2730 SC = ips_removeq_wait(&ha->scb_waitlist, q);
2731
2732 if (intr == IPS_INTR_ON)
2733 spin_unlock(host->host_lock);
2734
2735 SC->result = DID_OK;
2736 SC->host_scribble = NULL;
2737
2738 scb->target_id = SC->device->id;
2739 scb->lun = SC->device->lun;
2740 scb->bus = SC->device->channel;
2741 scb->scsi_cmd = SC;
2742 scb->breakup = 0;
2743 scb->data_len = 0;
2744 scb->callback = ipsintr_done;
2745 scb->timeout = ips_cmd_timeout;
2746 memset(&scb->cmd, 0, 16);
2747
2748
2749 memcpy(scb->cdb, SC->cmnd, SC->cmd_len);
2750
2751 scb->sg_count = scsi_dma_map(SC);
2752 BUG_ON(scb->sg_count < 0);
2753 if (scb->sg_count) {
2754 struct scatterlist *sg;
2755 int i;
2756
2757 scb->flags |= IPS_SCB_MAP_SG;
2758
2759 scsi_for_each_sg(SC, sg, scb->sg_count, i) {
2760 if (ips_fill_scb_sg_single
2761 (ha, sg_dma_address(sg), scb, i,
2762 sg_dma_len(sg)) < 0)
2763 break;
2764 }
2765 scb->dcdb.transfer_length = scb->data_len;
2766 } else {
2767 scb->data_busaddr = 0L;
2768 scb->sg_len = 0;
2769 scb->data_len = 0;
2770 scb->dcdb.transfer_length = 0;
2771 }
2772
2773 scb->dcdb.cmd_attribute =
2774 ips_command_direction[scb->scsi_cmd->cmnd[0]];
2775
2776
2777
2778 if ((scb->scsi_cmd->cmnd[0] == WRITE_BUFFER) &&
2779 (scb->data_len == 0))
2780 scb->dcdb.cmd_attribute = 0;
2781
2782 if (!(scb->dcdb.cmd_attribute & 0x3))
2783 scb->dcdb.transfer_length = 0;
2784
2785 if (scb->data_len >= IPS_MAX_XFER) {
2786 scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
2787 scb->dcdb.transfer_length = 0;
2788 }
2789 if (intr == IPS_INTR_ON)
2790 spin_lock(host->host_lock);
2791
2792 ret = ips_send_cmd(ha, scb);
2793
2794 switch (ret) {
2795 case IPS_SUCCESS:
2796 ips_putq_scb_head(&ha->scb_activelist, scb);
2797 break;
2798 case IPS_FAILURE:
2799 if (scb->scsi_cmd) {
2800 scb->scsi_cmd->result = DID_ERROR << 16;
2801 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2802 }
2803
2804 if (scb->bus)
2805 ha->dcdb_active[scb->bus - 1] &=
2806 ~(1 << scb->target_id);
2807
2808 ips_freescb(ha, scb);
2809 break;
2810 case IPS_SUCCESS_IMM:
2811 if (scb->scsi_cmd)
2812 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
2813
2814 if (scb->bus)
2815 ha->dcdb_active[scb->bus - 1] &=
2816 ~(1 << scb->target_id);
2817
2818 ips_freescb(ha, scb);
2819 break;
2820 default:
2821 break;
2822 }
2823
2824 p = (struct scsi_cmnd *) p->host_scribble;
2825
2826 }
2827
2828 if (intr == IPS_INTR_ON)
2829 spin_unlock(host->host_lock);
2830}
2831
2832
2833
2834
2835
2836
2837
2838
2839
2840
2841
2842
2843static void
2844ips_putq_scb_head(ips_scb_queue_t * queue, ips_scb_t * item)
2845{
2846 METHOD_TRACE("ips_putq_scb_head", 1);
2847
2848 if (!item)
2849 return;
2850
2851 item->q_next = queue->head;
2852 queue->head = item;
2853
2854 if (!queue->tail)
2855 queue->tail = item;
2856
2857 queue->count++;
2858}
2859
2860
2861
2862
2863
2864
2865
2866
2867
2868
2869
2870
2871static ips_scb_t *
2872ips_removeq_scb_head(ips_scb_queue_t * queue)
2873{
2874 ips_scb_t *item;
2875
2876 METHOD_TRACE("ips_removeq_scb_head", 1);
2877
2878 item = queue->head;
2879
2880 if (!item) {
2881 return (NULL);
2882 }
2883
2884 queue->head = item->q_next;
2885 item->q_next = NULL;
2886
2887 if (queue->tail == item)
2888 queue->tail = NULL;
2889
2890 queue->count--;
2891
2892 return (item);
2893}
2894
2895
2896
2897
2898
2899
2900
2901
2902
2903
2904
2905
2906static ips_scb_t *
2907ips_removeq_scb(ips_scb_queue_t * queue, ips_scb_t * item)
2908{
2909 ips_scb_t *p;
2910
2911 METHOD_TRACE("ips_removeq_scb", 1);
2912
2913 if (!item)
2914 return (NULL);
2915
2916 if (item == queue->head) {
2917 return (ips_removeq_scb_head(queue));
2918 }
2919
2920 p = queue->head;
2921
2922 while ((p) && (item != p->q_next))
2923 p = p->q_next;
2924
2925 if (p) {
2926
2927 p->q_next = item->q_next;
2928
2929 if (!item->q_next)
2930 queue->tail = p;
2931
2932 item->q_next = NULL;
2933 queue->count--;
2934
2935 return (item);
2936 }
2937
2938 return (NULL);
2939}
2940
2941
2942
2943
2944
2945
2946
2947
2948
2949
2950
2951
2952static void ips_putq_wait_tail(ips_wait_queue_t *queue, struct scsi_cmnd *item)
2953{
2954 METHOD_TRACE("ips_putq_wait_tail", 1);
2955
2956 if (!item)
2957 return;
2958
2959 item->host_scribble = NULL;
2960
2961 if (queue->tail)
2962 queue->tail->host_scribble = (char *) item;
2963
2964 queue->tail = item;
2965
2966 if (!queue->head)
2967 queue->head = item;
2968
2969 queue->count++;
2970}
2971
2972
2973
2974
2975
2976
2977
2978
2979
2980
2981
2982
2983static struct scsi_cmnd *ips_removeq_wait_head(ips_wait_queue_t *queue)
2984{
2985 struct scsi_cmnd *item;
2986
2987 METHOD_TRACE("ips_removeq_wait_head", 1);
2988
2989 item = queue->head;
2990
2991 if (!item) {
2992 return (NULL);
2993 }
2994
2995 queue->head = (struct scsi_cmnd *) item->host_scribble;
2996 item->host_scribble = NULL;
2997
2998 if (queue->tail == item)
2999 queue->tail = NULL;
3000
3001 queue->count--;
3002
3003 return (item);
3004}
3005
3006
3007
3008
3009
3010
3011
3012
3013
3014
3015
3016
3017static struct scsi_cmnd *ips_removeq_wait(ips_wait_queue_t *queue,
3018 struct scsi_cmnd *item)
3019{
3020 struct scsi_cmnd *p;
3021
3022 METHOD_TRACE("ips_removeq_wait", 1);
3023
3024 if (!item)
3025 return (NULL);
3026
3027 if (item == queue->head) {
3028 return (ips_removeq_wait_head(queue));
3029 }
3030
3031 p = queue->head;
3032
3033 while ((p) && (item != (struct scsi_cmnd *) p->host_scribble))
3034 p = (struct scsi_cmnd *) p->host_scribble;
3035
3036 if (p) {
3037
3038 p->host_scribble = item->host_scribble;
3039
3040 if (!item->host_scribble)
3041 queue->tail = p;
3042
3043 item->host_scribble = NULL;
3044 queue->count--;
3045
3046 return (item);
3047 }
3048
3049 return (NULL);
3050}
3051
3052
3053
3054
3055
3056
3057
3058
3059
3060
3061
3062
3063static void
3064ips_putq_copp_tail(ips_copp_queue_t * queue, ips_copp_wait_item_t * item)
3065{
3066 METHOD_TRACE("ips_putq_copp_tail", 1);
3067
3068 if (!item)
3069 return;
3070
3071 item->next = NULL;
3072
3073 if (queue->tail)
3074 queue->tail->next = item;
3075
3076 queue->tail = item;
3077
3078 if (!queue->head)
3079 queue->head = item;
3080
3081 queue->count++;
3082}
3083
3084
3085
3086
3087
3088
3089
3090
3091
3092
3093
3094
3095static ips_copp_wait_item_t *
3096ips_removeq_copp_head(ips_copp_queue_t * queue)
3097{
3098 ips_copp_wait_item_t *item;
3099
3100 METHOD_TRACE("ips_removeq_copp_head", 1);
3101
3102 item = queue->head;
3103
3104 if (!item) {
3105 return (NULL);
3106 }
3107
3108 queue->head = item->next;
3109 item->next = NULL;
3110
3111 if (queue->tail == item)
3112 queue->tail = NULL;
3113
3114 queue->count--;
3115
3116 return (item);
3117}
3118
3119
3120
3121
3122
3123
3124
3125
3126
3127
3128
3129
3130static ips_copp_wait_item_t *
3131ips_removeq_copp(ips_copp_queue_t * queue, ips_copp_wait_item_t * item)
3132{
3133 ips_copp_wait_item_t *p;
3134
3135 METHOD_TRACE("ips_removeq_copp", 1);
3136
3137 if (!item)
3138 return (NULL);
3139
3140 if (item == queue->head) {
3141 return (ips_removeq_copp_head(queue));
3142 }
3143
3144 p = queue->head;
3145
3146 while ((p) && (item != p->next))
3147 p = p->next;
3148
3149 if (p) {
3150
3151 p->next = item->next;
3152
3153 if (!item->next)
3154 queue->tail = p;
3155
3156 item->next = NULL;
3157 queue->count--;
3158
3159 return (item);
3160 }
3161
3162 return (NULL);
3163}
3164
3165
3166
3167
3168
3169
3170
3171
3172
3173
3174static void
3175ipsintr_blocking(ips_ha_t * ha, ips_scb_t * scb)
3176{
3177 METHOD_TRACE("ipsintr_blocking", 2);
3178
3179 ips_freescb(ha, scb);
3180 if ((ha->waitflag == TRUE) && (ha->cmd_in_progress == scb->cdb[0])) {
3181 ha->waitflag = FALSE;
3182
3183 return;
3184 }
3185}
3186
3187
3188
3189
3190
3191
3192
3193
3194
3195
3196static void
3197ipsintr_done(ips_ha_t * ha, ips_scb_t * scb)
3198{
3199 METHOD_TRACE("ipsintr_done", 2);
3200
3201 if (!scb) {
3202 IPS_PRINTK(KERN_WARNING, ha->pcidev,
3203 "Spurious interrupt; scb NULL.\n");
3204
3205 return;
3206 }
3207
3208 if (scb->scsi_cmd == NULL) {
3209
3210 IPS_PRINTK(KERN_WARNING, ha->pcidev,
3211 "Spurious interrupt; scsi_cmd not set.\n");
3212
3213 return;
3214 }
3215
3216 ips_done(ha, scb);
3217}
3218
3219
3220
3221
3222
3223
3224
3225
3226
3227
3228static void
3229ips_done(ips_ha_t * ha, ips_scb_t * scb)
3230{
3231 int ret;
3232
3233 METHOD_TRACE("ips_done", 1);
3234
3235 if (!scb)
3236 return;
3237
3238 if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd))) {
3239 ips_cleanup_passthru(ha, scb);
3240 ha->num_ioctl--;
3241 } else {
3242
3243
3244
3245
3246
3247 if ((scb->breakup) || (scb->sg_break)) {
3248 struct scatterlist *sg;
3249 int i, sg_dma_index, ips_sg_index = 0;
3250
3251
3252 scb->data_len = 0;
3253
3254 sg = scsi_sglist(scb->scsi_cmd);
3255
3256
3257 sg_dma_index = scb->breakup;
3258 for (i = 0; i < scb->breakup; i++)
3259 sg = sg_next(sg);
3260
3261
3262 ips_fill_scb_sg_single(ha,
3263 sg_dma_address(sg),
3264 scb, ips_sg_index++,
3265 sg_dma_len(sg));
3266
3267 for (; sg_dma_index < scsi_sg_count(scb->scsi_cmd);
3268 sg_dma_index++, sg = sg_next(sg)) {
3269 if (ips_fill_scb_sg_single
3270 (ha,
3271 sg_dma_address(sg),
3272 scb, ips_sg_index++,
3273 sg_dma_len(sg)) < 0)
3274 break;
3275 }
3276
3277 scb->dcdb.transfer_length = scb->data_len;
3278 scb->dcdb.cmd_attribute |=
3279 ips_command_direction[scb->scsi_cmd->cmnd[0]];
3280
3281 if (!(scb->dcdb.cmd_attribute & 0x3))
3282 scb->dcdb.transfer_length = 0;
3283
3284 if (scb->data_len >= IPS_MAX_XFER) {
3285 scb->dcdb.cmd_attribute |= IPS_TRANSFER64K;
3286 scb->dcdb.transfer_length = 0;
3287 }
3288
3289 ret = ips_send_cmd(ha, scb);
3290
3291 switch (ret) {
3292 case IPS_FAILURE:
3293 if (scb->scsi_cmd) {
3294 scb->scsi_cmd->result = DID_ERROR << 16;
3295 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3296 }
3297
3298 ips_freescb(ha, scb);
3299 break;
3300 case IPS_SUCCESS_IMM:
3301 if (scb->scsi_cmd) {
3302 scb->scsi_cmd->result = DID_ERROR << 16;
3303 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3304 }
3305
3306 ips_freescb(ha, scb);
3307 break;
3308 default:
3309 break;
3310 }
3311
3312 return;
3313 }
3314 }
3315
3316 if (scb->bus) {
3317 ha->dcdb_active[scb->bus - 1] &= ~(1 << scb->target_id);
3318 }
3319
3320 scb->scsi_cmd->scsi_done(scb->scsi_cmd);
3321
3322 ips_freescb(ha, scb);
3323}
3324
3325
3326
3327
3328
3329
3330
3331
3332
3333
3334static int
3335ips_map_status(ips_ha_t * ha, ips_scb_t * scb, ips_stat_t * sp)
3336{
3337 int errcode;
3338 int device_error;
3339 uint32_t transfer_len;
3340 IPS_DCDB_TABLE_TAPE *tapeDCDB;
3341 IPS_SCSI_INQ_DATA inquiryData;
3342
3343 METHOD_TRACE("ips_map_status", 1);
3344
3345 if (scb->bus) {
3346 DEBUG_VAR(2,
3347 "(%s%d) Physical device error (%d %d %d): %x %x, Sense Key: %x, ASC: %x, ASCQ: %x",
3348 ips_name, ha->host_num,
3349 scb->scsi_cmd->device->channel,
3350 scb->scsi_cmd->device->id, scb->scsi_cmd->device->lun,
3351 scb->basic_status, scb->extended_status,
3352 scb->extended_status ==
3353 IPS_ERR_CKCOND ? scb->dcdb.sense_info[2] & 0xf : 0,
3354 scb->extended_status ==
3355 IPS_ERR_CKCOND ? scb->dcdb.sense_info[12] : 0,
3356 scb->extended_status ==
3357 IPS_ERR_CKCOND ? scb->dcdb.sense_info[13] : 0);
3358 }
3359
3360
3361 errcode = DID_ERROR;
3362 device_error = 0;
3363
3364 switch (scb->basic_status & IPS_GSC_STATUS_MASK) {
3365 case IPS_CMD_TIMEOUT:
3366 errcode = DID_TIME_OUT;
3367 break;
3368
3369 case IPS_INVAL_OPCO:
3370 case IPS_INVAL_CMD_BLK:
3371 case IPS_INVAL_PARM_BLK:
3372 case IPS_LD_ERROR:
3373 case IPS_CMD_CMPLT_WERROR:
3374 break;
3375
3376 case IPS_PHYS_DRV_ERROR:
3377 switch (scb->extended_status) {
3378 case IPS_ERR_SEL_TO:
3379 if (scb->bus)
3380 errcode = DID_NO_CONNECT;
3381
3382 break;
3383
3384 case IPS_ERR_OU_RUN:
3385 if ((scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB) ||
3386 (scb->cmd.dcdb.op_code ==
3387 IPS_CMD_EXTENDED_DCDB_SG)) {
3388 tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
3389 transfer_len = tapeDCDB->transfer_length;
3390 } else {
3391 transfer_len =
3392 (uint32_t) scb->dcdb.transfer_length;
3393 }
3394
3395 if ((scb->bus) && (transfer_len < scb->data_len)) {
3396
3397 errcode = DID_OK;
3398
3399
3400 if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
3401 ips_scmd_buf_read(scb->scsi_cmd,
3402 &inquiryData, sizeof (inquiryData));
3403 if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK) {
3404 errcode = DID_TIME_OUT;
3405 break;
3406 }
3407 }
3408 } else
3409 errcode = DID_ERROR;
3410
3411 break;
3412
3413 case IPS_ERR_RECOVERY:
3414
3415 if (scb->bus)
3416 errcode = DID_OK;
3417
3418 break;
3419
3420 case IPS_ERR_HOST_RESET:
3421 case IPS_ERR_DEV_RESET:
3422 errcode = DID_RESET;
3423 break;
3424
3425 case IPS_ERR_CKCOND:
3426 if (scb->bus) {
3427 if ((scb->cmd.dcdb.op_code ==
3428 IPS_CMD_EXTENDED_DCDB)
3429 || (scb->cmd.dcdb.op_code ==
3430 IPS_CMD_EXTENDED_DCDB_SG)) {
3431 tapeDCDB =
3432 (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
3433 memcpy(scb->scsi_cmd->sense_buffer,
3434 tapeDCDB->sense_info,
3435 SCSI_SENSE_BUFFERSIZE);
3436 } else {
3437 memcpy(scb->scsi_cmd->sense_buffer,
3438 scb->dcdb.sense_info,
3439 SCSI_SENSE_BUFFERSIZE);
3440 }
3441 device_error = 2;
3442 }
3443
3444 errcode = DID_OK;
3445
3446 break;
3447
3448 default:
3449 errcode = DID_ERROR;
3450 break;
3451
3452 }
3453 }
3454
3455 scb->scsi_cmd->result = device_error | (errcode << 16);
3456
3457 return (1);
3458}
3459
3460
3461
3462
3463
3464
3465
3466
3467
3468
3469
3470
3471static int
3472ips_send_wait(ips_ha_t * ha, ips_scb_t * scb, int timeout, int intr)
3473{
3474 int ret;
3475
3476 METHOD_TRACE("ips_send_wait", 1);
3477
3478 if (intr != IPS_FFDC) {
3479 ha->waitflag = TRUE;
3480 ha->cmd_in_progress = scb->cdb[0];
3481 }
3482 scb->callback = ipsintr_blocking;
3483 ret = ips_send_cmd(ha, scb);
3484
3485 if ((ret == IPS_FAILURE) || (ret == IPS_SUCCESS_IMM))
3486 return (ret);
3487
3488 if (intr != IPS_FFDC)
3489 ret = ips_wait(ha, timeout, intr);
3490
3491 return (ret);
3492}
3493
3494
3495
3496
3497
3498
3499
3500
3501static void
3502ips_scmd_buf_write(struct scsi_cmnd *scmd, void *data, unsigned int count)
3503{
3504 unsigned long flags;
3505
3506 local_irq_save(flags);
3507 scsi_sg_copy_from_buffer(scmd, data, count);
3508 local_irq_restore(flags);
3509}
3510
3511
3512
3513
3514
3515
3516
3517
3518static void
3519ips_scmd_buf_read(struct scsi_cmnd *scmd, void *data, unsigned int count)
3520{
3521 unsigned long flags;
3522
3523 local_irq_save(flags);
3524 scsi_sg_copy_to_buffer(scmd, data, count);
3525 local_irq_restore(flags);
3526}
3527
3528
3529
3530
3531
3532
3533
3534
3535
3536
3537static int
3538ips_send_cmd(ips_ha_t * ha, ips_scb_t * scb)
3539{
3540 int ret;
3541 char *sp;
3542 int device_error;
3543 IPS_DCDB_TABLE_TAPE *tapeDCDB;
3544 int TimeOut;
3545
3546 METHOD_TRACE("ips_send_cmd", 1);
3547
3548 ret = IPS_SUCCESS;
3549
3550 if (!scb->scsi_cmd) {
3551
3552
3553 if (scb->bus > 0) {
3554
3555
3556 if ((ha->waitflag == TRUE) &&
3557 (ha->cmd_in_progress == scb->cdb[0])) {
3558 ha->waitflag = FALSE;
3559 }
3560
3561 return (1);
3562 }
3563 } else if ((scb->bus == 0) && (!ips_is_passthru(scb->scsi_cmd))) {
3564
3565 ret = IPS_SUCCESS_IMM;
3566
3567 switch (scb->scsi_cmd->cmnd[0]) {
3568 case ALLOW_MEDIUM_REMOVAL:
3569 case REZERO_UNIT:
3570 case ERASE:
3571 case WRITE_FILEMARKS:
3572 case SPACE:
3573 scb->scsi_cmd->result = DID_ERROR << 16;
3574 break;
3575
3576 case START_STOP:
3577 scb->scsi_cmd->result = DID_OK << 16;
3578
3579 case TEST_UNIT_READY:
3580 case INQUIRY:
3581 if (scb->target_id == IPS_ADAPTER_ID) {
3582
3583
3584
3585
3586 if (scb->scsi_cmd->cmnd[0] == TEST_UNIT_READY)
3587 scb->scsi_cmd->result = DID_OK << 16;
3588
3589 if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
3590 IPS_SCSI_INQ_DATA inquiry;
3591
3592 memset(&inquiry, 0,
3593 sizeof (IPS_SCSI_INQ_DATA));
3594
3595 inquiry.DeviceType =
3596 IPS_SCSI_INQ_TYPE_PROCESSOR;
3597 inquiry.DeviceTypeQualifier =
3598 IPS_SCSI_INQ_LU_CONNECTED;
3599 inquiry.Version = IPS_SCSI_INQ_REV2;
3600 inquiry.ResponseDataFormat =
3601 IPS_SCSI_INQ_RD_REV2;
3602 inquiry.AdditionalLength = 31;
3603 inquiry.Flags[0] =
3604 IPS_SCSI_INQ_Address16;
3605 inquiry.Flags[1] =
3606 IPS_SCSI_INQ_WBus16 |
3607 IPS_SCSI_INQ_Sync;
3608 strncpy(inquiry.VendorId, "IBM ",
3609 8);
3610 strncpy(inquiry.ProductId,
3611 "SERVERAID ", 16);
3612 strncpy(inquiry.ProductRevisionLevel,
3613 "1.00", 4);
3614
3615 ips_scmd_buf_write(scb->scsi_cmd,
3616 &inquiry,
3617 sizeof (inquiry));
3618
3619 scb->scsi_cmd->result = DID_OK << 16;
3620 }
3621 } else {
3622 scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
3623 scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
3624 scb->cmd.logical_info.reserved = 0;
3625 scb->cmd.logical_info.reserved2 = 0;
3626 scb->data_len = sizeof (IPS_LD_INFO);
3627 scb->data_busaddr = ha->logical_drive_info_dma_addr;
3628 scb->flags = 0;
3629 scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
3630 ret = IPS_SUCCESS;
3631 }
3632
3633 break;
3634
3635 case REQUEST_SENSE:
3636 ips_reqsen(ha, scb);
3637 scb->scsi_cmd->result = DID_OK << 16;
3638 break;
3639
3640 case READ_6:
3641 case WRITE_6:
3642 if (!scb->sg_len) {
3643 scb->cmd.basic_io.op_code =
3644 (scb->scsi_cmd->cmnd[0] ==
3645 READ_6) ? IPS_CMD_READ : IPS_CMD_WRITE;
3646 scb->cmd.basic_io.enhanced_sg = 0;
3647 scb->cmd.basic_io.sg_addr =
3648 cpu_to_le32(scb->data_busaddr);
3649 } else {
3650 scb->cmd.basic_io.op_code =
3651 (scb->scsi_cmd->cmnd[0] ==
3652 READ_6) ? IPS_CMD_READ_SG :
3653 IPS_CMD_WRITE_SG;
3654 scb->cmd.basic_io.enhanced_sg =
3655 IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3656 scb->cmd.basic_io.sg_addr =
3657 cpu_to_le32(scb->sg_busaddr);
3658 }
3659
3660 scb->cmd.basic_io.segment_4G = 0;
3661 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3662 scb->cmd.basic_io.log_drv = scb->target_id;
3663 scb->cmd.basic_io.sg_count = scb->sg_len;
3664
3665 if (scb->cmd.basic_io.lba)
3666 le32_add_cpu(&scb->cmd.basic_io.lba,
3667 le16_to_cpu(scb->cmd.basic_io.
3668 sector_count));
3669 else
3670 scb->cmd.basic_io.lba =
3671 (((scb->scsi_cmd->
3672 cmnd[1] & 0x1f) << 16) | (scb->scsi_cmd->
3673 cmnd[2] << 8) |
3674 (scb->scsi_cmd->cmnd[3]));
3675
3676 scb->cmd.basic_io.sector_count =
3677 cpu_to_le16(scb->data_len / IPS_BLKSIZE);
3678
3679 if (le16_to_cpu(scb->cmd.basic_io.sector_count) == 0)
3680 scb->cmd.basic_io.sector_count =
3681 cpu_to_le16(256);
3682
3683 ret = IPS_SUCCESS;
3684 break;
3685
3686 case READ_10:
3687 case WRITE_10:
3688 if (!scb->sg_len) {
3689 scb->cmd.basic_io.op_code =
3690 (scb->scsi_cmd->cmnd[0] ==
3691 READ_10) ? IPS_CMD_READ : IPS_CMD_WRITE;
3692 scb->cmd.basic_io.enhanced_sg = 0;
3693 scb->cmd.basic_io.sg_addr =
3694 cpu_to_le32(scb->data_busaddr);
3695 } else {
3696 scb->cmd.basic_io.op_code =
3697 (scb->scsi_cmd->cmnd[0] ==
3698 READ_10) ? IPS_CMD_READ_SG :
3699 IPS_CMD_WRITE_SG;
3700 scb->cmd.basic_io.enhanced_sg =
3701 IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3702 scb->cmd.basic_io.sg_addr =
3703 cpu_to_le32(scb->sg_busaddr);
3704 }
3705
3706 scb->cmd.basic_io.segment_4G = 0;
3707 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3708 scb->cmd.basic_io.log_drv = scb->target_id;
3709 scb->cmd.basic_io.sg_count = scb->sg_len;
3710
3711 if (scb->cmd.basic_io.lba)
3712 le32_add_cpu(&scb->cmd.basic_io.lba,
3713 le16_to_cpu(scb->cmd.basic_io.
3714 sector_count));
3715 else
3716 scb->cmd.basic_io.lba =
3717 ((scb->scsi_cmd->cmnd[2] << 24) | (scb->
3718 scsi_cmd->
3719 cmnd[3]
3720 << 16) |
3721 (scb->scsi_cmd->cmnd[4] << 8) | scb->
3722 scsi_cmd->cmnd[5]);
3723
3724 scb->cmd.basic_io.sector_count =
3725 cpu_to_le16(scb->data_len / IPS_BLKSIZE);
3726
3727 if (cpu_to_le16(scb->cmd.basic_io.sector_count) == 0) {
3728
3729
3730
3731
3732
3733 scb->scsi_cmd->result = DID_OK << 16;
3734 } else
3735 ret = IPS_SUCCESS;
3736
3737 break;
3738
3739 case RESERVE:
3740 case RELEASE:
3741 scb->scsi_cmd->result = DID_OK << 16;
3742 break;
3743
3744 case MODE_SENSE:
3745 scb->cmd.basic_io.op_code = IPS_CMD_ENQUIRY;
3746 scb->cmd.basic_io.command_id = IPS_COMMAND_ID(ha, scb);
3747 scb->cmd.basic_io.segment_4G = 0;
3748 scb->cmd.basic_io.enhanced_sg = 0;
3749 scb->data_len = sizeof (*ha->enq);
3750 scb->cmd.basic_io.sg_addr = ha->enq_busaddr;
3751 ret = IPS_SUCCESS;
3752 break;
3753
3754 case READ_CAPACITY:
3755 scb->cmd.logical_info.op_code = IPS_CMD_GET_LD_INFO;
3756 scb->cmd.logical_info.command_id = IPS_COMMAND_ID(ha, scb);
3757 scb->cmd.logical_info.reserved = 0;
3758 scb->cmd.logical_info.reserved2 = 0;
3759 scb->cmd.logical_info.reserved3 = 0;
3760 scb->data_len = sizeof (IPS_LD_INFO);
3761 scb->data_busaddr = ha->logical_drive_info_dma_addr;
3762 scb->flags = 0;
3763 scb->cmd.logical_info.buffer_addr = scb->data_busaddr;
3764 ret = IPS_SUCCESS;
3765 break;
3766
3767 case SEND_DIAGNOSTIC:
3768 case REASSIGN_BLOCKS:
3769 case FORMAT_UNIT:
3770 case SEEK_10:
3771 case VERIFY:
3772 case READ_DEFECT_DATA:
3773 case READ_BUFFER:
3774 case WRITE_BUFFER:
3775 scb->scsi_cmd->result = DID_OK << 16;
3776 break;
3777
3778 default:
3779
3780
3781
3782 sp = (char *) scb->scsi_cmd->sense_buffer;
3783
3784 sp[0] = 0x70;
3785 sp[2] = ILLEGAL_REQUEST;
3786 sp[7] = 0x0A;
3787 sp[12] = 0x20;
3788 sp[13] = 0x00;
3789
3790 device_error = 2;
3791 scb->scsi_cmd->result = device_error | (DID_OK << 16);
3792 break;
3793 }
3794 }
3795
3796 if (ret == IPS_SUCCESS_IMM)
3797 return (ret);
3798
3799
3800 if (scb->bus > 0) {
3801
3802
3803
3804 if (ha->conf->dev[scb->bus - 1][scb->target_id].ucState == 0) {
3805 scb->scsi_cmd->result = DID_NO_CONNECT << 16;
3806 return (IPS_SUCCESS_IMM);
3807 }
3808
3809 ha->dcdb_active[scb->bus - 1] |= (1 << scb->target_id);
3810 scb->cmd.dcdb.command_id = IPS_COMMAND_ID(ha, scb);
3811 scb->cmd.dcdb.dcdb_address = cpu_to_le32(scb->scb_busaddr +
3812 (unsigned long) &scb->
3813 dcdb -
3814 (unsigned long) scb);
3815 scb->cmd.dcdb.reserved = 0;
3816 scb->cmd.dcdb.reserved2 = 0;
3817 scb->cmd.dcdb.reserved3 = 0;
3818 scb->cmd.dcdb.segment_4G = 0;
3819 scb->cmd.dcdb.enhanced_sg = 0;
3820
3821 TimeOut = scb->scsi_cmd->request->timeout;
3822
3823 if (ha->subsys->param[4] & 0x00100000) {
3824 if (!scb->sg_len) {
3825 scb->cmd.dcdb.op_code = IPS_CMD_EXTENDED_DCDB;
3826 } else {
3827 scb->cmd.dcdb.op_code =
3828 IPS_CMD_EXTENDED_DCDB_SG;
3829 scb->cmd.dcdb.enhanced_sg =
3830 IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3831 }
3832
3833 tapeDCDB = (IPS_DCDB_TABLE_TAPE *) & scb->dcdb;
3834 tapeDCDB->device_address =
3835 ((scb->bus - 1) << 4) | scb->target_id;
3836 tapeDCDB->cmd_attribute |= IPS_DISCONNECT_ALLOWED;
3837 tapeDCDB->cmd_attribute &= ~IPS_TRANSFER64K;
3838
3839 if (TimeOut) {
3840 if (TimeOut < (10 * HZ))
3841 tapeDCDB->cmd_attribute |= IPS_TIMEOUT10;
3842 else if (TimeOut < (60 * HZ))
3843 tapeDCDB->cmd_attribute |= IPS_TIMEOUT60;
3844 else if (TimeOut < (1200 * HZ))
3845 tapeDCDB->cmd_attribute |= IPS_TIMEOUT20M;
3846 }
3847
3848 tapeDCDB->cdb_length = scb->scsi_cmd->cmd_len;
3849 tapeDCDB->reserved_for_LUN = 0;
3850 tapeDCDB->transfer_length = scb->data_len;
3851 if (scb->cmd.dcdb.op_code == IPS_CMD_EXTENDED_DCDB_SG)
3852 tapeDCDB->buffer_pointer =
3853 cpu_to_le32(scb->sg_busaddr);
3854 else
3855 tapeDCDB->buffer_pointer =
3856 cpu_to_le32(scb->data_busaddr);
3857 tapeDCDB->sg_count = scb->sg_len;
3858 tapeDCDB->sense_length = sizeof (tapeDCDB->sense_info);
3859 tapeDCDB->scsi_status = 0;
3860 tapeDCDB->reserved = 0;
3861 memcpy(tapeDCDB->scsi_cdb, scb->scsi_cmd->cmnd,
3862 scb->scsi_cmd->cmd_len);
3863 } else {
3864 if (!scb->sg_len) {
3865 scb->cmd.dcdb.op_code = IPS_CMD_DCDB;
3866 } else {
3867 scb->cmd.dcdb.op_code = IPS_CMD_DCDB_SG;
3868 scb->cmd.dcdb.enhanced_sg =
3869 IPS_USE_ENH_SGLIST(ha) ? 0xFF : 0;
3870 }
3871
3872 scb->dcdb.device_address =
3873 ((scb->bus - 1) << 4) | scb->target_id;
3874 scb->dcdb.cmd_attribute |= IPS_DISCONNECT_ALLOWED;
3875
3876 if (TimeOut) {
3877 if (TimeOut < (10 * HZ))
3878 scb->dcdb.cmd_attribute |= IPS_TIMEOUT10;
3879 else if (TimeOut < (60 * HZ))
3880 scb->dcdb.cmd_attribute |= IPS_TIMEOUT60;
3881 else if (TimeOut < (1200 * HZ))
3882 scb->dcdb.cmd_attribute |= IPS_TIMEOUT20M;
3883 }
3884
3885 scb->dcdb.transfer_length = scb->data_len;
3886 if (scb->dcdb.cmd_attribute & IPS_TRANSFER64K)
3887 scb->dcdb.transfer_length = 0;
3888 if (scb->cmd.dcdb.op_code == IPS_CMD_DCDB_SG)
3889 scb->dcdb.buffer_pointer =
3890 cpu_to_le32(scb->sg_busaddr);
3891 else
3892 scb->dcdb.buffer_pointer =
3893 cpu_to_le32(scb->data_busaddr);
3894 scb->dcdb.cdb_length = scb->scsi_cmd->cmd_len;
3895 scb->dcdb.sense_length = sizeof (scb->dcdb.sense_info);
3896 scb->dcdb.sg_count = scb->sg_len;
3897 scb->dcdb.reserved = 0;
3898 memcpy(scb->dcdb.scsi_cdb, scb->scsi_cmd->cmnd,
3899 scb->scsi_cmd->cmd_len);
3900 scb->dcdb.scsi_status = 0;
3901 scb->dcdb.reserved2[0] = 0;
3902 scb->dcdb.reserved2[1] = 0;
3903 scb->dcdb.reserved2[2] = 0;
3904 }
3905 }
3906
3907 return ((*ha->func.issue) (ha, scb));
3908}
3909
3910
3911
3912
3913
3914
3915
3916
3917
3918
3919static void
3920ips_chkstatus(ips_ha_t * ha, IPS_STATUS * pstatus)
3921{
3922 ips_scb_t *scb;
3923 ips_stat_t *sp;
3924 uint8_t basic_status;
3925 uint8_t ext_status;
3926 int errcode;
3927 IPS_SCSI_INQ_DATA inquiryData;
3928
3929 METHOD_TRACE("ips_chkstatus", 1);
3930
3931 scb = &ha->scbs[pstatus->fields.command_id];
3932 scb->basic_status = basic_status =
3933 pstatus->fields.basic_status & IPS_BASIC_STATUS_MASK;
3934 scb->extended_status = ext_status = pstatus->fields.extended_status;
3935
3936 sp = &ha->sp;
3937 sp->residue_len = 0;
3938 sp->scb_addr = (void *) scb;
3939
3940
3941 ips_removeq_scb(&ha->scb_activelist, scb);
3942
3943 if (!scb->scsi_cmd)
3944
3945 return;
3946
3947 DEBUG_VAR(2, "(%s%d) ips_chkstatus: cmd 0x%X id %d (%d %d %d)",
3948 ips_name,
3949 ha->host_num,
3950 scb->cdb[0],
3951 scb->cmd.basic_io.command_id,
3952 scb->bus, scb->target_id, scb->lun);
3953
3954 if ((scb->scsi_cmd) && (ips_is_passthru(scb->scsi_cmd)))
3955
3956 return;
3957
3958 errcode = DID_OK;
3959
3960 if (((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_SUCCESS) ||
3961 ((basic_status & IPS_GSC_STATUS_MASK) == IPS_CMD_RECOVERED_ERROR)) {
3962
3963 if (scb->bus == 0) {
3964 if ((basic_status & IPS_GSC_STATUS_MASK) ==
3965 IPS_CMD_RECOVERED_ERROR) {
3966 DEBUG_VAR(1,
3967 "(%s%d) Recovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
3968 ips_name, ha->host_num,
3969 scb->cmd.basic_io.op_code,
3970 basic_status, ext_status);
3971 }
3972
3973 switch (scb->scsi_cmd->cmnd[0]) {
3974 case ALLOW_MEDIUM_REMOVAL:
3975 case REZERO_UNIT:
3976 case ERASE:
3977 case WRITE_FILEMARKS:
3978 case SPACE:
3979 errcode = DID_ERROR;
3980 break;
3981
3982 case START_STOP:
3983 break;
3984
3985 case TEST_UNIT_READY:
3986 if (!ips_online(ha, scb)) {
3987 errcode = DID_TIME_OUT;
3988 }
3989 break;
3990
3991 case INQUIRY:
3992 if (ips_online(ha, scb)) {
3993 ips_inquiry(ha, scb);
3994 } else {
3995 errcode = DID_TIME_OUT;
3996 }
3997 break;
3998
3999 case REQUEST_SENSE:
4000 ips_reqsen(ha, scb);
4001 break;
4002
4003 case READ_6:
4004 case WRITE_6:
4005 case READ_10:
4006 case WRITE_10:
4007 case RESERVE:
4008 case RELEASE:
4009 break;
4010
4011 case MODE_SENSE:
4012 if (!ips_online(ha, scb)
4013 || !ips_msense(ha, scb)) {
4014 errcode = DID_ERROR;
4015 }
4016 break;
4017
4018 case READ_CAPACITY:
4019 if (ips_online(ha, scb))
4020 ips_rdcap(ha, scb);
4021 else {
4022 errcode = DID_TIME_OUT;
4023 }
4024 break;
4025
4026 case SEND_DIAGNOSTIC:
4027 case REASSIGN_BLOCKS:
4028 break;
4029
4030 case FORMAT_UNIT:
4031 errcode = DID_ERROR;
4032 break;
4033
4034 case SEEK_10:
4035 case VERIFY:
4036 case READ_DEFECT_DATA:
4037 case READ_BUFFER:
4038 case WRITE_BUFFER:
4039 break;
4040
4041 default:
4042 errcode = DID_ERROR;
4043 }
4044
4045 scb->scsi_cmd->result = errcode << 16;
4046 } else {
4047
4048 if (scb->scsi_cmd->cmnd[0] == INQUIRY) {
4049 ips_scmd_buf_read(scb->scsi_cmd,
4050 &inquiryData, sizeof (inquiryData));
4051 if ((inquiryData.DeviceType & 0x1f) == TYPE_DISK)
4052 scb->scsi_cmd->result = DID_TIME_OUT << 16;
4053 }
4054 }
4055 } else {
4056 if (scb->bus == 0) {
4057 DEBUG_VAR(1,
4058 "(%s%d) Unrecovered Logical Drive Error OpCode: %x, BSB: %x, ESB: %x",
4059 ips_name, ha->host_num,
4060 scb->cmd.basic_io.op_code, basic_status,
4061 ext_status);
4062 }
4063
4064 ips_map_status(ha, scb, sp);
4065 }
4066}
4067
4068
4069
4070
4071
4072
4073
4074
4075
4076
4077static int
4078ips_online(ips_ha_t * ha, ips_scb_t * scb)
4079{
4080 METHOD_TRACE("ips_online", 1);
4081
4082 if (scb->target_id >= IPS_MAX_LD)
4083 return (0);
4084
4085 if ((scb->basic_status & IPS_GSC_STATUS_MASK) > 1) {
4086 memset(ha->logical_drive_info, 0, sizeof (IPS_LD_INFO));
4087 return (0);
4088 }
4089
4090 if (ha->logical_drive_info->drive_info[scb->target_id].state !=
4091 IPS_LD_OFFLINE
4092 && ha->logical_drive_info->drive_info[scb->target_id].state !=
4093 IPS_LD_FREE
4094 && ha->logical_drive_info->drive_info[scb->target_id].state !=
4095 IPS_LD_CRS
4096 && ha->logical_drive_info->drive_info[scb->target_id].state !=
4097 IPS_LD_SYS)
4098 return (1);
4099 else
4100 return (0);
4101}
4102
4103
4104
4105
4106
4107
4108
4109
4110
4111
4112static int
4113ips_inquiry(ips_ha_t * ha, ips_scb_t * scb)
4114{
4115 IPS_SCSI_INQ_DATA inquiry;
4116
4117 METHOD_TRACE("ips_inquiry", 1);
4118
4119 memset(&inquiry, 0, sizeof (IPS_SCSI_INQ_DATA));
4120
4121 inquiry.DeviceType = IPS_SCSI_INQ_TYPE_DASD;
4122 inquiry.DeviceTypeQualifier = IPS_SCSI_INQ_LU_CONNECTED;
4123 inquiry.Version = IPS_SCSI_INQ_REV2;
4124 inquiry.ResponseDataFormat = IPS_SCSI_INQ_RD_REV2;
4125 inquiry.AdditionalLength = 31;
4126 inquiry.Flags[0] = IPS_SCSI_INQ_Address16;
4127 inquiry.Flags[1] =
4128 IPS_SCSI_INQ_WBus16 | IPS_SCSI_INQ_Sync | IPS_SCSI_INQ_CmdQue;
4129 strncpy(inquiry.VendorId, "IBM ", 8);
4130 strncpy(inquiry.ProductId, "SERVERAID ", 16);
4131 strncpy(inquiry.ProductRevisionLevel, "1.00", 4);
4132
4133 ips_scmd_buf_write(scb->scsi_cmd, &inquiry, sizeof (inquiry));
4134
4135 return (1);
4136}
4137
4138
4139
4140
4141
4142
4143
4144
4145
4146
4147static int
4148ips_rdcap(ips_ha_t * ha, ips_scb_t * scb)
4149{
4150 IPS_SCSI_CAPACITY cap;
4151
4152 METHOD_TRACE("ips_rdcap", 1);
4153
4154 if (scsi_bufflen(scb->scsi_cmd) < 8)
4155 return (0);
4156
4157 cap.lba =
4158 cpu_to_be32(le32_to_cpu
4159 (ha->logical_drive_info->
4160 drive_info[scb->target_id].sector_count) - 1);
4161 cap.len = cpu_to_be32((uint32_t) IPS_BLKSIZE);
4162
4163 ips_scmd_buf_write(scb->scsi_cmd, &cap, sizeof (cap));
4164
4165 return (1);
4166}
4167
4168
4169
4170
4171
4172
4173
4174
4175
4176
4177static int
4178ips_msense(ips_ha_t * ha, ips_scb_t * scb)
4179{
4180 uint16_t heads;
4181 uint16_t sectors;
4182 uint32_t cylinders;
4183 IPS_SCSI_MODE_PAGE_DATA mdata;
4184
4185 METHOD_TRACE("ips_msense", 1);
4186
4187 if (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) > 0x400000 &&
4188 (ha->enq->ucMiscFlag & 0x8) == 0) {
4189 heads = IPS_NORM_HEADS;
4190 sectors = IPS_NORM_SECTORS;
4191 } else {
4192 heads = IPS_COMP_HEADS;
4193 sectors = IPS_COMP_SECTORS;
4194 }
4195
4196 cylinders =
4197 (le32_to_cpu(ha->enq->ulDriveSize[scb->target_id]) -
4198 1) / (heads * sectors);
4199
4200 memset(&mdata, 0, sizeof (IPS_SCSI_MODE_PAGE_DATA));
4201
4202 mdata.hdr.BlockDescLength = 8;
4203
4204 switch (scb->scsi_cmd->cmnd[2] & 0x3f) {
4205 case 0x03:
4206 mdata.pdata.pg3.PageCode = 3;
4207 mdata.pdata.pg3.PageLength = sizeof (IPS_SCSI_MODE_PAGE3);
4208 mdata.hdr.DataLength =
4209 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg3.PageLength;
4210 mdata.pdata.pg3.TracksPerZone = 0;
4211 mdata.pdata.pg3.AltSectorsPerZone = 0;
4212 mdata.pdata.pg3.AltTracksPerZone = 0;
4213 mdata.pdata.pg3.AltTracksPerVolume = 0;
4214 mdata.pdata.pg3.SectorsPerTrack = cpu_to_be16(sectors);
4215 mdata.pdata.pg3.BytesPerSector = cpu_to_be16(IPS_BLKSIZE);
4216 mdata.pdata.pg3.Interleave = cpu_to_be16(1);
4217 mdata.pdata.pg3.TrackSkew = 0;
4218 mdata.pdata.pg3.CylinderSkew = 0;
4219 mdata.pdata.pg3.flags = IPS_SCSI_MP3_SoftSector;
4220 break;
4221
4222 case 0x4:
4223 mdata.pdata.pg4.PageCode = 4;
4224 mdata.pdata.pg4.PageLength = sizeof (IPS_SCSI_MODE_PAGE4);
4225 mdata.hdr.DataLength =
4226 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg4.PageLength;
4227 mdata.pdata.pg4.CylindersHigh =
4228 cpu_to_be16((cylinders >> 8) & 0xFFFF);
4229 mdata.pdata.pg4.CylindersLow = (cylinders & 0xFF);
4230 mdata.pdata.pg4.Heads = heads;
4231 mdata.pdata.pg4.WritePrecompHigh = 0;
4232 mdata.pdata.pg4.WritePrecompLow = 0;
4233 mdata.pdata.pg4.ReducedWriteCurrentHigh = 0;
4234 mdata.pdata.pg4.ReducedWriteCurrentLow = 0;
4235 mdata.pdata.pg4.StepRate = cpu_to_be16(1);
4236 mdata.pdata.pg4.LandingZoneHigh = 0;
4237 mdata.pdata.pg4.LandingZoneLow = 0;
4238 mdata.pdata.pg4.flags = 0;
4239 mdata.pdata.pg4.RotationalOffset = 0;
4240 mdata.pdata.pg4.MediumRotationRate = 0;
4241 break;
4242 case 0x8:
4243 mdata.pdata.pg8.PageCode = 8;
4244 mdata.pdata.pg8.PageLength = sizeof (IPS_SCSI_MODE_PAGE8);
4245 mdata.hdr.DataLength =
4246 3 + mdata.hdr.BlockDescLength + mdata.pdata.pg8.PageLength;
4247
4248 break;
4249
4250 default:
4251 return (0);
4252 }
4253
4254 ips_scmd_buf_write(scb->scsi_cmd, &mdata, sizeof (mdata));
4255
4256 return (1);
4257}
4258
4259
4260
4261
4262
4263
4264
4265
4266
4267
4268static int
4269ips_reqsen(ips_ha_t * ha, ips_scb_t * scb)
4270{
4271 IPS_SCSI_REQSEN reqsen;
4272
4273 METHOD_TRACE("ips_reqsen", 1);
4274
4275 memset(&reqsen, 0, sizeof (IPS_SCSI_REQSEN));
4276
4277 reqsen.ResponseCode =
4278 IPS_SCSI_REQSEN_VALID | IPS_SCSI_REQSEN_CURRENT_ERR;
4279 reqsen.AdditionalLength = 10;
4280 reqsen.AdditionalSenseCode = IPS_SCSI_REQSEN_NO_SENSE;
4281 reqsen.AdditionalSenseCodeQual = IPS_SCSI_REQSEN_NO_SENSE;
4282
4283 ips_scmd_buf_write(scb->scsi_cmd, &reqsen, sizeof (reqsen));
4284
4285 return (1);
4286}
4287
4288
4289
4290
4291
4292
4293
4294
4295
4296
4297static void
4298ips_free(ips_ha_t * ha)
4299{
4300
4301 METHOD_TRACE("ips_free", 1);
4302
4303 if (ha) {
4304 if (ha->enq) {
4305 pci_free_consistent(ha->pcidev, sizeof(IPS_ENQ),
4306 ha->enq, ha->enq_busaddr);
4307 ha->enq = NULL;
4308 }
4309
4310 kfree(ha->conf);
4311 ha->conf = NULL;
4312
4313 if (ha->adapt) {
4314 pci_free_consistent(ha->pcidev,
4315 sizeof (IPS_ADAPTER) +
4316 sizeof (IPS_IO_CMD), ha->adapt,
4317 ha->adapt->hw_status_start);
4318 ha->adapt = NULL;
4319 }
4320
4321 if (ha->logical_drive_info) {
4322 pci_free_consistent(ha->pcidev,
4323 sizeof (IPS_LD_INFO),
4324 ha->logical_drive_info,
4325 ha->logical_drive_info_dma_addr);
4326 ha->logical_drive_info = NULL;
4327 }
4328
4329 kfree(ha->nvram);
4330 ha->nvram = NULL;
4331
4332 kfree(ha->subsys);
4333 ha->subsys = NULL;
4334
4335 if (ha->ioctl_data) {
4336 pci_free_consistent(ha->pcidev, ha->ioctl_len,
4337 ha->ioctl_data, ha->ioctl_busaddr);
4338 ha->ioctl_data = NULL;
4339 ha->ioctl_datasize = 0;
4340 ha->ioctl_len = 0;
4341 }
4342 ips_deallocatescbs(ha, ha->max_cmds);
4343
4344
4345 if (ha->mem_ptr) {
4346 iounmap(ha->ioremap_ptr);
4347 ha->ioremap_ptr = NULL;
4348 ha->mem_ptr = NULL;
4349 }
4350
4351 ha->mem_addr = 0;
4352
4353 }
4354}
4355
4356
4357
4358
4359
4360
4361
4362
4363
4364
4365static int
4366ips_deallocatescbs(ips_ha_t * ha, int cmds)
4367{
4368 if (ha->scbs) {
4369 pci_free_consistent(ha->pcidev,
4370 IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * cmds,
4371 ha->scbs->sg_list.list,
4372 ha->scbs->sg_busaddr);
4373 pci_free_consistent(ha->pcidev, sizeof (ips_scb_t) * cmds,
4374 ha->scbs, ha->scbs->scb_busaddr);
4375 ha->scbs = NULL;
4376 }
4377 return 1;
4378}
4379
4380
4381
4382
4383
4384
4385
4386
4387
4388
4389static int
4390ips_allocatescbs(ips_ha_t * ha)
4391{
4392 ips_scb_t *scb_p;
4393 IPS_SG_LIST ips_sg;
4394 int i;
4395 dma_addr_t command_dma, sg_dma;
4396
4397 METHOD_TRACE("ips_allocatescbs", 1);
4398
4399
4400 ha->scbs =
4401 pci_alloc_consistent(ha->pcidev, ha->max_cmds * sizeof (ips_scb_t),
4402 &command_dma);
4403 if (ha->scbs == NULL)
4404 return 0;
4405 ips_sg.list =
4406 pci_alloc_consistent(ha->pcidev,
4407 IPS_SGLIST_SIZE(ha) * IPS_MAX_SG *
4408 ha->max_cmds, &sg_dma);
4409 if (ips_sg.list == NULL) {
4410 pci_free_consistent(ha->pcidev,
4411 ha->max_cmds * sizeof (ips_scb_t), ha->scbs,
4412 command_dma);
4413 return 0;
4414 }
4415
4416 memset(ha->scbs, 0, ha->max_cmds * sizeof (ips_scb_t));
4417
4418 for (i = 0; i < ha->max_cmds; i++) {
4419 scb_p = &ha->scbs[i];
4420 scb_p->scb_busaddr = command_dma + sizeof (ips_scb_t) * i;
4421
4422 if (IPS_USE_ENH_SGLIST(ha)) {
4423 scb_p->sg_list.enh_list =
4424 ips_sg.enh_list + i * IPS_MAX_SG;
4425 scb_p->sg_busaddr =
4426 sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
4427 } else {
4428 scb_p->sg_list.std_list =
4429 ips_sg.std_list + i * IPS_MAX_SG;
4430 scb_p->sg_busaddr =
4431 sg_dma + IPS_SGLIST_SIZE(ha) * IPS_MAX_SG * i;
4432 }
4433
4434
4435 if (i < ha->max_cmds - 1) {
4436 scb_p->q_next = ha->scb_freelist;
4437 ha->scb_freelist = scb_p;
4438 }
4439 }
4440
4441
4442 return (1);
4443}
4444
4445
4446
4447
4448
4449
4450
4451
4452
4453
4454static void
4455ips_init_scb(ips_ha_t * ha, ips_scb_t * scb)
4456{
4457 IPS_SG_LIST sg_list;
4458 uint32_t cmd_busaddr, sg_busaddr;
4459 METHOD_TRACE("ips_init_scb", 1);
4460
4461 if (scb == NULL)
4462 return;
4463
4464 sg_list.list = scb->sg_list.list;
4465 cmd_busaddr = scb->scb_busaddr;
4466 sg_busaddr = scb->sg_busaddr;
4467
4468 memset(scb, 0, sizeof (ips_scb_t));
4469 memset(ha->dummy, 0, sizeof (IPS_IO_CMD));
4470
4471
4472 ha->dummy->op_code = 0xFF;
4473 ha->dummy->ccsar = cpu_to_le32(ha->adapt->hw_status_start
4474 + sizeof (IPS_ADAPTER));
4475 ha->dummy->command_id = IPS_MAX_CMDS;
4476
4477
4478 scb->scb_busaddr = cmd_busaddr;
4479 scb->sg_busaddr = sg_busaddr;
4480 scb->sg_list.list = sg_list.list;
4481
4482
4483 scb->cmd.basic_io.cccr = cpu_to_le32((uint32_t) IPS_BIT_ILE);
4484 scb->cmd.basic_io.ccsar = cpu_to_le32(ha->adapt->hw_status_start
4485 + sizeof (IPS_ADAPTER));
4486}
4487
4488
4489
4490
4491
4492
4493
4494
4495
4496
4497
4498
4499static ips_scb_t *
4500ips_getscb(ips_ha_t * ha)
4501{
4502 ips_scb_t *scb;
4503
4504 METHOD_TRACE("ips_getscb", 1);
4505
4506 if ((scb = ha->scb_freelist) == NULL) {
4507
4508 return (NULL);
4509 }
4510
4511 ha->scb_freelist = scb->q_next;
4512 scb->flags = 0;
4513 scb->q_next = NULL;
4514
4515 ips_init_scb(ha, scb);
4516
4517 return (scb);
4518}
4519
4520
4521
4522
4523
4524
4525
4526
4527
4528
4529
4530
4531static void
4532ips_freescb(ips_ha_t * ha, ips_scb_t * scb)
4533{
4534
4535 METHOD_TRACE("ips_freescb", 1);
4536 if (scb->flags & IPS_SCB_MAP_SG)
4537 scsi_dma_unmap(scb->scsi_cmd);
4538 else if (scb->flags & IPS_SCB_MAP_SINGLE)
4539 pci_unmap_single(ha->pcidev, scb->data_busaddr, scb->data_len,
4540 IPS_DMA_DIR(scb));
4541
4542
4543 if (IPS_COMMAND_ID(ha, scb) < (ha->max_cmds - 1)) {
4544 scb->q_next = ha->scb_freelist;
4545 ha->scb_freelist = scb;
4546 }
4547}
4548
4549
4550
4551
4552
4553
4554
4555
4556
4557
4558static int
4559ips_isinit_copperhead(ips_ha_t * ha)
4560{
4561 uint8_t scpr;
4562 uint8_t isr;
4563
4564 METHOD_TRACE("ips_isinit_copperhead", 1);
4565
4566 isr = inb(ha->io_addr + IPS_REG_HISR);
4567 scpr = inb(ha->io_addr + IPS_REG_SCPR);
4568
4569 if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
4570 return (0);
4571 else
4572 return (1);
4573}
4574
4575
4576
4577
4578
4579
4580
4581
4582
4583
4584static int
4585ips_isinit_copperhead_memio(ips_ha_t * ha)
4586{
4587 uint8_t isr = 0;
4588 uint8_t scpr;
4589
4590 METHOD_TRACE("ips_is_init_copperhead_memio", 1);
4591
4592 isr = readb(ha->mem_ptr + IPS_REG_HISR);
4593 scpr = readb(ha->mem_ptr + IPS_REG_SCPR);
4594
4595 if (((isr & IPS_BIT_EI) == 0) && ((scpr & IPS_BIT_EBM) == 0))
4596 return (0);
4597 else
4598 return (1);
4599}
4600
4601
4602
4603
4604
4605
4606
4607
4608
4609
4610static int
4611ips_isinit_morpheus(ips_ha_t * ha)
4612{
4613 uint32_t post;
4614 uint32_t bits;
4615
4616 METHOD_TRACE("ips_is_init_morpheus", 1);
4617
4618 if (ips_isintr_morpheus(ha))
4619 ips_flush_and_reset(ha);
4620
4621 post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
4622 bits = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
4623
4624 if (post == 0)
4625 return (0);
4626 else if (bits & 0x3)
4627 return (0);
4628 else
4629 return (1);
4630}
4631
4632
4633
4634
4635
4636
4637
4638
4639
4640
4641
4642static void
4643ips_flush_and_reset(ips_ha_t *ha)
4644{
4645 ips_scb_t *scb;
4646 int ret;
4647 int time;
4648 int done;
4649 dma_addr_t command_dma;
4650
4651
4652 scb = pci_alloc_consistent(ha->pcidev, sizeof(ips_scb_t), &command_dma);
4653 if (scb) {
4654 memset(scb, 0, sizeof(ips_scb_t));
4655 ips_init_scb(ha, scb);
4656 scb->scb_busaddr = command_dma;
4657
4658 scb->timeout = ips_cmd_timeout;
4659 scb->cdb[0] = IPS_CMD_FLUSH;
4660
4661 scb->cmd.flush_cache.op_code = IPS_CMD_FLUSH;
4662 scb->cmd.flush_cache.command_id = IPS_MAX_CMDS;
4663 scb->cmd.flush_cache.state = IPS_NORM_STATE;
4664 scb->cmd.flush_cache.reserved = 0;
4665 scb->cmd.flush_cache.reserved2 = 0;
4666 scb->cmd.flush_cache.reserved3 = 0;
4667 scb->cmd.flush_cache.reserved4 = 0;
4668
4669 ret = ips_send_cmd(ha, scb);
4670
4671 if (ret == IPS_SUCCESS) {
4672 time = 60 * IPS_ONE_SEC;
4673 done = 0;
4674
4675 while ((time > 0) && (!done)) {
4676 done = ips_poll_for_flush_complete(ha);
4677
4678 udelay(1000);
4679 time--;
4680 }
4681 }
4682 }
4683
4684
4685 (*ha->func.reset) (ha);
4686
4687 pci_free_consistent(ha->pcidev, sizeof(ips_scb_t), scb, command_dma);
4688 return;
4689}
4690
4691
4692
4693
4694
4695
4696
4697
4698
4699
4700
4701static int
4702ips_poll_for_flush_complete(ips_ha_t * ha)
4703{
4704 IPS_STATUS cstatus;
4705
4706 while (TRUE) {
4707 cstatus.value = (*ha->func.statupd) (ha);
4708
4709 if (cstatus.value == 0xffffffff)
4710 break;
4711
4712
4713 if (cstatus.fields.command_id == IPS_MAX_CMDS)
4714 return 1;
4715 }
4716
4717 return 0;
4718}
4719
4720
4721
4722
4723
4724
4725
4726
4727
4728static void
4729ips_enable_int_copperhead(ips_ha_t * ha)
4730{
4731 METHOD_TRACE("ips_enable_int_copperhead", 1);
4732
4733 outb(ha->io_addr + IPS_REG_HISR, IPS_BIT_EI);
4734 inb(ha->io_addr + IPS_REG_HISR);
4735}
4736
4737
4738
4739
4740
4741
4742
4743
4744
4745static void
4746ips_enable_int_copperhead_memio(ips_ha_t * ha)
4747{
4748 METHOD_TRACE("ips_enable_int_copperhead_memio", 1);
4749
4750 writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
4751 readb(ha->mem_ptr + IPS_REG_HISR);
4752}
4753
4754
4755
4756
4757
4758
4759
4760
4761
4762static void
4763ips_enable_int_morpheus(ips_ha_t * ha)
4764{
4765 uint32_t Oimr;
4766
4767 METHOD_TRACE("ips_enable_int_morpheus", 1);
4768
4769 Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
4770 Oimr &= ~0x08;
4771 writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
4772 readl(ha->mem_ptr + IPS_REG_I960_OIMR);
4773}
4774
4775
4776
4777
4778
4779
4780
4781
4782
4783
4784static int
4785ips_init_copperhead(ips_ha_t * ha)
4786{
4787 uint8_t Isr;
4788 uint8_t Cbsp;
4789 uint8_t PostByte[IPS_MAX_POST_BYTES];
4790 uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES];
4791 int i, j;
4792
4793 METHOD_TRACE("ips_init_copperhead", 1);
4794
4795 for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
4796 for (j = 0; j < 45; j++) {
4797 Isr = inb(ha->io_addr + IPS_REG_HISR);
4798 if (Isr & IPS_BIT_GHI)
4799 break;
4800
4801
4802 MDELAY(IPS_ONE_SEC);
4803 }
4804
4805 if (j >= 45)
4806
4807 return (0);
4808
4809 PostByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
4810 outb(Isr, ha->io_addr + IPS_REG_HISR);
4811 }
4812
4813 if (PostByte[0] < IPS_GOOD_POST_STATUS) {
4814 IPS_PRINTK(KERN_WARNING, ha->pcidev,
4815 "reset controller fails (post status %x %x).\n",
4816 PostByte[0], PostByte[1]);
4817
4818 return (0);
4819 }
4820
4821 for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
4822 for (j = 0; j < 240; j++) {
4823 Isr = inb(ha->io_addr + IPS_REG_HISR);
4824 if (Isr & IPS_BIT_GHI)
4825 break;
4826
4827
4828 MDELAY(IPS_ONE_SEC);
4829 }
4830
4831 if (j >= 240)
4832
4833 return (0);
4834
4835 ConfigByte[i] = inb(ha->io_addr + IPS_REG_ISPR);
4836 outb(Isr, ha->io_addr + IPS_REG_HISR);
4837 }
4838
4839 for (i = 0; i < 240; i++) {
4840 Cbsp = inb(ha->io_addr + IPS_REG_CBSP);
4841
4842 if ((Cbsp & IPS_BIT_OP) == 0)
4843 break;
4844
4845
4846 MDELAY(IPS_ONE_SEC);
4847 }
4848
4849 if (i >= 240)
4850
4851 return (0);
4852
4853
4854 outl(0x1010, ha->io_addr + IPS_REG_CCCR);
4855
4856
4857 outb(IPS_BIT_EBM, ha->io_addr + IPS_REG_SCPR);
4858
4859 if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
4860
4861 outl(0, ha->io_addr + IPS_REG_NDAE);
4862
4863
4864 outb(IPS_BIT_EI, ha->io_addr + IPS_REG_HISR);
4865
4866 return (1);
4867}
4868
4869
4870
4871
4872
4873
4874
4875
4876
4877
4878static int
4879ips_init_copperhead_memio(ips_ha_t * ha)
4880{
4881 uint8_t Isr = 0;
4882 uint8_t Cbsp;
4883 uint8_t PostByte[IPS_MAX_POST_BYTES];
4884 uint8_t ConfigByte[IPS_MAX_CONFIG_BYTES];
4885 int i, j;
4886
4887 METHOD_TRACE("ips_init_copperhead_memio", 1);
4888
4889 for (i = 0; i < IPS_MAX_POST_BYTES; i++) {
4890 for (j = 0; j < 45; j++) {
4891 Isr = readb(ha->mem_ptr + IPS_REG_HISR);
4892 if (Isr & IPS_BIT_GHI)
4893 break;
4894
4895
4896 MDELAY(IPS_ONE_SEC);
4897 }
4898
4899 if (j >= 45)
4900
4901 return (0);
4902
4903 PostByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
4904 writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
4905 }
4906
4907 if (PostByte[0] < IPS_GOOD_POST_STATUS) {
4908 IPS_PRINTK(KERN_WARNING, ha->pcidev,
4909 "reset controller fails (post status %x %x).\n",
4910 PostByte[0], PostByte[1]);
4911
4912 return (0);
4913 }
4914
4915 for (i = 0; i < IPS_MAX_CONFIG_BYTES; i++) {
4916 for (j = 0; j < 240; j++) {
4917 Isr = readb(ha->mem_ptr + IPS_REG_HISR);
4918 if (Isr & IPS_BIT_GHI)
4919 break;
4920
4921
4922 MDELAY(IPS_ONE_SEC);
4923 }
4924
4925 if (j >= 240)
4926
4927 return (0);
4928
4929 ConfigByte[i] = readb(ha->mem_ptr + IPS_REG_ISPR);
4930 writeb(Isr, ha->mem_ptr + IPS_REG_HISR);
4931 }
4932
4933 for (i = 0; i < 240; i++) {
4934 Cbsp = readb(ha->mem_ptr + IPS_REG_CBSP);
4935
4936 if ((Cbsp & IPS_BIT_OP) == 0)
4937 break;
4938
4939
4940 MDELAY(IPS_ONE_SEC);
4941 }
4942
4943 if (i >= 240)
4944
4945 return (0);
4946
4947
4948 writel(0x1010, ha->mem_ptr + IPS_REG_CCCR);
4949
4950
4951 writeb(IPS_BIT_EBM, ha->mem_ptr + IPS_REG_SCPR);
4952
4953 if (ha->pcidev->revision == IPS_REVID_TROMBONE64)
4954
4955 writel(0, ha->mem_ptr + IPS_REG_NDAE);
4956
4957
4958 writeb(IPS_BIT_EI, ha->mem_ptr + IPS_REG_HISR);
4959
4960
4961 return (1);
4962}
4963
4964
4965
4966
4967
4968
4969
4970
4971
4972
4973static int
4974ips_init_morpheus(ips_ha_t * ha)
4975{
4976 uint32_t Post;
4977 uint32_t Config;
4978 uint32_t Isr;
4979 uint32_t Oimr;
4980 int i;
4981
4982 METHOD_TRACE("ips_init_morpheus", 1);
4983
4984
4985 for (i = 0; i < 45; i++) {
4986 Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
4987
4988 if (Isr & IPS_BIT_I960_MSG0I)
4989 break;
4990
4991
4992 MDELAY(IPS_ONE_SEC);
4993 }
4994
4995 if (i >= 45) {
4996
4997 IPS_PRINTK(KERN_WARNING, ha->pcidev,
4998 "timeout waiting for post.\n");
4999
5000 return (0);
5001 }
5002
5003 Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
5004
5005 if (Post == 0x4F00) {
5006 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5007 "Flashing Battery PIC, Please wait ...\n");
5008
5009
5010 Isr = (uint32_t) IPS_BIT_I960_MSG0I;
5011 writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
5012
5013 for (i = 0; i < 120; i++) {
5014 Post = readl(ha->mem_ptr + IPS_REG_I960_MSG0);
5015 if (Post != 0x4F00)
5016 break;
5017
5018 MDELAY(IPS_ONE_SEC);
5019 }
5020
5021 if (i >= 120) {
5022 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5023 "timeout waiting for Battery PIC Flash\n");
5024 return (0);
5025 }
5026
5027 }
5028
5029
5030 Isr = (uint32_t) IPS_BIT_I960_MSG0I;
5031 writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
5032
5033 if (Post < (IPS_GOOD_POST_STATUS << 8)) {
5034 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5035 "reset controller fails (post status %x).\n", Post);
5036
5037 return (0);
5038 }
5039
5040
5041 for (i = 0; i < 240; i++) {
5042 Isr = readl(ha->mem_ptr + IPS_REG_I2O_HIR);
5043
5044 if (Isr & IPS_BIT_I960_MSG1I)
5045 break;
5046
5047
5048 MDELAY(IPS_ONE_SEC);
5049 }
5050
5051 if (i >= 240) {
5052
5053 IPS_PRINTK(KERN_WARNING, ha->pcidev,
5054 "timeout waiting for config.\n");
5055
5056 return (0);
5057 }
5058
5059 Config = readl(ha->mem_ptr + IPS_REG_I960_MSG1);
5060
5061
5062 Isr = (uint32_t) IPS_BIT_I960_MSG1I;
5063 writel(Isr, ha->mem_ptr + IPS_REG_I2O_HIR);
5064
5065
5066 Oimr = readl(ha->mem_ptr + IPS_REG_I960_OIMR);
5067 Oimr &= ~0x8;
5068 writel(Oimr, ha->mem_ptr + IPS_REG_I960_OIMR);
5069
5070
5071
5072
5073 if (Post == 0xEF10) {
5074 if ((Config == 0x000F) || (Config == 0x0009))
5075 ha->requires_esl = 1;
5076 }
5077
5078 return (1);
5079}
5080
5081
5082
5083
5084
5085
5086
5087
5088
5089
5090static int
5091ips_reset_copperhead(ips_ha_t * ha)
5092{
5093 int reset_counter;
5094
5095 METHOD_TRACE("ips_reset_copperhead", 1);
5096
5097 DEBUG_VAR(1, "(%s%d) ips_reset_copperhead: io addr: %x, irq: %d",
5098 ips_name, ha->host_num, ha->io_addr, ha->pcidev->irq);
5099
5100 reset_counter = 0;
5101
5102 while (reset_counter < 2) {
5103 reset_counter++;
5104
5105 outb(IPS_BIT_RST, ha->io_addr + IPS_REG_SCPR);
5106
5107
5108 MDELAY(IPS_ONE_SEC);
5109
5110 outb(0, ha->io_addr + IPS_REG_SCPR);
5111
5112
5113 MDELAY(IPS_ONE_SEC);
5114
5115 if ((*ha->func.init) (ha))
5116 break;
5117 else if (reset_counter >= 2) {
5118
5119 return (0);
5120 }
5121 }
5122
5123 return (1);
5124}
5125
5126
5127
5128
5129
5130
5131
5132
5133
5134
5135static int
5136ips_reset_copperhead_memio(ips_ha_t * ha)
5137{
5138 int reset_counter;
5139
5140 METHOD_TRACE("ips_reset_copperhead_memio", 1);
5141
5142 DEBUG_VAR(1, "(%s%d) ips_reset_copperhead_memio: mem addr: %x, irq: %d",
5143 ips_name, ha->host_num, ha->mem_addr, ha->pcidev->irq);
5144
5145 reset_counter = 0;
5146
5147 while (reset_counter < 2) {
5148 reset_counter++;
5149
5150 writeb(IPS_BIT_RST, ha->mem_ptr + IPS_REG_SCPR);
5151
5152
5153 MDELAY(IPS_ONE_SEC);
5154
5155 writeb(0, ha->mem_ptr + IPS_REG_SCPR);
5156
5157
5158 MDELAY(IPS_ONE_SEC);
5159
5160 if ((*ha->func.init) (ha))
5161 break;
5162 else if (reset_counter >= 2) {
5163
5164 return (0);
5165 }
5166 }
5167
5168 return (1);
5169}
5170
5171
5172
5173
5174
5175
5176
5177
5178
5179
5180static int
5181ips_reset_morpheus(ips_ha_t * ha)
5182{
5183 int reset_counter;
5184 uint8_t junk;
5185
5186 METHOD_TRACE("ips_reset_morpheus", 1);
5187
5188 DEBUG_VAR(1, "(%s%d) ips_reset_morpheus: mem addr: %x, irq: %d",
5189 ips_name, ha->host_num, ha->mem_addr, ha->pcidev->irq);
5190
5191 reset_counter = 0;
5192
5193 while (reset_counter < 2) {
5194 reset_counter++;
5195
5196 writel(0x80000000, ha->mem_ptr + IPS_REG_I960_IDR);
5197
5198
5199 MDELAY(5 * IPS_ONE_SEC);
5200
5201
5202 pci_read_config_byte(ha->pcidev, 4, &junk);
5203
5204 if ((*ha->func.init) (ha))
5205 break;
5206 else if (reset_counter >= 2) {
5207
5208 return (0);
5209 }
5210 }
5211
5212 return (1);
5213}
5214
5215
5216
5217
5218
5219
5220
5221
5222
5223
5224static void
5225ips_statinit(ips_ha_t * ha)
5226{
5227 uint32_t phys_status_start;
5228
5229 METHOD_TRACE("ips_statinit", 1);
5230
5231 ha->adapt->p_status_start = ha->adapt->status;
5232 ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
5233 ha->adapt->p_status_tail = ha->adapt->status;
5234
5235 phys_status_start = ha->adapt->hw_status_start;
5236 outl(phys_status_start, ha->io_addr + IPS_REG_SQSR);
5237 outl(phys_status_start + IPS_STATUS_Q_SIZE,
5238 ha->io_addr + IPS_REG_SQER);
5239 outl(phys_status_start + IPS_STATUS_SIZE,
5240 ha->io_addr + IPS_REG_SQHR);
5241 outl(phys_status_start, ha->io_addr + IPS_REG_SQTR);
5242
5243 ha->adapt->hw_status_tail = phys_status_start;
5244}
5245
5246
5247
5248
5249
5250
5251
5252
5253
5254
5255static void
5256ips_statinit_memio(ips_ha_t * ha)
5257{
5258 uint32_t phys_status_start;
5259
5260 METHOD_TRACE("ips_statinit_memio", 1);
5261
5262 ha->adapt->p_status_start = ha->adapt->status;
5263 ha->adapt->p_status_end = ha->adapt->status + IPS_MAX_CMDS;
5264 ha->adapt->p_status_tail = ha->adapt->status;
5265