diff options
author | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-15 11:19:33 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@woody.linux-foundation.org> | 2007-10-15 11:19:33 -0400 |
commit | df3d80f5a5c74168be42788364d13cf6c83c7b9c (patch) | |
tree | 892a964c2fd28d028f2fb7471e8543d3f4006a58 /drivers/scsi | |
parent | 3d06f7a5f74a813cee817c4b30b5e6f0398da0be (diff) | |
parent | c8e91b0a8fc8493e3bf3efcb3c8f866e9453cf1c (diff) |
Merge master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6
* master.kernel.org:/pub/scm/linux/kernel/git/jejb/scsi-misc-2.6: (207 commits)
[SCSI] gdth: fix CONFIG_ISA build failure
[SCSI] esp_scsi: remove __dev{init,exit}
[SCSI] gdth: !use_sg cleanup and use of scsi accessors
[SCSI] gdth: Move members from SCp to gdth_cmndinfo, stage 2
[SCSI] gdth: Setup proper per-command private data
[SCSI] gdth: Remove gdth_ctr_tab[]
[SCSI] gdth: switch to modern scsi host registration
[SCSI] gdth: gdth_interrupt() gdth_get_status() & gdth_wait() fixes
[SCSI] gdth: clean up host private data
[SCSI] gdth: Remove virt hosts
[SCSI] gdth: Reorder scsi_host_template intitializers
[SCSI] gdth: kill gdth_{read,write}[bwl] wrappers
[SCSI] gdth: Remove 2.4.x support, in-kernel changelog
[SCSI] gdth: split out pci probing
[SCSI] gdth: split out eisa probing
[SCSI] gdth: split out isa probing
gdth: Make one abuse of scsi_cmnd less obvious
[SCSI] NCR5380: Use scsi_eh API for REQUEST_SENSE invocation
[SCSI] usb storage: use scsi_eh API in REQUEST_SENSE execution
[SCSI] scsi_error: Refactoring scsi_error to facilitate in synchronous REQUEST_SENSE
...
Diffstat (limited to 'drivers/scsi')
106 files changed, 13536 insertions, 18319 deletions
diff --git a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig index 6f2c71ef47ee..30905cebefbb 100644 --- a/drivers/scsi/Kconfig +++ b/drivers/scsi/Kconfig | |||
@@ -272,6 +272,13 @@ config SCSI_FC_ATTRS | |||
272 | each attached FiberChannel device to sysfs, say Y. | 272 | each attached FiberChannel device to sysfs, say Y. |
273 | Otherwise, say N. | 273 | Otherwise, say N. |
274 | 274 | ||
275 | config SCSI_FC_TGT_ATTRS | ||
276 | bool "SCSI target support for FiberChannel Transport Attributes" | ||
277 | depends on SCSI_FC_ATTRS | ||
278 | depends on SCSI_TGT = y || SCSI_TGT = SCSI_FC_ATTRS | ||
279 | help | ||
280 | If you want to use SCSI target mode drivers enable this option. | ||
281 | |||
275 | config SCSI_ISCSI_ATTRS | 282 | config SCSI_ISCSI_ATTRS |
276 | tristate "iSCSI Transport Attributes" | 283 | tristate "iSCSI Transport Attributes" |
277 | depends on SCSI && NET | 284 | depends on SCSI && NET |
@@ -289,6 +296,20 @@ config SCSI_SAS_ATTRS | |||
289 | 296 | ||
290 | source "drivers/scsi/libsas/Kconfig" | 297 | source "drivers/scsi/libsas/Kconfig" |
291 | 298 | ||
299 | config SCSI_SRP_ATTRS | ||
300 | tristate "SRP Transport Attributes" | ||
301 | depends on SCSI | ||
302 | help | ||
303 | If you wish to export transport-specific information about | ||
304 | each attached SRP device to sysfs, say Y. | ||
305 | |||
306 | config SCSI_SRP_TGT_ATTRS | ||
307 | bool "SCSI target support for SRP Transport Attributes" | ||
308 | depends on SCSI_SRP_ATTRS | ||
309 | depends on SCSI_TGT = y || SCSI_TGT = SCSI_SRP_ATTRS | ||
310 | help | ||
311 | If you want to use SCSI target mode drivers enable this option. | ||
312 | |||
292 | endmenu | 313 | endmenu |
293 | 314 | ||
294 | menuconfig SCSI_LOWLEVEL | 315 | menuconfig SCSI_LOWLEVEL |
@@ -502,7 +523,6 @@ config SCSI_ADVANSYS | |||
502 | tristate "AdvanSys SCSI support" | 523 | tristate "AdvanSys SCSI support" |
503 | depends on SCSI | 524 | depends on SCSI |
504 | depends on ISA || EISA || PCI | 525 | depends on ISA || EISA || PCI |
505 | depends on BROKEN || X86_32 | ||
506 | help | 526 | help |
507 | This is a driver for all SCSI host adapters manufactured by | 527 | This is a driver for all SCSI host adapters manufactured by |
508 | AdvanSys. It is documented in the kernel source in | 528 | AdvanSys. It is documented in the kernel source in |
@@ -524,19 +544,32 @@ config SCSI_IN2000 | |||
524 | module will be called in2000. | 544 | module will be called in2000. |
525 | 545 | ||
526 | config SCSI_ARCMSR | 546 | config SCSI_ARCMSR |
527 | tristate "ARECA ARC11X0[PCI-X]/ARC12X0[PCI-EXPRESS] SATA-RAID support" | 547 | tristate "ARECA (ARC11xx/12xx/13xx/16xx) SATA/SAS RAID Host Adapter" |
528 | depends on PCI && SCSI | 548 | depends on PCI && SCSI |
529 | help | 549 | help |
530 | This driver supports all of ARECA's SATA RAID controller cards. | 550 | This driver supports all of ARECA's SATA/SAS RAID controller cards. |
531 | This is an ARECA-maintained driver by Erich Chen. | 551 | This is an ARECA-maintained driver by Erich Chen. |
532 | If you have any problems, please mail to: < erich@areca.com.tw > | 552 | If you have any problems, please mail to: <erich@areca.com.tw>. |
533 | Areca supports Linux RAID config tools. | 553 | Areca supports Linux RAID config tools. |
534 | 554 | Please link <http://www.areca.com.tw> | |
535 | < http://www.areca.com.tw > | ||
536 | 555 | ||
537 | To compile this driver as a module, choose M here: the | 556 | To compile this driver as a module, choose M here: the |
538 | module will be called arcmsr (modprobe arcmsr). | 557 | module will be called arcmsr (modprobe arcmsr). |
539 | 558 | ||
559 | config SCSI_ARCMSR_AER | ||
560 | bool "Enable PCI Error Recovery Capability in Areca Driver(ARCMSR)" | ||
561 | depends on SCSI_ARCMSR && PCIEAER | ||
562 | default n | ||
563 | help | ||
564 | The advanced error reporting(AER) capability is "NOT" provided by | ||
565 | ARC1200/1201/1202 SATA RAID controllers cards. | ||
566 | If your card is one of ARC1200/1201/1202, please use the default setting, n. | ||
567 | If your card is other models, you could pick it | ||
568 | on condition that the kernel version is greater than 2.6.19. | ||
569 | This function is maintained driver by Nick Cheng. If you have any | ||
570 | problems or suggestion, you are welcome to contact with <nick.cheng@areca.com.tw>. | ||
571 | To enable this function, choose Y here. | ||
572 | |||
540 | source "drivers/scsi/megaraid/Kconfig.megaraid" | 573 | source "drivers/scsi/megaraid/Kconfig.megaraid" |
541 | 574 | ||
542 | config SCSI_HPTIOP | 575 | config SCSI_HPTIOP |
@@ -836,6 +869,7 @@ config SCSI_IPS | |||
836 | config SCSI_IBMVSCSI | 869 | config SCSI_IBMVSCSI |
837 | tristate "IBM Virtual SCSI support" | 870 | tristate "IBM Virtual SCSI support" |
838 | depends on PPC_PSERIES || PPC_ISERIES | 871 | depends on PPC_PSERIES || PPC_ISERIES |
872 | select SCSI_SRP_ATTRS | ||
839 | help | 873 | help |
840 | This is the IBM POWER Virtual SCSI Client | 874 | This is the IBM POWER Virtual SCSI Client |
841 | 875 | ||
@@ -844,7 +878,7 @@ config SCSI_IBMVSCSI | |||
844 | 878 | ||
845 | config SCSI_IBMVSCSIS | 879 | config SCSI_IBMVSCSIS |
846 | tristate "IBM Virtual SCSI Server support" | 880 | tristate "IBM Virtual SCSI Server support" |
847 | depends on PPC_PSERIES && SCSI_TGT && SCSI_SRP | 881 | depends on PPC_PSERIES && SCSI_SRP && SCSI_SRP_TGT_ATTRS |
848 | help | 882 | help |
849 | This is the SRP target driver for IBM pSeries virtual environments. | 883 | This is the SRP target driver for IBM pSeries virtual environments. |
850 | 884 | ||
diff --git a/drivers/scsi/Makefile b/drivers/scsi/Makefile index 86a7ba7bad63..6141389dcdb2 100644 --- a/drivers/scsi/Makefile +++ b/drivers/scsi/Makefile | |||
@@ -34,6 +34,7 @@ obj-$(CONFIG_SCSI_FC_ATTRS) += scsi_transport_fc.o | |||
34 | obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o | 34 | obj-$(CONFIG_SCSI_ISCSI_ATTRS) += scsi_transport_iscsi.o |
35 | obj-$(CONFIG_SCSI_SAS_ATTRS) += scsi_transport_sas.o | 35 | obj-$(CONFIG_SCSI_SAS_ATTRS) += scsi_transport_sas.o |
36 | obj-$(CONFIG_SCSI_SAS_LIBSAS) += libsas/ | 36 | obj-$(CONFIG_SCSI_SAS_LIBSAS) += libsas/ |
37 | obj-$(CONFIG_SCSI_SRP_ATTRS) += scsi_transport_srp.o | ||
37 | 38 | ||
38 | obj-$(CONFIG_ISCSI_TCP) += libiscsi.o iscsi_tcp.o | 39 | obj-$(CONFIG_ISCSI_TCP) += libiscsi.o iscsi_tcp.o |
39 | obj-$(CONFIG_INFINIBAND_ISER) += libiscsi.o | 40 | obj-$(CONFIG_INFINIBAND_ISER) += libiscsi.o |
diff --git a/drivers/scsi/NCR5380.c b/drivers/scsi/NCR5380.c index f8e449a98d29..988f0bc5eda5 100644 --- a/drivers/scsi/NCR5380.c +++ b/drivers/scsi/NCR5380.c | |||
@@ -1542,9 +1542,7 @@ part2: | |||
1542 | hostdata->connected = cmd; | 1542 | hostdata->connected = cmd; |
1543 | hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); | 1543 | hostdata->busy[cmd->device->id] |= (1 << cmd->device->lun); |
1544 | 1544 | ||
1545 | if (cmd->SCp.ptr != (char *)cmd->sense_buffer) { | 1545 | initialize_SCp(cmd); |
1546 | initialize_SCp(cmd); | ||
1547 | } | ||
1548 | 1546 | ||
1549 | return 0; | 1547 | return 0; |
1550 | 1548 | ||
@@ -2133,7 +2131,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { | |||
2133 | sink = 1; | 2131 | sink = 1; |
2134 | do_abort(instance); | 2132 | do_abort(instance); |
2135 | cmd->result = DID_ERROR << 16; | 2133 | cmd->result = DID_ERROR << 16; |
2136 | cmd->done(cmd); | 2134 | cmd->scsi_done(cmd); |
2137 | return; | 2135 | return; |
2138 | #endif | 2136 | #endif |
2139 | /* | 2137 | /* |
@@ -2196,7 +2194,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { | |||
2196 | sink = 1; | 2194 | sink = 1; |
2197 | do_abort(instance); | 2195 | do_abort(instance); |
2198 | cmd->result = DID_ERROR << 16; | 2196 | cmd->result = DID_ERROR << 16; |
2199 | cmd->done(cmd); | 2197 | cmd->scsi_done(cmd); |
2200 | /* XXX - need to source or sink data here, as appropriate */ | 2198 | /* XXX - need to source or sink data here, as appropriate */ |
2201 | } else | 2199 | } else |
2202 | cmd->SCp.this_residual -= transfersize - len; | 2200 | cmd->SCp.this_residual -= transfersize - len; |
@@ -2280,19 +2278,16 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) { | |||
2280 | cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); | 2278 | cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); |
2281 | 2279 | ||
2282 | #ifdef AUTOSENSE | 2280 | #ifdef AUTOSENSE |
2281 | if ((cmd->cmnd[0] == REQUEST_SENSE) && | ||
2282 | hostdata->ses.cmd_len) { | ||
2283 | scsi_eh_restore_cmnd(cmd, &hostdata->ses); | ||
2284 | hostdata->ses.cmd_len = 0 ; | ||
2285 | } | ||
2286 | |||
2283 | if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) { | 2287 | if ((cmd->cmnd[0] != REQUEST_SENSE) && (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) { |
2288 | scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0); | ||
2289 | |||
2284 | dprintk(NDEBUG_AUTOSENSE, ("scsi%d : performing request sense\n", instance->host_no)); | 2290 | dprintk(NDEBUG_AUTOSENSE, ("scsi%d : performing request sense\n", instance->host_no)); |
2285 | cmd->cmnd[0] = REQUEST_SENSE; | ||
2286 | cmd->cmnd[1] &= 0xe0; | ||
2287 | cmd->cmnd[2] = 0; | ||
2288 | cmd->cmnd[3] = 0; | ||
2289 | cmd->cmnd[4] = sizeof(cmd->sense_buffer); | ||
2290 | cmd->cmnd[5] = 0; | ||
2291 | |||
2292 | cmd->SCp.buffer = NULL; | ||
2293 | cmd->SCp.buffers_residual = 0; | ||
2294 | cmd->SCp.ptr = (char *) cmd->sense_buffer; | ||
2295 | cmd->SCp.this_residual = sizeof(cmd->sense_buffer); | ||
2296 | 2291 | ||
2297 | LIST(cmd, hostdata->issue_queue); | 2292 | LIST(cmd, hostdata->issue_queue); |
2298 | cmd->host_scribble = (unsigned char *) | 2293 | cmd->host_scribble = (unsigned char *) |
@@ -2740,7 +2735,7 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) { | |||
2740 | tmp->host_scribble = NULL; | 2735 | tmp->host_scribble = NULL; |
2741 | tmp->result = DID_ABORT << 16; | 2736 | tmp->result = DID_ABORT << 16; |
2742 | dprintk(NDEBUG_ABORT, ("scsi%d : abort removed command from issue queue.\n", instance->host_no)); | 2737 | dprintk(NDEBUG_ABORT, ("scsi%d : abort removed command from issue queue.\n", instance->host_no)); |
2743 | tmp->done(tmp); | 2738 | tmp->scsi_done(tmp); |
2744 | return SUCCESS; | 2739 | return SUCCESS; |
2745 | } | 2740 | } |
2746 | #if (NDEBUG & NDEBUG_ABORT) | 2741 | #if (NDEBUG & NDEBUG_ABORT) |
@@ -2805,7 +2800,7 @@ static int NCR5380_abort(Scsi_Cmnd * cmd) { | |||
2805 | *prev = (Scsi_Cmnd *) tmp->host_scribble; | 2800 | *prev = (Scsi_Cmnd *) tmp->host_scribble; |
2806 | tmp->host_scribble = NULL; | 2801 | tmp->host_scribble = NULL; |
2807 | tmp->result = DID_ABORT << 16; | 2802 | tmp->result = DID_ABORT << 16; |
2808 | tmp->done(tmp); | 2803 | tmp->scsi_done(tmp); |
2809 | return SUCCESS; | 2804 | return SUCCESS; |
2810 | } | 2805 | } |
2811 | } | 2806 | } |
diff --git a/drivers/scsi/NCR5380.h b/drivers/scsi/NCR5380.h index bccf13f71532..bdc468c9e1d9 100644 --- a/drivers/scsi/NCR5380.h +++ b/drivers/scsi/NCR5380.h | |||
@@ -30,6 +30,10 @@ | |||
30 | 30 | ||
31 | #include <linux/interrupt.h> | 31 | #include <linux/interrupt.h> |
32 | 32 | ||
33 | #ifdef AUTOSENSE | ||
34 | #include <scsi/scsi_eh.h> | ||
35 | #endif | ||
36 | |||
33 | #define NCR5380_PUBLIC_RELEASE 7 | 37 | #define NCR5380_PUBLIC_RELEASE 7 |
34 | #define NCR53C400_PUBLIC_RELEASE 2 | 38 | #define NCR53C400_PUBLIC_RELEASE 2 |
35 | 39 | ||
@@ -281,6 +285,9 @@ struct NCR5380_hostdata { | |||
281 | unsigned pendingr; | 285 | unsigned pendingr; |
282 | unsigned pendingw; | 286 | unsigned pendingw; |
283 | #endif | 287 | #endif |
288 | #ifdef AUTOSENSE | ||
289 | struct scsi_eh_save ses; | ||
290 | #endif | ||
284 | }; | 291 | }; |
285 | 292 | ||
286 | #ifdef __KERNEL__ | 293 | #ifdef __KERNEL__ |
diff --git a/drivers/scsi/NCR53C9x.c b/drivers/scsi/NCR53C9x.c index 79b4df158140..96e8e29aa05d 100644 --- a/drivers/scsi/NCR53C9x.c +++ b/drivers/scsi/NCR53C9x.c | |||
@@ -1385,7 +1385,7 @@ int esp_abort(Scsi_Cmnd *SCptr) | |||
1385 | this->host_scribble = NULL; | 1385 | this->host_scribble = NULL; |
1386 | esp_release_dmabufs(esp, this); | 1386 | esp_release_dmabufs(esp, this); |
1387 | this->result = DID_ABORT << 16; | 1387 | this->result = DID_ABORT << 16; |
1388 | this->done(this); | 1388 | this->scsi_done(this); |
1389 | if(don) | 1389 | if(don) |
1390 | esp->dma_ints_on(esp); | 1390 | esp->dma_ints_on(esp); |
1391 | return SUCCESS; | 1391 | return SUCCESS; |
diff --git a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c index 3a8089705feb..9e64b21ef637 100644 --- a/drivers/scsi/NCR_D700.c +++ b/drivers/scsi/NCR_D700.c | |||
@@ -97,7 +97,6 @@ | |||
97 | #include <linux/kernel.h> | 97 | #include <linux/kernel.h> |
98 | #include <linux/module.h> | 98 | #include <linux/module.h> |
99 | #include <linux/mca.h> | 99 | #include <linux/mca.h> |
100 | #include <linux/interrupt.h> | ||
101 | #include <asm/io.h> | 100 | #include <asm/io.h> |
102 | #include <scsi/scsi_host.h> | 101 | #include <scsi/scsi_host.h> |
103 | #include <scsi/scsi_device.h> | 102 | #include <scsi/scsi_device.h> |
@@ -314,10 +313,10 @@ NCR_D700_probe(struct device *dev) | |||
314 | break; | 313 | break; |
315 | } | 314 | } |
316 | 315 | ||
317 | p = kmalloc(sizeof(*p), GFP_KERNEL); | 316 | p = kzalloc(sizeof(*p), GFP_KERNEL); |
318 | if (!p) | 317 | if (!p) |
319 | return -ENOMEM; | 318 | return -ENOMEM; |
320 | memset(p, '\0', sizeof(*p)); | 319 | |
321 | p->dev = dev; | 320 | p->dev = dev; |
322 | snprintf(p->name, sizeof(p->name), "D700(%s)", dev->bus_id); | 321 | snprintf(p->name, sizeof(p->name), "D700(%s)", dev->bus_id); |
323 | if (request_irq(irq, NCR_D700_intr, IRQF_SHARED, p->name, p)) { | 322 | if (request_irq(irq, NCR_D700_intr, IRQF_SHARED, p->name, p)) { |
diff --git a/drivers/scsi/a4000t.c b/drivers/scsi/a4000t.c index 0c758d1452ba..d4bda2017746 100644 --- a/drivers/scsi/a4000t.c +++ b/drivers/scsi/a4000t.c | |||
@@ -37,7 +37,7 @@ static struct platform_device *a4000t_scsi_device; | |||
37 | 37 | ||
38 | static int __devinit a4000t_probe(struct device *dev) | 38 | static int __devinit a4000t_probe(struct device *dev) |
39 | { | 39 | { |
40 | struct Scsi_Host * host = NULL; | 40 | struct Scsi_Host *host; |
41 | struct NCR_700_Host_Parameters *hostdata; | 41 | struct NCR_700_Host_Parameters *hostdata; |
42 | 42 | ||
43 | if (!(MACH_IS_AMIGA && AMIGAHW_PRESENT(A4000_SCSI))) | 43 | if (!(MACH_IS_AMIGA && AMIGAHW_PRESENT(A4000_SCSI))) |
@@ -47,12 +47,11 @@ static int __devinit a4000t_probe(struct device *dev) | |||
47 | "A4000T builtin SCSI")) | 47 | "A4000T builtin SCSI")) |
48 | goto out; | 48 | goto out; |
49 | 49 | ||
50 | hostdata = kmalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); | 50 | hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); |
51 | if (hostdata == NULL) { | 51 | if (!hostdata) { |
52 | printk(KERN_ERR "a4000t-scsi: Failed to allocate host data\n"); | 52 | printk(KERN_ERR "a4000t-scsi: Failed to allocate host data\n"); |
53 | goto out_release; | 53 | goto out_release; |
54 | } | 54 | } |
55 | memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters)); | ||
56 | 55 | ||
57 | /* Fill in the required pieces of hostdata */ | 56 | /* Fill in the required pieces of hostdata */ |
58 | hostdata->base = (void __iomem *)ZTWO_VADDR(A4000T_SCSI_ADDR); | 57 | hostdata->base = (void __iomem *)ZTWO_VADDR(A4000T_SCSI_ADDR); |
diff --git a/drivers/scsi/aacraid/aachba.c b/drivers/scsi/aacraid/aachba.c index 6800e578e4b1..80e448d0f3db 100644 --- a/drivers/scsi/aacraid/aachba.c +++ b/drivers/scsi/aacraid/aachba.c | |||
@@ -177,9 +177,9 @@ int check_interval = 24 * 60 * 60; | |||
177 | module_param(check_interval, int, S_IRUGO|S_IWUSR); | 177 | module_param(check_interval, int, S_IRUGO|S_IWUSR); |
178 | MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health checks."); | 178 | MODULE_PARM_DESC(check_interval, "Interval in seconds between adapter health checks."); |
179 | 179 | ||
180 | int check_reset = 1; | 180 | int aac_check_reset = 1; |
181 | module_param(check_reset, int, S_IRUGO|S_IWUSR); | 181 | module_param_named(check_reset, aac_check_reset, int, S_IRUGO|S_IWUSR); |
182 | MODULE_PARM_DESC(check_reset, "If adapter fails health check, reset the adapter."); | 182 | MODULE_PARM_DESC(aac_check_reset, "If adapter fails health check, reset the adapter."); |
183 | 183 | ||
184 | int expose_physicals = -1; | 184 | int expose_physicals = -1; |
185 | module_param(expose_physicals, int, S_IRUGO|S_IWUSR); | 185 | module_param(expose_physicals, int, S_IRUGO|S_IWUSR); |
@@ -1305,7 +1305,7 @@ int aac_get_adapter_info(struct aac_dev* dev) | |||
1305 | (int)sizeof(dev->supplement_adapter_info.VpdInfo.Tsid), | 1305 | (int)sizeof(dev->supplement_adapter_info.VpdInfo.Tsid), |
1306 | dev->supplement_adapter_info.VpdInfo.Tsid); | 1306 | dev->supplement_adapter_info.VpdInfo.Tsid); |
1307 | } | 1307 | } |
1308 | if (!check_reset || | 1308 | if (!aac_check_reset || |
1309 | (dev->supplement_adapter_info.SupportedOptions2 & | 1309 | (dev->supplement_adapter_info.SupportedOptions2 & |
1310 | le32_to_cpu(AAC_OPTION_IGNORE_RESET))) { | 1310 | le32_to_cpu(AAC_OPTION_IGNORE_RESET))) { |
1311 | printk(KERN_INFO "%s%d: Reset Adapter Ignored\n", | 1311 | printk(KERN_INFO "%s%d: Reset Adapter Ignored\n", |
diff --git a/drivers/scsi/aacraid/aacraid.h b/drivers/scsi/aacraid/aacraid.h index 94727b9375ec..03b51025a8f4 100644 --- a/drivers/scsi/aacraid/aacraid.h +++ b/drivers/scsi/aacraid/aacraid.h | |||
@@ -1871,4 +1871,4 @@ extern int aac_reset_devices; | |||
1871 | extern int aac_commit; | 1871 | extern int aac_commit; |
1872 | extern int update_interval; | 1872 | extern int update_interval; |
1873 | extern int check_interval; | 1873 | extern int check_interval; |
1874 | extern int check_reset; | 1874 | extern int aac_check_reset; |
diff --git a/drivers/scsi/aacraid/commsup.c b/drivers/scsi/aacraid/commsup.c index bb870906b4cf..240a0bb8986f 100644 --- a/drivers/scsi/aacraid/commsup.c +++ b/drivers/scsi/aacraid/commsup.c | |||
@@ -1372,8 +1372,9 @@ int aac_check_health(struct aac_dev * aac) | |||
1372 | 1372 | ||
1373 | printk(KERN_ERR "%s: Host adapter BLINK LED 0x%x\n", aac->name, BlinkLED); | 1373 | printk(KERN_ERR "%s: Host adapter BLINK LED 0x%x\n", aac->name, BlinkLED); |
1374 | 1374 | ||
1375 | if (!check_reset || (aac->supplement_adapter_info.SupportedOptions2 & | 1375 | if (!aac_check_reset || |
1376 | le32_to_cpu(AAC_OPTION_IGNORE_RESET))) | 1376 | (aac->supplement_adapter_info.SupportedOptions2 & |
1377 | le32_to_cpu(AAC_OPTION_IGNORE_RESET))) | ||
1377 | goto out; | 1378 | goto out; |
1378 | host = aac->scsi_host_ptr; | 1379 | host = aac->scsi_host_ptr; |
1379 | if (aac->thread->pid != current->pid) | 1380 | if (aac->thread->pid != current->pid) |
diff --git a/drivers/scsi/advansys.c b/drivers/scsi/advansys.c index 79c0b6e37a3b..9dd3952516c5 100644 --- a/drivers/scsi/advansys.c +++ b/drivers/scsi/advansys.c | |||
@@ -1,765 +1,27 @@ | |||
1 | #define ASC_VERSION "3.3K" /* AdvanSys Driver Version */ | 1 | #define DRV_NAME "advansys" |
2 | #define ASC_VERSION "3.4" /* AdvanSys Driver Version */ | ||
2 | 3 | ||
3 | /* | 4 | /* |
4 | * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters | 5 | * advansys.c - Linux Host Driver for AdvanSys SCSI Adapters |
5 | * | 6 | * |
6 | * Copyright (c) 1995-2000 Advanced System Products, Inc. | 7 | * Copyright (c) 1995-2000 Advanced System Products, Inc. |
7 | * Copyright (c) 2000-2001 ConnectCom Solutions, Inc. | 8 | * Copyright (c) 2000-2001 ConnectCom Solutions, Inc. |
9 | * Copyright (c) 2007 Matthew Wilcox <matthew@wil.cx> | ||
8 | * All Rights Reserved. | 10 | * All Rights Reserved. |
9 | * | 11 | * |
10 | * Redistribution and use in source and binary forms, with or without | 12 | * This program is free software; you can redistribute it and/or modify |
11 | * modification, are permitted provided that redistributions of source | 13 | * it under the terms of the GNU General Public License as published by |
12 | * code retain the above copyright notice and this comment without | 14 | * the Free Software Foundation; either version 2 of the License, or |
13 | * modification. | 15 | * (at your option) any later version. |
14 | * | ||
15 | * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys) | ||
16 | * changed its name to ConnectCom Solutions, Inc. | ||
17 | * | ||
18 | */ | 16 | */ |
19 | 17 | ||
20 | /* | 18 | /* |
21 | 19 | * As of March 8, 2000 Advanced System Products, Inc. (AdvanSys) | |
22 | Documentation for the AdvanSys Driver | 20 | * changed its name to ConnectCom Solutions, Inc. |
23 | 21 | * On June 18, 2001 Initio Corp. acquired ConnectCom's SCSI assets | |
24 | A. Linux Kernels Supported by this Driver | ||
25 | B. Adapters Supported by this Driver | ||
26 | C. Linux source files modified by AdvanSys Driver | ||
27 | D. Source Comments | ||
28 | E. Driver Compile Time Options and Debugging | ||
29 | F. Driver LILO Option | ||
30 | G. Tests to run before releasing new driver | ||
31 | H. Release History | ||
32 | I. Known Problems/Fix List | ||
33 | J. Credits (Chronological Order) | ||
34 | |||
35 | A. Linux Kernels Supported by this Driver | ||
36 | |||
37 | This driver has been tested in the following Linux kernels: v2.2.18 | ||
38 | v2.4.0. The driver is supported on v2.2 and v2.4 kernels and on x86, | ||
39 | alpha, and PowerPC platforms. | ||
40 | |||
41 | B. Adapters Supported by this Driver | ||
42 | |||
43 | AdvanSys (Advanced System Products, Inc.) manufactures the following | ||
44 | RISC-based, Bus-Mastering, Fast (10 Mhz) and Ultra (20 Mhz) Narrow | ||
45 | (8-bit transfer) SCSI Host Adapters for the ISA, EISA, VL, and PCI | ||
46 | buses and RISC-based, Bus-Mastering, Ultra (20 Mhz) Wide (16-bit | ||
47 | transfer) SCSI Host Adapters for the PCI bus. | ||
48 | |||
49 | The CDB counts below indicate the number of SCSI CDB (Command | ||
50 | Descriptor Block) requests that can be stored in the RISC chip | ||
51 | cache and board LRAM. A CDB is a single SCSI command. The driver | ||
52 | detect routine will display the number of CDBs available for each | ||
53 | adapter detected. The number of CDBs used by the driver can be | ||
54 | lowered in the BIOS by changing the 'Host Queue Size' adapter setting. | ||
55 | |||
56 | Laptop Products: | ||
57 | ABP-480 - Bus-Master CardBus (16 CDB) (2.4 kernel and greater) | ||
58 | |||
59 | Connectivity Products: | ||
60 | ABP510/5150 - Bus-Master ISA (240 CDB) | ||
61 | ABP5140 - Bus-Master ISA PnP (16 CDB) | ||
62 | ABP5142 - Bus-Master ISA PnP with floppy (16 CDB) | ||
63 | ABP902/3902 - Bus-Master PCI (16 CDB) | ||
64 | ABP3905 - Bus-Master PCI (16 CDB) | ||
65 | ABP915 - Bus-Master PCI (16 CDB) | ||
66 | ABP920 - Bus-Master PCI (16 CDB) | ||
67 | ABP3922 - Bus-Master PCI (16 CDB) | ||
68 | ABP3925 - Bus-Master PCI (16 CDB) | ||
69 | ABP930 - Bus-Master PCI (16 CDB) | ||
70 | ABP930U - Bus-Master PCI Ultra (16 CDB) | ||
71 | ABP930UA - Bus-Master PCI Ultra (16 CDB) | ||
72 | ABP960 - Bus-Master PCI MAC/PC (16 CDB) | ||
73 | ABP960U - Bus-Master PCI MAC/PC Ultra (16 CDB) | ||
74 | |||
75 | Single Channel Products: | ||
76 | ABP542 - Bus-Master ISA with floppy (240 CDB) | ||
77 | ABP742 - Bus-Master EISA (240 CDB) | ||
78 | ABP842 - Bus-Master VL (240 CDB) | ||
79 | ABP940 - Bus-Master PCI (240 CDB) | ||
80 | ABP940U - Bus-Master PCI Ultra (240 CDB) | ||
81 | ABP940UA/3940UA - Bus-Master PCI Ultra (240 CDB) | ||
82 | ABP970 - Bus-Master PCI MAC/PC (240 CDB) | ||
83 | ABP970U - Bus-Master PCI MAC/PC Ultra (240 CDB) | ||
84 | ABP3960UA - Bus-Master PCI MAC/PC Ultra (240 CDB) | ||
85 | ABP940UW/3940UW - Bus-Master PCI Ultra-Wide (253 CDB) | ||
86 | ABP970UW - Bus-Master PCI MAC/PC Ultra-Wide (253 CDB) | ||
87 | ABP3940U2W - Bus-Master PCI LVD/Ultra2-Wide (253 CDB) | ||
88 | |||
89 | Multi-Channel Products: | ||
90 | ABP752 - Dual Channel Bus-Master EISA (240 CDB Per Channel) | ||
91 | ABP852 - Dual Channel Bus-Master VL (240 CDB Per Channel) | ||
92 | ABP950 - Dual Channel Bus-Master PCI (240 CDB Per Channel) | ||
93 | ABP950UW - Dual Channel Bus-Master PCI Ultra-Wide (253 CDB Per Channel) | ||
94 | ABP980 - Four Channel Bus-Master PCI (240 CDB Per Channel) | ||
95 | ABP980U - Four Channel Bus-Master PCI Ultra (240 CDB Per Channel) | ||
96 | ABP980UA/3980UA - Four Channel Bus-Master PCI Ultra (16 CDB Per Chan.) | ||
97 | ABP3950U2W - Bus-Master PCI LVD/Ultra2-Wide and Ultra-Wide (253 CDB) | ||
98 | ABP3950U3W - Bus-Master PCI Dual LVD2/Ultra3-Wide (253 CDB) | ||
99 | |||
100 | C. Linux source files modified by AdvanSys Driver | ||
101 | |||
102 | This section for historical purposes documents the changes | ||
103 | originally made to the Linux kernel source to add the advansys | ||
104 | driver. As Linux has changed some of these files have also | ||
105 | been modified. | ||
106 | |||
107 | 1. linux/arch/i386/config.in: | ||
108 | |||
109 | bool 'AdvanSys SCSI support' CONFIG_SCSI_ADVANSYS y | ||
110 | |||
111 | 2. linux/drivers/scsi/hosts.c: | ||
112 | |||
113 | #ifdef CONFIG_SCSI_ADVANSYS | ||
114 | #include "advansys.h" | ||
115 | #endif | ||
116 | |||
117 | and after "static struct scsi_host_template builtin_scsi_hosts[] =": | ||
118 | |||
119 | #ifdef CONFIG_SCSI_ADVANSYS | ||
120 | ADVANSYS, | ||
121 | #endif | ||
122 | |||
123 | 3. linux/drivers/scsi/Makefile: | ||
124 | |||
125 | ifdef CONFIG_SCSI_ADVANSYS | ||
126 | SCSI_SRCS := $(SCSI_SRCS) advansys.c | ||
127 | SCSI_OBJS := $(SCSI_OBJS) advansys.o | ||
128 | else | ||
129 | SCSI_MODULE_OBJS := $(SCSI_MODULE_OBJS) advansys.o | ||
130 | endif | ||
131 | |||
132 | 4. linux/init/main.c: | ||
133 | |||
134 | extern void advansys_setup(char *str, int *ints); | ||
135 | |||
136 | and add the following lines to the bootsetups[] array. | ||
137 | |||
138 | #ifdef CONFIG_SCSI_ADVANSYS | ||
139 | { "advansys=", advansys_setup }, | ||
140 | #endif | ||
141 | |||
142 | D. Source Comments | ||
143 | |||
144 | 1. Use tab stops set to 4 for the source files. For vi use 'se tabstops=4'. | ||
145 | |||
146 | 2. This driver should be maintained in multiple files. But to make | ||
147 | it easier to include with Linux and to follow Linux conventions, | ||
148 | the whole driver is maintained in the source files advansys.h and | ||
149 | advansys.c. In this file logical sections of the driver begin with | ||
150 | a comment that contains '---'. The following are the logical sections | ||
151 | of the driver below. | ||
152 | |||
153 | --- Linux Version | ||
154 | --- Linux Include File | ||
155 | --- Driver Options | ||
156 | --- Debugging Header | ||
157 | --- Asc Library Constants and Macros | ||
158 | --- Adv Library Constants and Macros | ||
159 | --- Driver Constants and Macros | ||
160 | --- Driver Structures | ||
161 | --- Driver Data | ||
162 | --- Driver Function Prototypes | ||
163 | --- Linux 'struct scsi_host_template' and advansys_setup() Functions | ||
164 | --- Loadable Driver Support | ||
165 | --- Miscellaneous Driver Functions | ||
166 | --- Functions Required by the Asc Library | ||
167 | --- Functions Required by the Adv Library | ||
168 | --- Tracing and Debugging Functions | ||
169 | --- Asc Library Functions | ||
170 | --- Adv Library Functions | ||
171 | |||
172 | 3. The string 'XXX' is used to flag code that needs to be re-written | ||
173 | or that contains a problem that needs to be addressed. | ||
174 | |||
175 | 4. I have stripped comments from and reformatted the source for the | ||
176 | Asc Library and Adv Library to reduce the size of this file. This | ||
177 | source can be found under the following headings. The Asc Library | ||
178 | is used to support Narrow Boards. The Adv Library is used to | ||
179 | support Wide Boards. | ||
180 | |||
181 | --- Asc Library Constants and Macros | ||
182 | --- Adv Library Constants and Macros | ||
183 | --- Asc Library Functions | ||
184 | --- Adv Library Functions | ||
185 | |||
186 | E. Driver Compile Time Options and Debugging | ||
187 | |||
188 | In this source file the following constants can be defined. They are | ||
189 | defined in the source below. Both of these options are enabled by | ||
190 | default. | ||
191 | |||
192 | 1. ADVANSYS_ASSERT - Enable driver assertions (Def: Enabled) | ||
193 | |||
194 | Enabling this option adds assertion logic statements to the | ||
195 | driver. If an assertion fails a message will be displayed to | ||
196 | the console, but the system will continue to operate. Any | ||
197 | assertions encountered should be reported to the person | ||
198 | responsible for the driver. Assertion statements may proactively | ||
199 | detect problems with the driver and facilitate fixing these | ||
200 | problems. Enabling assertions will add a small overhead to the | ||
201 | execution of the driver. | ||
202 | |||
203 | 2. ADVANSYS_DEBUG - Enable driver debugging (Def: Disabled) | ||
204 | |||
205 | Enabling this option adds tracing functions to the driver and | ||
206 | the ability to set a driver tracing level at boot time. This | ||
207 | option will also export symbols not required outside the driver to | ||
208 | the kernel name space. This option is very useful for debugging | ||
209 | the driver, but it will add to the size of the driver execution | ||
210 | image and add overhead to the execution of the driver. | ||
211 | |||
212 | The amount of debugging output can be controlled with the global | ||
213 | variable 'asc_dbglvl'. The higher the number the more output. By | ||
214 | default the debug level is 0. | ||
215 | |||
216 | If the driver is loaded at boot time and the LILO Driver Option | ||
217 | is included in the system, the debug level can be changed by | ||
218 | specifying a 5th (ASC_NUM_IOPORT_PROBE + 1) I/O Port. The | ||
219 | first three hex digits of the pseudo I/O Port must be set to | ||
220 | 'deb' and the fourth hex digit specifies the debug level: 0 - F. | ||
221 | The following command line will look for an adapter at 0x330 | ||
222 | and set the debug level to 2. | ||
223 | |||
224 | linux advansys=0x330,0,0,0,0xdeb2 | ||
225 | |||
226 | If the driver is built as a loadable module this variable can be | ||
227 | defined when the driver is loaded. The following insmod command | ||
228 | will set the debug level to one. | ||
229 | |||
230 | insmod advansys.o asc_dbglvl=1 | ||
231 | |||
232 | Debugging Message Levels: | ||
233 | 0: Errors Only | ||
234 | 1: High-Level Tracing | ||
235 | 2-N: Verbose Tracing | ||
236 | |||
237 | To enable debug output to console, please make sure that: | ||
238 | |||
239 | a. System and kernel logging is enabled (syslogd, klogd running). | ||
240 | b. Kernel messages are routed to console output. Check | ||
241 | /etc/syslog.conf for an entry similar to this: | ||
242 | |||
243 | kern.* /dev/console | ||
244 | |||
245 | c. klogd is started with the appropriate -c parameter | ||
246 | (e.g. klogd -c 8) | ||
247 | |||
248 | This will cause printk() messages to be be displayed on the | ||
249 | current console. Refer to the klogd(8) and syslogd(8) man pages | ||
250 | for details. | ||
251 | |||
252 | Alternatively you can enable printk() to console with this | ||
253 | program. However, this is not the 'official' way to do this. | ||
254 | Debug output is logged in /var/log/messages. | ||
255 | |||
256 | main() | ||
257 | { | ||
258 | syscall(103, 7, 0, 0); | ||
259 | } | ||
260 | |||
261 | Increasing LOG_BUF_LEN in kernel/printk.c to something like | ||
262 | 40960 allows more debug messages to be buffered in the kernel | ||
263 | and written to the console or log file. | ||
264 | |||
265 | 3. ADVANSYS_STATS - Enable statistics (Def: Enabled >= v1.3.0) | ||
266 | |||
267 | Enabling this option adds statistics collection and display | ||
268 | through /proc to the driver. The information is useful for | ||
269 | monitoring driver and device performance. It will add to the | ||
270 | size of the driver execution image and add minor overhead to | ||
271 | the execution of the driver. | ||
272 | |||
273 | Statistics are maintained on a per adapter basis. Driver entry | ||
274 | point call counts and transfer size counts are maintained. | ||
275 | Statistics are only available for kernels greater than or equal | ||
276 | to v1.3.0 with the CONFIG_PROC_FS (/proc) file system configured. | ||
277 | |||
278 | AdvanSys SCSI adapter files have the following path name format: | ||
279 | |||
280 | /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)] | ||
281 | |||
282 | This information can be displayed with cat. For example: | ||
283 | |||
284 | cat /proc/scsi/advansys/0 | ||
285 | |||
286 | When ADVANSYS_STATS is not defined the AdvanSys /proc files only | ||
287 | contain adapter and device configuration information. | ||
288 | |||
289 | F. Driver LILO Option | ||
290 | |||
291 | If init/main.c is modified as described in the 'Directions for Adding | ||
292 | the AdvanSys Driver to Linux' section (B.4.) above, the driver will | ||
293 | recognize the 'advansys' LILO command line and /etc/lilo.conf option. | ||
294 | This option can be used to either disable I/O port scanning or to limit | ||
295 | scanning to 1 - 4 I/O ports. Regardless of the option setting EISA and | ||
296 | PCI boards will still be searched for and detected. This option only | ||
297 | affects searching for ISA and VL boards. | ||
298 | |||
299 | Examples: | ||
300 | 1. Eliminate I/O port scanning: | ||
301 | boot: linux advansys= | ||
302 | or | ||
303 | boot: linux advansys=0x0 | ||
304 | 2. Limit I/O port scanning to one I/O port: | ||
305 | boot: linux advansys=0x110 | ||
306 | 3. Limit I/O port scanning to four I/O ports: | ||
307 | boot: linux advansys=0x110,0x210,0x230,0x330 | ||
308 | |||
309 | For a loadable module the same effect can be achieved by setting | ||
310 | the 'asc_iopflag' variable and 'asc_ioport' array when loading | ||
311 | the driver, e.g. | ||
312 | |||
313 | insmod advansys.o asc_iopflag=1 asc_ioport=0x110,0x330 | ||
314 | |||
315 | If ADVANSYS_DEBUG is defined a 5th (ASC_NUM_IOPORT_PROBE + 1) | ||
316 | I/O Port may be added to specify the driver debug level. Refer to | ||
317 | the 'Driver Compile Time Options and Debugging' section above for | ||
318 | more information. | ||
319 | |||
320 | G. Tests to run before releasing new driver | ||
321 | |||
322 | 1. In the supported kernels verify there are no warning or compile | ||
323 | errors when the kernel is built as both a driver and as a module | ||
324 | and with the following options: | ||
325 | |||
326 | ADVANSYS_DEBUG - enabled and disabled | ||
327 | CONFIG_SMP - enabled and disabled | ||
328 | CONFIG_PROC_FS - enabled and disabled | ||
329 | |||
330 | 2. Run tests on an x86, alpha, and PowerPC with at least one narrow | ||
331 | card and one wide card attached to a hard disk and CD-ROM drive: | ||
332 | fdisk, mkfs, fsck, bonnie, copy/compare test from the | ||
333 | CD-ROM to the hard drive. | ||
334 | |||
335 | H. Release History | ||
336 | |||
337 | BETA-1.0 (12/23/95): | ||
338 | First Release | ||
339 | |||
340 | BETA-1.1 (12/28/95): | ||
341 | 1. Prevent advansys_detect() from being called twice. | ||
342 | 2. Add LILO 0xdeb[0-f] option to set 'asc_dbglvl'. | ||
343 | |||
344 | 1.2 (1/12/96): | ||
345 | 1. Prevent re-entrancy in the interrupt handler which | ||
346 | resulted in the driver hanging Linux. | ||
347 | 2. Fix problem that prevented ABP-940 cards from being | ||
348 | recognized on some PCI motherboards. | ||
349 | 3. Add support for the ABP-5140 PnP ISA card. | ||
350 | 4. Fix check condition return status. | ||
351 | 5. Add conditionally compiled code for Linux v1.3.X. | ||
352 | |||
353 | 1.3 (2/23/96): | ||
354 | 1. Fix problem in advansys_biosparam() that resulted in the | ||
355 | wrong drive geometry being returned for drives > 1GB with | ||
356 | extended translation enabled. | ||
357 | 2. Add additional tracing during device initialization. | ||
358 | 3. Change code that only applies to ISA PnP adapter. | ||
359 | 4. Eliminate 'make dep' warning. | ||
360 | 5. Try to fix problem with handling resets by increasing their | ||
361 | timeout value. | ||
362 | |||
363 | 1.4 (5/8/96): | ||
364 | 1. Change definitions to eliminate conflicts with other subsystems. | ||
365 | 2. Add versioning code for the shared interrupt changes. | ||
366 | 3. Eliminate problem in asc_rmqueue() with iterating after removing | ||
367 | a request. | ||
368 | 4. Remove reset request loop problem from the "Known Problems or | ||
369 | Issues" section. This problem was isolated and fixed in the | ||
370 | mid-level SCSI driver. | ||
371 | |||
372 | 1.5 (8/8/96): | ||
373 | 1. Add support for ABP-940U (PCI Ultra) adapter. | ||
374 | 2. Add support for IRQ sharing by setting the IRQF_SHARED flag for | ||
375 | request_irq and supplying a dev_id pointer to both request_irq() | ||
376 | and free_irq(). | ||
377 | 3. In AscSearchIOPortAddr11() restore a call to check_region() which | ||
378 | should be used before I/O port probing. | ||
379 | 4. Fix bug in asc_prt_hex() which resulted in the displaying | ||
380 | the wrong data. | ||
381 | 5. Incorporate miscellaneous Asc Library bug fixes and new microcode. | ||
382 | 6. Change driver versioning to be specific to each Linux sub-level. | ||
383 | 7. Change statistics gathering to be per adapter instead of global | ||
384 | to the driver. | ||
385 | 8. Add more information and statistics to the adapter /proc file: | ||
386 | /proc/scsi/advansys[0...]. | ||
387 | 9. Remove 'cmd_per_lun' from the "Known Problems or Issues" list. | ||
388 | This problem has been addressed with the SCSI mid-level changes | ||
389 | made in v1.3.89. The advansys_select_queue_depths() function | ||
390 | was added for the v1.3.89 changes. | ||
391 | |||
392 | 1.6 (9/10/96): | ||
393 | 1. Incorporate miscellaneous Asc Library bug fixes and new microcode. | ||
394 | |||
395 | 1.7 (9/25/96): | ||
396 | 1. Enable clustering and optimize the setting of the maximum number | ||
397 | of scatter gather elements for any particular board. Clustering | ||
398 | increases CPU utilization, but results in a relatively larger | ||
399 | increase in I/O throughput. | ||
400 | 2. Improve the performance of the request queuing functions by | ||
401 | adding a last pointer to the queue structure. | ||
402 | 3. Correct problems with reset and abort request handling that | ||
403 | could have hung or crashed Linux. | ||
404 | 4. Add more information to the adapter /proc file: | ||
405 | /proc/scsi/advansys[0...]. | ||
406 | 5. Remove the request timeout issue form the driver issues list. | ||
407 | 6. Miscellaneous documentation additions and changes. | ||
408 | |||
409 | 1.8 (10/4/96): | ||
410 | 1. Make changes to handle the new v2.1.0 kernel memory mapping | ||
411 | in which a kernel virtual address may not be equivalent to its | ||
412 | bus or DMA memory address. | ||
413 | 2. Change abort and reset request handling to make it yet even | ||
414 | more robust. | ||
415 | 3. Try to mitigate request starvation by sending ordered requests | ||
416 | to heavily loaded, tag queuing enabled devices. | ||
417 | 4. Maintain statistics on request response time. | ||
418 | 5. Add request response time statistics and other information to | ||
419 | the adapter /proc file: /proc/scsi/advansys[0...]. | ||
420 | |||
421 | 1.9 (10/21/96): | ||
422 | 1. Add conditionally compiled code (ASC_QUEUE_FLOW_CONTROL) to | ||
423 | make use of mid-level SCSI driver device queue depth flow | ||
424 | control mechanism. This will eliminate aborts caused by a | ||
425 | device being unable to keep up with requests and eliminate | ||
426 | repeat busy or QUEUE FULL status returned by a device. | ||
427 | 2. Incorporate miscellaneous Asc Library bug fixes. | ||
428 | 3. To allow the driver to work in kernels with broken module | ||
429 | support set 'cmd_per_lun' if the driver is compiled as a | ||
430 | module. This change affects kernels v1.3.89 to present. | ||
431 | 4. Remove PCI BIOS address from the driver banner. The PCI BIOS | ||
432 | is relocated by the motherboard BIOS and its new address can | ||
433 | not be determined by the driver. | ||
434 | 5. Add mid-level SCSI queue depth information to the adapter | ||
435 | /proc file: /proc/scsi/advansys[0...]. | ||
436 | |||
437 | 2.0 (11/14/96): | ||
438 | 1. Change allocation of global structures used for device | ||
439 | initialization to guarantee they are in DMA-able memory. | ||
440 | Previously when the driver was loaded as a module these | ||
441 | structures might not have been in DMA-able memory, causing | ||
442 | device initialization to fail. | ||
443 | |||
444 | 2.1 (12/30/96): | ||
445 | 1. In advansys_reset(), if the request is a synchronous reset | ||
446 | request, even if the request serial number has changed, then | ||
447 | complete the request. | ||
448 | 2. Add Asc Library bug fixes including new microcode. | ||
449 | 3. Clear inquiry buffer before using it. | ||
450 | 4. Correct ifdef typo. | ||
451 | |||
452 | 2.2 (1/15/97): | ||
453 | 1. Add Asc Library bug fixes including new microcode. | ||
454 | 2. Add synchronous data transfer rate information to the | ||
455 | adapter /proc file: /proc/scsi/advansys[0...]. | ||
456 | 3. Change ADVANSYS_DEBUG to be disabled by default. This | ||
457 | will reduce the size of the driver image, eliminate execution | ||
458 | overhead, and remove unneeded symbols from the kernel symbol | ||
459 | space that were previously added by the driver. | ||
460 | 4. Add new compile-time option ADVANSYS_ASSERT for assertion | ||
461 | code that used to be defined within ADVANSYS_DEBUG. This | ||
462 | option is enabled by default. | ||
463 | |||
464 | 2.8 (5/26/97): | ||
465 | 1. Change version number to 2.8 to synchronize the Linux driver | ||
466 | version numbering with other AdvanSys drivers. | ||
467 | 2. Reformat source files without tabs to present the same view | ||
468 | of the file to everyone regardless of the editor tab setting | ||
469 | being used. | ||
470 | 3. Add Asc Library bug fixes. | ||
471 | |||
472 | 3.1A (1/8/98): | ||
473 | 1. Change version number to 3.1 to indicate that support for | ||
474 | Ultra-Wide adapters (ABP-940UW) is included in this release. | ||
475 | 2. Add Asc Library (Narrow Board) bug fixes. | ||
476 | 3. Report an underrun condition with the host status byte set | ||
477 | to DID_UNDERRUN. Currently DID_UNDERRUN is defined to 0 which | ||
478 | causes the underrun condition to be ignored. When Linux defines | ||
479 | its own DID_UNDERRUN the constant defined in this file can be | ||
480 | removed. | ||
481 | 4. Add patch to AscWaitTixISRDone(). | ||
482 | 5. Add support for up to 16 different AdvanSys host adapter SCSI | ||
483 | channels in one system. This allows four cards with four channels | ||
484 | to be used in one system. | ||
485 | |||
486 | 3.1B (1/9/98): | ||
487 | 1. Handle that PCI register base addresses are not always page | ||
488 | aligned even though ioremap() requires that the address argument | ||
489 | be page aligned. | ||
490 | |||
491 | 3.1C (1/10/98): | ||
492 | 1. Update latest BIOS version checked for from the /proc file. | ||
493 | 2. Don't set microcode SDTR variable at initialization. Instead | ||
494 | wait until device capabilities have been detected from an Inquiry | ||
495 | command. | ||
496 | |||
497 | 3.1D (1/21/98): | ||
498 | 1. Improve performance when the driver is compiled as module by | ||
499 | allowing up to 64 scatter-gather elements instead of 8. | ||
500 | |||
501 | 3.1E (5/1/98): | ||
502 | 1. Set time delay in AscWaitTixISRDone() to 1000 ms. | ||
503 | 2. Include SMP locking changes. | ||
504 | 3. For v2.1.93 and newer kernels use CONFIG_PCI and new PCI BIOS | ||
505 | access functions. | ||
506 | 4. Update board serial number printing. | ||
507 | 5. Try allocating an IRQ both with and without the IRQF_DISABLED | ||
508 | flag set to allow IRQ sharing with drivers that do not set | ||
509 | the IRQF_DISABLED flag. Also display a more descriptive error | ||
510 | message if request_irq() fails. | ||
511 | 6. Update to latest Asc and Adv Libraries. | ||
512 | |||
513 | 3.2A (7/22/99): | ||
514 | 1. Update Adv Library to 4.16 which includes support for | ||
515 | the ASC38C0800 (Ultra2/LVD) IC. | ||
516 | |||
517 | 3.2B (8/23/99): | ||
518 | 1. Correct PCI compile time option for v2.1.93 and greater | ||
519 | kernels, advansys_info() string, and debug compile time | ||
520 | option. | ||
521 | 2. Correct DvcSleepMilliSecond() for v2.1.0 and greater | ||
522 | kernels. This caused an LVD detection/BIST problem problem | ||
523 | among other things. | ||
524 | 3. Sort PCI cards by PCI Bus, Slot, Function ascending order | ||
525 | to be consistent with the BIOS. | ||
526 | 4. Update to Asc Library S121 and Adv Library 5.2. | ||
527 | |||
528 | 3.2C (8/24/99): | ||
529 | 1. Correct PCI card detection bug introduced in 3.2B that | ||
530 | prevented PCI cards from being detected in kernels older | ||
531 | than v2.1.93. | ||
532 | |||
533 | 3.2D (8/26/99): | ||
534 | 1. Correct /proc device synchronous speed information display. | ||
535 | Also when re-negotiation is pending for a target device | ||
536 | note this condition with an * and footnote. | ||
537 | 2. Correct initialization problem with Ultra-Wide cards that | ||
538 | have a pre-3.2 BIOS. A microcode variable changed locations | ||
539 | in 3.2 and greater BIOSes which caused WDTR to be attempted | ||
540 | erroneously with drives that don't support WDTR. | ||
541 | |||
542 | 3.2E (8/30/99): | ||
543 | 1. Fix compile error caused by v2.3.13 PCI structure change. | ||
544 | 2. Remove field from ASCEEP_CONFIG that resulted in an EEPROM | ||
545 | checksum error for ISA cards. | ||
546 | 3. Remove ASC_QUEUE_FLOW_CONTROL conditional code. The mid-level | ||
547 | SCSI changes that it depended on were never included in Linux. | ||
548 | |||
549 | 3.2F (9/3/99): | ||
550 | 1. Handle new initial function code added in v2.3.16 for all | ||
551 | driver versions. | ||
552 | |||
553 | 3.2G (9/8/99): | ||
554 | 1. Fix PCI board detection in v2.3.13 and greater kernels. | ||
555 | 2. Fix comiple errors in v2.3.X with debugging enabled. | ||
556 | |||
557 | 3.2H (9/13/99): | ||
558 | 1. Add 64-bit address, long support for Alpha and UltraSPARC. | ||
559 | The driver has been verified to work on an Alpha system. | ||
560 | 2. Add partial byte order handling support for Power PC and | ||
561 | other big-endian platforms. This support has not yet been | ||
562 | completed or verified. | ||
563 | 3. For wide boards replace block zeroing of request and | ||
564 | scatter-gather structures with individual field initialization | ||
565 | to improve performance. | ||
566 | 4. Correct and clarify ROM BIOS version detection. | ||
567 | |||
568 | 3.2I (10/8/99): | ||
569 | 1. Update to Adv Library 5.4. | ||
570 | 2. Add v2.3.19 underrun reporting to asc_isr_callback() and | ||
571 | adv_isr_callback(). Remove DID_UNDERRUN constant and other | ||
572 | no longer needed code that previously documented the lack | ||
573 | of underrun handling. | ||
574 | |||
575 | 3.2J (10/14/99): | ||
576 | 1. Eliminate compile errors for v2.0 and earlier kernels. | ||
577 | |||
578 | 3.2K (11/15/99): | ||
579 | 1. Correct debug compile error in asc_prt_adv_scsi_req_q(). | ||
580 | 2. Update Adv Library to 5.5. | ||
581 | 3. Add ifdef handling for /proc changes added in v2.3.28. | ||
582 | 4. Increase Wide board scatter-gather list maximum length to | ||
583 | 255 when the driver is compiled into the kernel. | ||
584 | |||
585 | 3.2L (11/18/99): | ||
586 | 1. Fix bug in adv_get_sglist() that caused an assertion failure | ||
587 | at line 7475. The reqp->sgblkp pointer must be initialized | ||
588 | to NULL in adv_get_sglist(). | ||
589 | |||
590 | 3.2M (11/29/99): | ||
591 | 1. Really fix bug in adv_get_sglist(). | ||
592 | 2. Incorporate v2.3.29 changes into driver. | ||
593 | |||
594 | 3.2N (4/1/00): | ||
595 | 1. Add CONFIG_ISA ifdef code. | ||
596 | 2. Include advansys_interrupts_enabled name change patch. | ||
597 | 3. For >= v2.3.28 use new SCSI error handling with new function | ||
598 | advansys_eh_bus_reset(). Don't include an abort function | ||
599 | because of base library limitations. | ||
600 | 4. For >= v2.3.28 use per board lock instead of io_request_lock. | ||
601 | 5. For >= v2.3.28 eliminate advansys_command() and | ||
602 | advansys_command_done(). | ||
603 | 6. Add some changes for PowerPC (Big Endian) support, but it isn't | ||
604 | working yet. | ||
605 | 7. Fix "nonexistent resource free" problem that occurred on a module | ||
606 | unload for boards with an I/O space >= 255. The 'n_io_port' field | ||
607 | is only one byte and can not be used to hold an ioport length more | ||
608 | than 255. | ||
609 | |||
610 | 3.3A (4/4/00): | ||
611 | 1. Update to Adv Library 5.8. | ||
612 | 2. For wide cards add support for CDBs up to 16 bytes. | ||
613 | 3. Eliminate warnings when CONFIG_PROC_FS is not defined. | ||
614 | |||
615 | 3.3B (5/1/00): | ||
616 | 1. Support for PowerPC (Big Endian) wide cards. Narrow cards | ||
617 | still need work. | ||
618 | 2. Change bitfields to shift and mask access for endian | ||
619 | portability. | ||
620 | |||
621 | 3.3C (10/13/00): | ||
622 | 1. Update for latest 2.4 kernel. | ||
623 | 2. Test ABP-480 CardBus support in 2.4 kernel - works! | ||
624 | 3. Update to Asc Library S123. | ||
625 | 4. Update to Adv Library 5.12. | ||
626 | |||
627 | 3.3D (11/22/00): | ||
628 | 1. Update for latest 2.4 kernel. | ||
629 | 2. Create patches for 2.2 and 2.4 kernels. | ||
630 | |||
631 | 3.3E (1/9/01): | ||
632 | 1. Now that 2.4 is released remove ifdef code for kernel versions | ||
633 | less than 2.2. The driver is now only supported in kernels 2.2, | ||
634 | 2.4, and greater. | ||
635 | 2. Add code to release and acquire the io_request_lock in | ||
636 | the driver entrypoint functions: advansys_detect and | ||
637 | advansys_queuecommand. In kernel 2.4 the SCSI mid-level driver | ||
638 | still holds the io_request_lock on entry to SCSI low-level drivers. | ||
639 | This was supposed to be removed before 2.4 was released but never | ||
640 | happened. When the mid-level SCSI driver is changed all references | ||
641 | to the io_request_lock should be removed from the driver. | ||
642 | 3. Simplify error handling by removing advansys_abort(), | ||
643 | AscAbortSRB(), AscResetDevice(). SCSI bus reset requests are | ||
644 | now handled by resetting the SCSI bus and fully re-initializing | ||
645 | the chip. This simple method of error recovery has proven to work | ||
646 | most reliably after attempts at different methods. Also now only | ||
647 | support the "new" error handling method and remove the obsolete | ||
648 | error handling interface. | ||
649 | 4. Fix debug build errors. | ||
650 | |||
651 | 3.3F (1/24/01): | ||
652 | 1. Merge with ConnectCom version from Andy Kellner which | ||
653 | updates Adv Library to 5.14. | ||
654 | 2. Make PowerPC (Big Endian) work for narrow cards and | ||
655 | fix problems writing EEPROM for wide cards. | ||
656 | 3. Remove interrupts_enabled assertion function. | ||
657 | |||
658 | 3.3G (2/16/01): | ||
659 | 1. Return an error from narrow boards if passed a 16 byte | ||
660 | CDB. The wide board can already handle 16 byte CDBs. | ||
661 | |||
662 | 3.3GJ (4/15/02): | ||
663 | 1. hacks for lk 2.5 series (D. Gilbert) | ||
664 | |||
665 | 3.3GJD (10/14/02): | ||
666 | 1. change select_queue_depths to slave_configure | ||
667 | 2. make cmd_per_lun be sane again | ||
668 | |||
669 | 3.3K [2004/06/24]: | ||
670 | 1. continuing cleanup for lk 2.6 series | ||
671 | 2. Fix problem in lk 2.6.7-bk2 that broke PCI wide cards | ||
672 | 3. Fix problem that oopsed ISA cards | ||
673 | |||
674 | I. Known Problems/Fix List (XXX) | ||
675 | |||
676 | 1. Need to add memory mapping workaround. Test the memory mapping. | ||
677 | If it doesn't work revert to I/O port access. Can a test be done | ||
678 | safely? | ||
679 | 2. Handle an interrupt not working. Keep an interrupt counter in | ||
680 | the interrupt handler. In the timeout function if the interrupt | ||
681 | has not occurred then print a message and run in polled mode. | ||
682 | 3. Allow bus type scanning order to be changed. | ||
683 | 4. Need to add support for target mode commands, cf. CAM XPT. | ||
684 | |||
685 | J. Credits (Chronological Order) | ||
686 | |||
687 | Bob Frey <bfrey@turbolinux.com.cn> wrote the AdvanSys SCSI driver | ||
688 | and maintained it up to 3.3F. He continues to answer questions | ||
689 | and help maintain the driver. | ||
690 | |||
691 | Nathan Hartwell <mage@cdc3.cdc.net> provided the directions and | ||
692 | basis for the Linux v1.3.X changes which were included in the | ||
693 | 1.2 release. | ||
694 | |||
695 | Thomas E Zerucha <zerucha@shell.portal.com> pointed out a bug | ||
696 | in advansys_biosparam() which was fixed in the 1.3 release. | ||
697 | |||
698 | Erik Ratcliffe <erik@caldera.com> has done testing of the | ||
699 | AdvanSys driver in the Caldera releases. | ||
700 | |||
701 | Rik van Riel <H.H.vanRiel@fys.ruu.nl> provided a patch to | ||
702 | AscWaitTixISRDone() which he found necessary to make the | ||
703 | driver work with a SCSI-1 disk. | ||
704 | |||
705 | Mark Moran <mmoran@mmoran.com> has helped test Ultra-Wide | ||
706 | support in the 3.1A driver. | ||
707 | |||
708 | Doug Gilbert <dgilbert@interlog.com> has made changes and | ||
709 | suggestions to improve the driver and done a lot of testing. | ||
710 | |||
711 | Ken Mort <ken@mort.net> reported a DEBUG compile bug fixed | ||
712 | in 3.2K. | ||
713 | |||
714 | Tom Rini <trini@kernel.crashing.org> provided the CONFIG_ISA | ||
715 | patch and helped with PowerPC wide and narrow board support. | ||
716 | |||
717 | Philip Blundell <philb@gnu.org> provided an | ||
718 | advansys_interrupts_enabled patch. | ||
719 | |||
720 | Dave Jones <dave@denial.force9.co.uk> reported the compiler | ||
721 | warnings generated when CONFIG_PROC_FS was not defined in | ||
722 | the 3.2M driver. | ||
723 | |||
724 | Jerry Quinn <jlquinn@us.ibm.com> fixed PowerPC support (endian | ||
725 | problems) for wide cards. | ||
726 | |||
727 | Bryan Henderson <bryanh@giraffe-data.com> helped debug narrow | ||
728 | card error handling. | ||
729 | |||
730 | Manuel Veloso <veloso@pobox.com> worked hard on PowerPC narrow | ||
731 | board support and fixed a bug in AscGetEEPConfig(). | ||
732 | |||
733 | Arnaldo Carvalho de Melo <acme@conectiva.com.br> made | ||
734 | save_flags/restore_flags changes. | ||
735 | |||
736 | Andy Kellner <AKellner@connectcom.net> continues the Advansys SCSI | ||
737 | driver development for ConnectCom (Version > 3.3F). | ||
738 | |||
739 | K. ConnectCom (AdvanSys) Contact Information | ||
740 | |||
741 | Mail: ConnectCom Solutions, Inc. | ||
742 | 1150 Ringwood Court | ||
743 | San Jose, CA 95131 | ||
744 | Operator/Sales: 1-408-383-9400 | ||
745 | FAX: 1-408-383-9612 | ||
746 | Tech Support: 1-408-467-2930 | ||
747 | Tech Support E-Mail: linux@connectcom.net | ||
748 | FTP Site: ftp.connectcom.net (login: anonymous) | ||
749 | Web Site: http://www.connectcom.net | ||
750 | |||
751 | */ | ||
752 | |||
753 | /* | ||
754 | * --- Linux Include Files | ||
755 | */ | 22 | */ |
756 | 23 | ||
757 | #include <linux/module.h> | 24 | #include <linux/module.h> |
758 | |||
759 | #if defined(CONFIG_X86) && !defined(CONFIG_ISA) | ||
760 | #define CONFIG_ISA | ||
761 | #endif /* CONFIG_X86 && !CONFIG_ISA */ | ||
762 | |||
763 | #include <linux/string.h> | 25 | #include <linux/string.h> |
764 | #include <linux/kernel.h> | 26 | #include <linux/kernel.h> |
765 | #include <linux/types.h> | 27 | #include <linux/types.h> |
@@ -771,7 +33,9 @@ | |||
771 | #include <linux/proc_fs.h> | 33 | #include <linux/proc_fs.h> |
772 | #include <linux/init.h> | 34 | #include <linux/init.h> |
773 | #include <linux/blkdev.h> | 35 | #include <linux/blkdev.h> |
774 | #include <linux/stat.h> | 36 | #include <linux/isa.h> |
37 | #include <linux/eisa.h> | ||
38 | #include <linux/pci.h> | ||
775 | #include <linux/spinlock.h> | 39 | #include <linux/spinlock.h> |
776 | #include <linux/dma-mapping.h> | 40 | #include <linux/dma-mapping.h> |
777 | 41 | ||
@@ -779,49 +43,38 @@ | |||
779 | #include <asm/system.h> | 43 | #include <asm/system.h> |
780 | #include <asm/dma.h> | 44 | #include <asm/dma.h> |
781 | 45 | ||
782 | /* FIXME: (by jejb@steeleye.com) This warning is present for two | ||
783 | * reasons: | ||
784 | * | ||
785 | * 1) This driver badly needs converting to the correct driver model | ||
786 | * probing API | ||
787 | * | ||
788 | * 2) Although all of the necessary command mapping places have the | ||
789 | * appropriate dma_map.. APIs, the driver still processes its internal | ||
790 | * queue using bus_to_virt() and virt_to_bus() which are illegal under | ||
791 | * the API. The entire queue processing structure will need to be | ||
792 | * altered to fix this. | ||
793 | */ | ||
794 | #warning this driver is still not properly converted to the DMA API | ||
795 | |||
796 | #include <scsi/scsi_cmnd.h> | 46 | #include <scsi/scsi_cmnd.h> |
797 | #include <scsi/scsi_device.h> | 47 | #include <scsi/scsi_device.h> |
798 | #include <scsi/scsi_tcq.h> | 48 | #include <scsi/scsi_tcq.h> |
799 | #include <scsi/scsi.h> | 49 | #include <scsi/scsi.h> |
800 | #include <scsi/scsi_host.h> | 50 | #include <scsi/scsi_host.h> |
801 | #ifdef CONFIG_PCI | ||
802 | #include <linux/pci.h> | ||
803 | #endif /* CONFIG_PCI */ | ||
804 | 51 | ||
805 | /* | 52 | /* FIXME: |
806 | * --- Driver Options | 53 | * |
54 | * 1. Although all of the necessary command mapping places have the | ||
55 | * appropriate dma_map.. APIs, the driver still processes its internal | ||
56 | * queue using bus_to_virt() and virt_to_bus() which are illegal under | ||
57 | * the API. The entire queue processing structure will need to be | ||
58 | * altered to fix this. | ||
59 | * 2. Need to add memory mapping workaround. Test the memory mapping. | ||
60 | * If it doesn't work revert to I/O port access. Can a test be done | ||
61 | * safely? | ||
62 | * 3. Handle an interrupt not working. Keep an interrupt counter in | ||
63 | * the interrupt handler. In the timeout function if the interrupt | ||
64 | * has not occurred then print a message and run in polled mode. | ||
65 | * 4. Need to add support for target mode commands, cf. CAM XPT. | ||
66 | * 5. check DMA mapping functions for failure | ||
67 | * 6. Use scsi_transport_spi | ||
68 | * 7. advansys_info is not safe against multiple simultaneous callers | ||
69 | * 8. Add module_param to override ISA/VLB ioport array | ||
807 | */ | 70 | */ |
808 | 71 | #warning this driver is still not properly converted to the DMA API | |
809 | /* Enable driver assertions. */ | ||
810 | #define ADVANSYS_ASSERT | ||
811 | 72 | ||
812 | /* Enable driver /proc statistics. */ | 73 | /* Enable driver /proc statistics. */ |
813 | #define ADVANSYS_STATS | 74 | #define ADVANSYS_STATS |
814 | 75 | ||
815 | /* Enable driver tracing. */ | 76 | /* Enable driver tracing. */ |
816 | /* #define ADVANSYS_DEBUG */ | 77 | #undef ADVANSYS_DEBUG |
817 | |||
818 | /* | ||
819 | * --- Asc Library Constants and Macros | ||
820 | */ | ||
821 | |||
822 | #define ASC_LIB_VERSION_MAJOR 1 | ||
823 | #define ASC_LIB_VERSION_MINOR 24 | ||
824 | #define ASC_LIB_SERIAL_NUMBER 123 | ||
825 | 78 | ||
826 | /* | 79 | /* |
827 | * Portable Data Types | 80 | * Portable Data Types |
@@ -837,17 +90,6 @@ | |||
837 | #define ASC_DCNT __u32 /* Unsigned Data count type. */ | 90 | #define ASC_DCNT __u32 /* Unsigned Data count type. */ |
838 | #define ASC_SDCNT __s32 /* Signed Data count type. */ | 91 | #define ASC_SDCNT __s32 /* Signed Data count type. */ |
839 | 92 | ||
840 | /* | ||
841 | * These macros are used to convert a virtual address to a | ||
842 | * 32-bit value. This currently can be used on Linux Alpha | ||
843 | * which uses 64-bit virtual address but a 32-bit bus address. | ||
844 | * This is likely to break in the future, but doing this now | ||
845 | * will give us time to change the HW and FW to handle 64-bit | ||
846 | * addresses. | ||
847 | */ | ||
848 | #define ASC_VADDR_TO_U32 virt_to_bus | ||
849 | #define ASC_U32_TO_VADDR bus_to_virt | ||
850 | |||
851 | typedef unsigned char uchar; | 93 | typedef unsigned char uchar; |
852 | 94 | ||
853 | #ifndef TRUE | 95 | #ifndef TRUE |
@@ -857,29 +99,9 @@ typedef unsigned char uchar; | |||
857 | #define FALSE (0) | 99 | #define FALSE (0) |
858 | #endif | 100 | #endif |
859 | 101 | ||
860 | #define EOF (-1) | ||
861 | #define ERR (-1) | 102 | #define ERR (-1) |
862 | #define UW_ERR (uint)(0xFFFF) | 103 | #define UW_ERR (uint)(0xFFFF) |
863 | #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0) | 104 | #define isodd_word(val) ((((uint)val) & (uint)0x0001) != 0) |
864 | #define AscPCIConfigVendorIDRegister 0x0000 | ||
865 | #define AscPCIConfigDeviceIDRegister 0x0002 | ||
866 | #define AscPCIConfigCommandRegister 0x0004 | ||
867 | #define AscPCIConfigStatusRegister 0x0006 | ||
868 | #define AscPCIConfigRevisionIDRegister 0x0008 | ||
869 | #define AscPCIConfigCacheSize 0x000C | ||
870 | #define AscPCIConfigLatencyTimer 0x000D | ||
871 | #define AscPCIIOBaseRegister 0x0010 | ||
872 | #define AscPCICmdRegBits_IOMemBusMaster 0x0007 | ||
873 | #define ASC_PCI_ID2BUS(id) ((id) & 0xFF) | ||
874 | #define ASC_PCI_ID2DEV(id) (((id) >> 11) & 0x1F) | ||
875 | #define ASC_PCI_ID2FUNC(id) (((id) >> 8) & 0x7) | ||
876 | #define ASC_PCI_MKID(bus, dev, func) ((((dev) & 0x1F) << 11) | (((func) & 0x7) << 8) | ((bus) & 0xFF)) | ||
877 | #define ASC_PCI_REVISION_3150 0x02 | ||
878 | #define ASC_PCI_REVISION_3050 0x03 | ||
879 | |||
880 | #define ASC_DVCLIB_CALL_DONE (1) | ||
881 | #define ASC_DVCLIB_CALL_FAILED (0) | ||
882 | #define ASC_DVCLIB_CALL_ERROR (-1) | ||
883 | 105 | ||
884 | #define PCI_VENDOR_ID_ASP 0x10cd | 106 | #define PCI_VENDOR_ID_ASP 0x10cd |
885 | #define PCI_DEVICE_ID_ASP_1200A 0x1100 | 107 | #define PCI_DEVICE_ID_ASP_1200A 0x1100 |
@@ -898,7 +120,7 @@ typedef unsigned char uchar; | |||
898 | #define CC_VERY_LONG_SG_LIST 0 | 120 | #define CC_VERY_LONG_SG_LIST 0 |
899 | #define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr) | 121 | #define ASC_SRB2SCSIQ(srb_ptr) (srb_ptr) |
900 | 122 | ||
901 | #define PortAddr unsigned short /* port address size */ | 123 | #define PortAddr unsigned int /* port address size */ |
902 | #define inp(port) inb(port) | 124 | #define inp(port) inb(port) |
903 | #define outp(port, byte) outb((byte), (port)) | 125 | #define outp(port, byte) outb((byte), (port)) |
904 | 126 | ||
@@ -918,11 +140,10 @@ typedef unsigned char uchar; | |||
918 | #define ASC_IS_PCMCIA (0x0008) | 140 | #define ASC_IS_PCMCIA (0x0008) |
919 | #define ASC_IS_MCA (0x0020) | 141 | #define ASC_IS_MCA (0x0020) |
920 | #define ASC_IS_VL (0x0040) | 142 | #define ASC_IS_VL (0x0040) |
921 | #define ASC_ISA_PNP_PORT_ADDR (0x279) | ||
922 | #define ASC_ISA_PNP_PORT_WRITE (ASC_ISA_PNP_PORT_ADDR+0x800) | ||
923 | #define ASC_IS_WIDESCSI_16 (0x0100) | 143 | #define ASC_IS_WIDESCSI_16 (0x0100) |
924 | #define ASC_IS_WIDESCSI_32 (0x0200) | 144 | #define ASC_IS_WIDESCSI_32 (0x0200) |
925 | #define ASC_IS_BIG_ENDIAN (0x8000) | 145 | #define ASC_IS_BIG_ENDIAN (0x8000) |
146 | |||
926 | #define ASC_CHIP_MIN_VER_VL (0x01) | 147 | #define ASC_CHIP_MIN_VER_VL (0x01) |
927 | #define ASC_CHIP_MAX_VER_VL (0x07) | 148 | #define ASC_CHIP_MAX_VER_VL (0x07) |
928 | #define ASC_CHIP_MIN_VER_PCI (0x09) | 149 | #define ASC_CHIP_MIN_VER_PCI (0x09) |
@@ -941,16 +162,9 @@ typedef unsigned char uchar; | |||
941 | #define ASC_CHIP_MAX_VER_EISA (0x47) | 162 | #define ASC_CHIP_MAX_VER_EISA (0x47) |
942 | #define ASC_CHIP_VER_EISA_BIT (0x40) | 163 | #define ASC_CHIP_VER_EISA_BIT (0x40) |
943 | #define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3) | 164 | #define ASC_CHIP_LATEST_VER_EISA ((ASC_CHIP_MIN_VER_EISA - 1) + 3) |
944 | #define ASC_MAX_LIB_SUPPORTED_ISA_CHIP_VER 0x21 | ||
945 | #define ASC_MAX_LIB_SUPPORTED_PCI_CHIP_VER 0x0A | ||
946 | #define ASC_MAX_VL_DMA_ADDR (0x07FFFFFFL) | ||
947 | #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL) | 165 | #define ASC_MAX_VL_DMA_COUNT (0x07FFFFFFL) |
948 | #define ASC_MAX_PCI_DMA_ADDR (0xFFFFFFFFL) | ||
949 | #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL) | 166 | #define ASC_MAX_PCI_DMA_COUNT (0xFFFFFFFFL) |
950 | #define ASC_MAX_ISA_DMA_ADDR (0x00FFFFFFL) | ||
951 | #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL) | 167 | #define ASC_MAX_ISA_DMA_COUNT (0x00FFFFFFL) |
952 | #define ASC_MAX_EISA_DMA_ADDR (0x07FFFFFFL) | ||
953 | #define ASC_MAX_EISA_DMA_COUNT (0x07FFFFFFL) | ||
954 | 168 | ||
955 | #define ASC_SCSI_ID_BITS 3 | 169 | #define ASC_SCSI_ID_BITS 3 |
956 | #define ASC_SCSI_TIX_TYPE uchar | 170 | #define ASC_SCSI_TIX_TYPE uchar |
@@ -961,82 +175,17 @@ typedef unsigned char uchar; | |||
961 | #define ASC_SCSI_WIDTH_BIT_SET 0xFF | 175 | #define ASC_SCSI_WIDTH_BIT_SET 0xFF |
962 | #define ASC_MAX_SENSE_LEN 32 | 176 | #define ASC_MAX_SENSE_LEN 32 |
963 | #define ASC_MIN_SENSE_LEN 14 | 177 | #define ASC_MIN_SENSE_LEN 14 |
964 | #define ASC_MAX_CDB_LEN 12 | ||
965 | #define ASC_SCSI_RESET_HOLD_TIME_US 60 | 178 | #define ASC_SCSI_RESET_HOLD_TIME_US 60 |
966 | 179 | ||
967 | #define ADV_INQ_CLOCKING_ST_ONLY 0x0 | ||
968 | #define ADV_INQ_CLOCKING_DT_ONLY 0x1 | ||
969 | #define ADV_INQ_CLOCKING_ST_AND_DT 0x3 | ||
970 | |||
971 | /* | 180 | /* |
972 | * Inquiry SPC-2 SPI Byte 1 EVPD (Enable Vital Product Data) | 181 | * Narrow boards only support 12-byte commands, while wide boards |
973 | * and CmdDt (Command Support Data) field bit definitions. | 182 | * extend to 16-byte commands. |
974 | */ | 183 | */ |
975 | #define ADV_INQ_RTN_VPD_AND_CMDDT 0x3 | 184 | #define ASC_MAX_CDB_LEN 12 |
976 | #define ADV_INQ_RTN_CMDDT_FOR_OP_CODE 0x2 | 185 | #define ADV_MAX_CDB_LEN 16 |
977 | #define ADV_INQ_RTN_VPD_FOR_PG_CODE 0x1 | 186 | |
978 | #define ADV_INQ_RTN_STD_INQUIRY_DATA 0x0 | ||
979 | |||
980 | #define ASC_SCSIDIR_NOCHK 0x00 | ||
981 | #define ASC_SCSIDIR_T2H 0x08 | ||
982 | #define ASC_SCSIDIR_H2T 0x10 | ||
983 | #define ASC_SCSIDIR_NODATA 0x18 | ||
984 | #define SCSI_ASC_NOMEDIA 0x3A | ||
985 | #define ASC_SRB_HOST(x) ((uchar)((uchar)(x) >> 4)) | ||
986 | #define ASC_SRB_TID(x) ((uchar)((uchar)(x) & (uchar)0x0F)) | ||
987 | #define ASC_SRB_LUN(x) ((uchar)((uint)(x) >> 13)) | ||
988 | #define PUT_CDB1(x) ((uchar)((uint)(x) >> 8)) | ||
989 | #define MS_CMD_DONE 0x00 | ||
990 | #define MS_EXTEND 0x01 | ||
991 | #define MS_SDTR_LEN 0x03 | 187 | #define MS_SDTR_LEN 0x03 |
992 | #define MS_SDTR_CODE 0x01 | ||
993 | #define MS_WDTR_LEN 0x02 | 188 | #define MS_WDTR_LEN 0x02 |
994 | #define MS_WDTR_CODE 0x03 | ||
995 | #define MS_MDP_LEN 0x05 | ||
996 | #define MS_MDP_CODE 0x00 | ||
997 | |||
998 | /* | ||
999 | * Inquiry data structure and bitfield macros | ||
1000 | * | ||
1001 | * Only quantities of more than 1 bit are shifted, since the others are | ||
1002 | * just tested for true or false. C bitfields aren't portable between big | ||
1003 | * and little-endian platforms so they are not used. | ||
1004 | */ | ||
1005 | |||
1006 | #define ASC_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f) | ||
1007 | #define ASC_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5) | ||
1008 | #define ASC_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f) | ||
1009 | #define ASC_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80) | ||
1010 | #define ASC_INQ_ANSI_VER(inq) ((inq)->ver & 0x07) | ||
1011 | #define ASC_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3) | ||
1012 | #define ASC_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6) | ||
1013 | #define ASC_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f) | ||
1014 | #define ASC_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40) | ||
1015 | #define ASC_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80) | ||
1016 | #define ASC_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01) | ||
1017 | #define ASC_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02) | ||
1018 | #define ASC_INQ_LINK_CMD(inq) ((inq)->flags & 0x08) | ||
1019 | #define ASC_INQ_SYNC(inq) ((inq)->flags & 0x10) | ||
1020 | #define ASC_INQ_WIDE16(inq) ((inq)->flags & 0x20) | ||
1021 | #define ASC_INQ_WIDE32(inq) ((inq)->flags & 0x40) | ||
1022 | #define ASC_INQ_REL_ADDR(inq) ((inq)->flags & 0x80) | ||
1023 | #define ASC_INQ_INFO_UNIT(inq) ((inq)->info & 0x01) | ||
1024 | #define ASC_INQ_QUICK_ARB(inq) ((inq)->info & 0x02) | ||
1025 | #define ASC_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2) | ||
1026 | |||
1027 | typedef struct { | ||
1028 | uchar periph; | ||
1029 | uchar devtype; | ||
1030 | uchar ver; | ||
1031 | uchar byte3; | ||
1032 | uchar add_len; | ||
1033 | uchar res1; | ||
1034 | uchar res2; | ||
1035 | uchar flags; | ||
1036 | uchar vendor_id[8]; | ||
1037 | uchar product_id[16]; | ||
1038 | uchar product_rev_level[4]; | ||
1039 | } ASC_SCSI_INQUIRY; | ||
1040 | 189 | ||
1041 | #define ASC_SG_LIST_PER_Q 7 | 190 | #define ASC_SG_LIST_PER_Q 7 |
1042 | #define QS_FREE 0x00 | 191 | #define QS_FREE 0x00 |
@@ -1215,22 +364,9 @@ typedef struct asc_sg_head { | |||
1215 | ushort queue_cnt; | 364 | ushort queue_cnt; |
1216 | ushort entry_to_copy; | 365 | ushort entry_to_copy; |
1217 | ushort res; | 366 | ushort res; |
1218 | ASC_SG_LIST sg_list[ASC_MAX_SG_LIST]; | 367 | ASC_SG_LIST sg_list[0]; |
1219 | } ASC_SG_HEAD; | 368 | } ASC_SG_HEAD; |
1220 | 369 | ||
1221 | #define ASC_MIN_SG_LIST 2 | ||
1222 | |||
1223 | typedef struct asc_min_sg_head { | ||
1224 | ushort entry_cnt; | ||
1225 | ushort queue_cnt; | ||
1226 | ushort entry_to_copy; | ||
1227 | ushort res; | ||
1228 | ASC_SG_LIST sg_list[ASC_MIN_SG_LIST]; | ||
1229 | } ASC_MIN_SG_HEAD; | ||
1230 | |||
1231 | #define QCX_SORT (0x0001) | ||
1232 | #define QCX_COALEASE (0x0002) | ||
1233 | |||
1234 | typedef struct asc_scsi_q { | 370 | typedef struct asc_scsi_q { |
1235 | ASC_SCSIQ_1 q1; | 371 | ASC_SCSIQ_1 q1; |
1236 | ASC_SCSIQ_2 q2; | 372 | ASC_SCSIQ_2 q2; |
@@ -1287,45 +423,12 @@ typedef struct asc_risc_sg_list_q { | |||
1287 | ASC_SG_LIST sg_list[7]; | 423 | ASC_SG_LIST sg_list[7]; |
1288 | } ASC_RISC_SG_LIST_Q; | 424 | } ASC_RISC_SG_LIST_Q; |
1289 | 425 | ||
1290 | #define ASC_EXE_SCSI_IO_MAX_IDLE_LOOP 0x1000000UL | ||
1291 | #define ASC_EXE_SCSI_IO_MAX_WAIT_LOOP 1024 | ||
1292 | #define ASCQ_ERR_NO_ERROR 0 | ||
1293 | #define ASCQ_ERR_IO_NOT_FOUND 1 | ||
1294 | #define ASCQ_ERR_LOCAL_MEM 2 | ||
1295 | #define ASCQ_ERR_CHKSUM 3 | ||
1296 | #define ASCQ_ERR_START_CHIP 4 | ||
1297 | #define ASCQ_ERR_INT_TARGET_ID 5 | ||
1298 | #define ASCQ_ERR_INT_LOCAL_MEM 6 | ||
1299 | #define ASCQ_ERR_HALT_RISC 7 | ||
1300 | #define ASCQ_ERR_GET_ASPI_ENTRY 8 | ||
1301 | #define ASCQ_ERR_CLOSE_ASPI 9 | ||
1302 | #define ASCQ_ERR_HOST_INQUIRY 0x0A | ||
1303 | #define ASCQ_ERR_SAVED_SRB_BAD 0x0B | ||
1304 | #define ASCQ_ERR_QCNTL_SG_LIST 0x0C | ||
1305 | #define ASCQ_ERR_Q_STATUS 0x0D | 426 | #define ASCQ_ERR_Q_STATUS 0x0D |
1306 | #define ASCQ_ERR_WR_SCSIQ 0x0E | ||
1307 | #define ASCQ_ERR_PC_ADDR 0x0F | ||
1308 | #define ASCQ_ERR_SYN_OFFSET 0x10 | ||
1309 | #define ASCQ_ERR_SYN_XFER_TIME 0x11 | ||
1310 | #define ASCQ_ERR_LOCK_DMA 0x12 | ||
1311 | #define ASCQ_ERR_UNLOCK_DMA 0x13 | ||
1312 | #define ASCQ_ERR_VDS_CHK_INSTALL 0x14 | ||
1313 | #define ASCQ_ERR_MICRO_CODE_HALT 0x15 | ||
1314 | #define ASCQ_ERR_SET_LRAM_ADDR 0x16 | ||
1315 | #define ASCQ_ERR_CUR_QNG 0x17 | 427 | #define ASCQ_ERR_CUR_QNG 0x17 |
1316 | #define ASCQ_ERR_SG_Q_LINKS 0x18 | 428 | #define ASCQ_ERR_SG_Q_LINKS 0x18 |
1317 | #define ASCQ_ERR_SCSIQ_PTR 0x19 | ||
1318 | #define ASCQ_ERR_ISR_RE_ENTRY 0x1A | 429 | #define ASCQ_ERR_ISR_RE_ENTRY 0x1A |
1319 | #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B | 430 | #define ASCQ_ERR_CRITICAL_RE_ENTRY 0x1B |
1320 | #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C | 431 | #define ASCQ_ERR_ISR_ON_CRITICAL 0x1C |
1321 | #define ASCQ_ERR_SG_LIST_ODD_ADDRESS 0x1D | ||
1322 | #define ASCQ_ERR_XFER_ADDRESS_TOO_BIG 0x1E | ||
1323 | #define ASCQ_ERR_SCSIQ_NULL_PTR 0x1F | ||
1324 | #define ASCQ_ERR_SCSIQ_BAD_NEXT_PTR 0x20 | ||
1325 | #define ASCQ_ERR_GET_NUM_OF_FREE_Q 0x21 | ||
1326 | #define ASCQ_ERR_SEND_SCSI_Q 0x22 | ||
1327 | #define ASCQ_ERR_HOST_REQ_RISC_HALT 0x23 | ||
1328 | #define ASCQ_ERR_RESET_SDTR 0x24 | ||
1329 | 432 | ||
1330 | /* | 433 | /* |
1331 | * Warning code values are set in ASC_DVC_VAR 'warn_code'. | 434 | * Warning code values are set in ASC_DVC_VAR 'warn_code'. |
@@ -1338,84 +441,51 @@ typedef struct asc_risc_sg_list_q { | |||
1338 | #define ASC_WARN_CMD_QNG_CONFLICT 0x0010 | 441 | #define ASC_WARN_CMD_QNG_CONFLICT 0x0010 |
1339 | #define ASC_WARN_EEPROM_RECOVER 0x0020 | 442 | #define ASC_WARN_EEPROM_RECOVER 0x0020 |
1340 | #define ASC_WARN_CFG_MSW_RECOVER 0x0040 | 443 | #define ASC_WARN_CFG_MSW_RECOVER 0x0040 |
1341 | #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 | ||
1342 | 444 | ||
1343 | /* | 445 | /* |
1344 | * Error code values are set in ASC_DVC_VAR 'err_code'. | 446 | * Error code values are set in {ASC/ADV}_DVC_VAR 'err_code'. |
1345 | */ | 447 | */ |
1346 | #define ASC_IERR_WRITE_EEPROM 0x0001 | 448 | #define ASC_IERR_NO_CARRIER 0x0001 /* No more carrier memory */ |
1347 | #define ASC_IERR_MCODE_CHKSUM 0x0002 | 449 | #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */ |
1348 | #define ASC_IERR_SET_PC_ADDR 0x0004 | 450 | #define ASC_IERR_SET_PC_ADDR 0x0004 |
1349 | #define ASC_IERR_START_STOP_CHIP 0x0008 | 451 | #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */ |
1350 | #define ASC_IERR_IRQ_NO 0x0010 | 452 | #define ASC_IERR_ILLEGAL_CONNECTION 0x0010 /* Illegal cable connection */ |
1351 | #define ASC_IERR_SET_IRQ_NO 0x0020 | 453 | #define ASC_IERR_SINGLE_END_DEVICE 0x0020 /* SE device on DIFF bus */ |
1352 | #define ASC_IERR_CHIP_VERSION 0x0040 | 454 | #define ASC_IERR_REVERSED_CABLE 0x0040 /* Narrow flat cable reversed */ |
1353 | #define ASC_IERR_SET_SCSI_ID 0x0080 | 455 | #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */ |
1354 | #define ASC_IERR_GET_PHY_ADDR 0x0100 | 456 | #define ASC_IERR_HVD_DEVICE 0x0100 /* HVD device on LVD port */ |
1355 | #define ASC_IERR_BAD_SIGNATURE 0x0200 | 457 | #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */ |
1356 | #define ASC_IERR_NO_BUS_TYPE 0x0400 | 458 | #define ASC_IERR_NO_BUS_TYPE 0x0400 |
1357 | #define ASC_IERR_SCAM 0x0800 | 459 | #define ASC_IERR_BIST_PRE_TEST 0x0800 /* BIST pre-test error */ |
1358 | #define ASC_IERR_SET_SDTR 0x1000 | 460 | #define ASC_IERR_BIST_RAM_TEST 0x1000 /* BIST RAM test error */ |
1359 | #define ASC_IERR_RW_LRAM 0x8000 | 461 | #define ASC_IERR_BAD_CHIPTYPE 0x2000 /* Invalid chip_type setting */ |
1360 | 462 | ||
1361 | #define ASC_DEF_IRQ_NO 10 | ||
1362 | #define ASC_MAX_IRQ_NO 15 | ||
1363 | #define ASC_MIN_IRQ_NO 10 | ||
1364 | #define ASC_MIN_REMAIN_Q (0x02) | ||
1365 | #define ASC_DEF_MAX_TOTAL_QNG (0xF0) | 463 | #define ASC_DEF_MAX_TOTAL_QNG (0xF0) |
1366 | #define ASC_MIN_TAG_Q_PER_DVC (0x04) | 464 | #define ASC_MIN_TAG_Q_PER_DVC (0x04) |
1367 | #define ASC_DEF_TAG_Q_PER_DVC (0x04) | 465 | #define ASC_MIN_FREE_Q (0x02) |
1368 | #define ASC_MIN_FREE_Q ASC_MIN_REMAIN_Q | ||
1369 | #define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q)) | 466 | #define ASC_MIN_TOTAL_QNG ((ASC_MAX_SG_QUEUE)+(ASC_MIN_FREE_Q)) |
1370 | #define ASC_MAX_TOTAL_QNG 240 | 467 | #define ASC_MAX_TOTAL_QNG 240 |
1371 | #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16 | 468 | #define ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG 16 |
1372 | #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8 | 469 | #define ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG 8 |
1373 | #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20 | 470 | #define ASC_MAX_PCI_INRAM_TOTAL_QNG 20 |
1374 | #define ASC_MAX_INRAM_TAG_QNG 16 | 471 | #define ASC_MAX_INRAM_TAG_QNG 16 |
1375 | #define ASC_IOADR_TABLE_MAX_IX 11 | ||
1376 | #define ASC_IOADR_GAP 0x10 | 472 | #define ASC_IOADR_GAP 0x10 |
1377 | #define ASC_SEARCH_IOP_GAP 0x10 | ||
1378 | #define ASC_MIN_IOP_ADDR (PortAddr)0x0100 | ||
1379 | #define ASC_MAX_IOP_ADDR (PortAddr)0x3F0 | ||
1380 | #define ASC_IOADR_1 (PortAddr)0x0110 | ||
1381 | #define ASC_IOADR_2 (PortAddr)0x0130 | ||
1382 | #define ASC_IOADR_3 (PortAddr)0x0150 | ||
1383 | #define ASC_IOADR_4 (PortAddr)0x0190 | ||
1384 | #define ASC_IOADR_5 (PortAddr)0x0210 | ||
1385 | #define ASC_IOADR_6 (PortAddr)0x0230 | ||
1386 | #define ASC_IOADR_7 (PortAddr)0x0250 | ||
1387 | #define ASC_IOADR_8 (PortAddr)0x0330 | ||
1388 | #define ASC_IOADR_DEF ASC_IOADR_8 | ||
1389 | #define ASC_LIB_SCSIQ_WK_SP 256 | ||
1390 | #define ASC_MAX_SYN_XFER_NO 16 | ||
1391 | #define ASC_SYN_MAX_OFFSET 0x0F | 473 | #define ASC_SYN_MAX_OFFSET 0x0F |
1392 | #define ASC_DEF_SDTR_OFFSET 0x0F | 474 | #define ASC_DEF_SDTR_OFFSET 0x0F |
1393 | #define ASC_DEF_SDTR_INDEX 0x00 | ||
1394 | #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02 | 475 | #define ASC_SDTR_ULTRA_PCI_10MB_INDEX 0x02 |
1395 | #define SYN_XFER_NS_0 25 | 476 | #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41 |
1396 | #define SYN_XFER_NS_1 30 | 477 | |
1397 | #define SYN_XFER_NS_2 35 | 478 | /* The narrow chip only supports a limited selection of transfer rates. |
1398 | #define SYN_XFER_NS_3 40 | 479 | * These are encoded in the range 0..7 or 0..15 depending whether the chip |
1399 | #define SYN_XFER_NS_4 50 | 480 | * is Ultra-capable or not. These tables let us convert from one to the other. |
1400 | #define SYN_XFER_NS_5 60 | 481 | */ |
1401 | #define SYN_XFER_NS_6 70 | 482 | static const unsigned char asc_syn_xfer_period[8] = { |
1402 | #define SYN_XFER_NS_7 85 | 483 | 25, 30, 35, 40, 50, 60, 70, 85 |
1403 | #define SYN_ULTRA_XFER_NS_0 12 | 484 | }; |
1404 | #define SYN_ULTRA_XFER_NS_1 19 | 485 | |
1405 | #define SYN_ULTRA_XFER_NS_2 25 | 486 | static const unsigned char asc_syn_ultra_xfer_period[16] = { |
1406 | #define SYN_ULTRA_XFER_NS_3 32 | 487 | 12, 19, 25, 32, 38, 44, 50, 57, 63, 69, 75, 82, 88, 94, 100, 107 |
1407 | #define SYN_ULTRA_XFER_NS_4 38 | 488 | }; |
1408 | #define SYN_ULTRA_XFER_NS_5 44 | ||
1409 | #define SYN_ULTRA_XFER_NS_6 50 | ||
1410 | #define SYN_ULTRA_XFER_NS_7 57 | ||
1411 | #define SYN_ULTRA_XFER_NS_8 63 | ||
1412 | #define SYN_ULTRA_XFER_NS_9 69 | ||
1413 | #define SYN_ULTRA_XFER_NS_10 75 | ||
1414 | #define SYN_ULTRA_XFER_NS_11 82 | ||
1415 | #define SYN_ULTRA_XFER_NS_12 88 | ||
1416 | #define SYN_ULTRA_XFER_NS_13 94 | ||
1417 | #define SYN_ULTRA_XFER_NS_14 100 | ||
1418 | #define SYN_ULTRA_XFER_NS_15 107 | ||
1419 | 489 | ||
1420 | typedef struct ext_msg { | 490 | typedef struct ext_msg { |
1421 | uchar msg_type; | 491 | uchar msg_type; |
@@ -1456,22 +526,16 @@ typedef struct asc_dvc_cfg { | |||
1456 | uchar isa_dma_speed; | 526 | uchar isa_dma_speed; |
1457 | uchar isa_dma_channel; | 527 | uchar isa_dma_channel; |
1458 | uchar chip_version; | 528 | uchar chip_version; |
1459 | ushort lib_serial_no; | ||
1460 | ushort lib_version; | ||
1461 | ushort mcode_date; | 529 | ushort mcode_date; |
1462 | ushort mcode_version; | 530 | ushort mcode_version; |
1463 | uchar max_tag_qng[ASC_MAX_TID + 1]; | 531 | uchar max_tag_qng[ASC_MAX_TID + 1]; |
1464 | uchar *overrun_buf; | ||
1465 | uchar sdtr_period_offset[ASC_MAX_TID + 1]; | 532 | uchar sdtr_period_offset[ASC_MAX_TID + 1]; |
1466 | ushort pci_slot_info; | ||
1467 | uchar adapter_info[6]; | 533 | uchar adapter_info[6]; |
1468 | struct device *dev; | ||
1469 | } ASC_DVC_CFG; | 534 | } ASC_DVC_CFG; |
1470 | 535 | ||
1471 | #define ASC_DEF_DVC_CNTL 0xFFFF | 536 | #define ASC_DEF_DVC_CNTL 0xFFFF |
1472 | #define ASC_DEF_CHIP_SCSI_ID 7 | 537 | #define ASC_DEF_CHIP_SCSI_ID 7 |
1473 | #define ASC_DEF_ISA_DMA_SPEED 4 | 538 | #define ASC_DEF_ISA_DMA_SPEED 4 |
1474 | #define ASC_INIT_STATE_NULL 0x0000 | ||
1475 | #define ASC_INIT_STATE_BEG_GET_CFG 0x0001 | 539 | #define ASC_INIT_STATE_BEG_GET_CFG 0x0001 |
1476 | #define ASC_INIT_STATE_END_GET_CFG 0x0002 | 540 | #define ASC_INIT_STATE_END_GET_CFG 0x0002 |
1477 | #define ASC_INIT_STATE_BEG_SET_CFG 0x0004 | 541 | #define ASC_INIT_STATE_BEG_SET_CFG 0x0004 |
@@ -1484,43 +548,39 @@ typedef struct asc_dvc_cfg { | |||
1484 | #define ASC_INIT_STATE_WITHOUT_EEP 0x8000 | 548 | #define ASC_INIT_STATE_WITHOUT_EEP 0x8000 |
1485 | #define ASC_BUG_FIX_IF_NOT_DWB 0x0001 | 549 | #define ASC_BUG_FIX_IF_NOT_DWB 0x0001 |
1486 | #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002 | 550 | #define ASC_BUG_FIX_ASYN_USE_SYN 0x0002 |
1487 | #define ASYN_SDTR_DATA_FIX_PCI_REV_AB 0x41 | ||
1488 | #define ASC_MIN_TAGGED_CMD 7 | 551 | #define ASC_MIN_TAGGED_CMD 7 |
1489 | #define ASC_MAX_SCSI_RESET_WAIT 30 | 552 | #define ASC_MAX_SCSI_RESET_WAIT 30 |
553 | #define ASC_OVERRUN_BSIZE 64 | ||
1490 | 554 | ||
1491 | struct asc_dvc_var; /* Forward Declaration. */ | 555 | struct asc_dvc_var; /* Forward Declaration. */ |
1492 | 556 | ||
1493 | typedef void (*ASC_ISR_CALLBACK) (struct asc_dvc_var *, ASC_QDONE_INFO *); | ||
1494 | typedef int (*ASC_EXE_CALLBACK) (struct asc_dvc_var *, ASC_SCSI_Q *); | ||
1495 | |||
1496 | typedef struct asc_dvc_var { | 557 | typedef struct asc_dvc_var { |
1497 | PortAddr iop_base; | 558 | PortAddr iop_base; |
1498 | ushort err_code; | 559 | ushort err_code; |
1499 | ushort dvc_cntl; | 560 | ushort dvc_cntl; |
1500 | ushort bug_fix_cntl; | 561 | ushort bug_fix_cntl; |
1501 | ushort bus_type; | 562 | ushort bus_type; |
1502 | ASC_ISR_CALLBACK isr_callback; | ||
1503 | ASC_EXE_CALLBACK exe_callback; | ||
1504 | ASC_SCSI_BIT_ID_TYPE init_sdtr; | 563 | ASC_SCSI_BIT_ID_TYPE init_sdtr; |
1505 | ASC_SCSI_BIT_ID_TYPE sdtr_done; | 564 | ASC_SCSI_BIT_ID_TYPE sdtr_done; |
1506 | ASC_SCSI_BIT_ID_TYPE use_tagged_qng; | 565 | ASC_SCSI_BIT_ID_TYPE use_tagged_qng; |
1507 | ASC_SCSI_BIT_ID_TYPE unit_not_ready; | 566 | ASC_SCSI_BIT_ID_TYPE unit_not_ready; |
1508 | ASC_SCSI_BIT_ID_TYPE queue_full_or_busy; | 567 | ASC_SCSI_BIT_ID_TYPE queue_full_or_busy; |
1509 | ASC_SCSI_BIT_ID_TYPE start_motor; | 568 | ASC_SCSI_BIT_ID_TYPE start_motor; |
569 | uchar overrun_buf[ASC_OVERRUN_BSIZE] __aligned(8); | ||
570 | dma_addr_t overrun_dma; | ||
1510 | uchar scsi_reset_wait; | 571 | uchar scsi_reset_wait; |
1511 | uchar chip_no; | 572 | uchar chip_no; |
1512 | char is_in_int; | 573 | char is_in_int; |
1513 | uchar max_total_qng; | 574 | uchar max_total_qng; |
1514 | uchar cur_total_qng; | 575 | uchar cur_total_qng; |
1515 | uchar in_critical_cnt; | 576 | uchar in_critical_cnt; |
1516 | uchar irq_no; | ||
1517 | uchar last_q_shortage; | 577 | uchar last_q_shortage; |
1518 | ushort init_state; | 578 | ushort init_state; |
1519 | uchar cur_dvc_qng[ASC_MAX_TID + 1]; | 579 | uchar cur_dvc_qng[ASC_MAX_TID + 1]; |
1520 | uchar max_dvc_qng[ASC_MAX_TID + 1]; | 580 | uchar max_dvc_qng[ASC_MAX_TID + 1]; |
1521 | ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1]; | 581 | ASC_SCSI_Q *scsiq_busy_head[ASC_MAX_TID + 1]; |
1522 | ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1]; | 582 | ASC_SCSI_Q *scsiq_busy_tail[ASC_MAX_TID + 1]; |
1523 | uchar sdtr_period_tbl[ASC_MAX_SYN_XFER_NO]; | 583 | const uchar *sdtr_period_tbl; |
1524 | ASC_DVC_CFG *cfg; | 584 | ASC_DVC_CFG *cfg; |
1525 | ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always; | 585 | ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer_always; |
1526 | char redo_scam; | 586 | char redo_scam; |
@@ -1529,9 +589,11 @@ typedef struct asc_dvc_var { | |||
1529 | ASC_DCNT max_dma_count; | 589 | ASC_DCNT max_dma_count; |
1530 | ASC_SCSI_BIT_ID_TYPE no_scam; | 590 | ASC_SCSI_BIT_ID_TYPE no_scam; |
1531 | ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer; | 591 | ASC_SCSI_BIT_ID_TYPE pci_fix_asyn_xfer; |
592 | uchar min_sdtr_index; | ||
1532 | uchar max_sdtr_index; | 593 | uchar max_sdtr_index; |
1533 | uchar host_init_sdtr_index; | ||
1534 | struct asc_board *drv_ptr; | 594 | struct asc_board *drv_ptr; |
595 | int ptr_map_count; | ||
596 | void **ptr_map; | ||
1535 | ASC_DCNT uc_break; | 597 | ASC_DCNT uc_break; |
1536 | } ASC_DVC_VAR; | 598 | } ASC_DVC_VAR; |
1537 | 599 | ||
@@ -1568,12 +630,7 @@ typedef struct asc_cap_info_array { | |||
1568 | #define ASC_EEP_MAX_DVC_ADDR_VL 15 | 630 | #define ASC_EEP_MAX_DVC_ADDR_VL 15 |
1569 | #define ASC_EEP_DVC_CFG_BEG 32 | 631 | #define ASC_EEP_DVC_CFG_BEG 32 |
1570 | #define ASC_EEP_MAX_DVC_ADDR 45 | 632 | #define ASC_EEP_MAX_DVC_ADDR 45 |
1571 | #define ASC_EEP_DEFINED_WORDS 10 | ||
1572 | #define ASC_EEP_MAX_ADDR 63 | ||
1573 | #define ASC_EEP_RES_WORDS 0 | ||
1574 | #define ASC_EEP_MAX_RETRY 20 | 633 | #define ASC_EEP_MAX_RETRY 20 |
1575 | #define ASC_MAX_INIT_BUSY_RETRY 8 | ||
1576 | #define ASC_EEP_ISA_PNP_WSIZE 16 | ||
1577 | 634 | ||
1578 | /* | 635 | /* |
1579 | * These macros keep the chip SCSI id and ISA DMA speed | 636 | * These macros keep the chip SCSI id and ISA DMA speed |
@@ -1609,17 +666,10 @@ typedef struct asceep_config { | |||
1609 | ushort chksum; | 666 | ushort chksum; |
1610 | } ASCEEP_CONFIG; | 667 | } ASCEEP_CONFIG; |
1611 | 668 | ||
1612 | #define ASC_PCI_CFG_LSW_SCSI_PARITY 0x0800 | ||
1613 | #define ASC_PCI_CFG_LSW_BURST_MODE 0x0080 | ||
1614 | #define ASC_PCI_CFG_LSW_INTR_ABLE 0x0020 | ||
1615 | |||
1616 | #define ASC_EEP_CMD_READ 0x80 | 669 | #define ASC_EEP_CMD_READ 0x80 |
1617 | #define ASC_EEP_CMD_WRITE 0x40 | 670 | #define ASC_EEP_CMD_WRITE 0x40 |
1618 | #define ASC_EEP_CMD_WRITE_ABLE 0x30 | 671 | #define ASC_EEP_CMD_WRITE_ABLE 0x30 |
1619 | #define ASC_EEP_CMD_WRITE_DISABLE 0x00 | 672 | #define ASC_EEP_CMD_WRITE_DISABLE 0x00 |
1620 | #define ASC_OVERRUN_BSIZE 0x00000048UL | ||
1621 | #define ASC_CTRL_BREAK_ONCE 0x0001 | ||
1622 | #define ASC_CTRL_BREAK_STAY_IDLE 0x0002 | ||
1623 | #define ASCV_MSGOUT_BEG 0x0000 | 673 | #define ASCV_MSGOUT_BEG 0x0000 |
1624 | #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3) | 674 | #define ASCV_MSGOUT_SDTR_PERIOD (ASCV_MSGOUT_BEG+3) |
1625 | #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4) | 675 | #define ASCV_MSGOUT_SDTR_OFFSET (ASCV_MSGOUT_BEG+4) |
@@ -1796,16 +846,9 @@ typedef struct asceep_config { | |||
1796 | #define ASC_1000_ID0W 0x04C1 | 846 | #define ASC_1000_ID0W 0x04C1 |
1797 | #define ASC_1000_ID0W_FIX 0x00C1 | 847 | #define ASC_1000_ID0W_FIX 0x00C1 |
1798 | #define ASC_1000_ID1B 0x25 | 848 | #define ASC_1000_ID1B 0x25 |
1799 | #define ASC_EISA_BIG_IOP_GAP (0x1C30-0x0C50) | ||
1800 | #define ASC_EISA_SMALL_IOP_GAP (0x0020) | ||
1801 | #define ASC_EISA_MIN_IOP_ADDR (0x0C30) | ||
1802 | #define ASC_EISA_MAX_IOP_ADDR (0xFC50) | ||
1803 | #define ASC_EISA_REV_IOP_MASK (0x0C83) | 849 | #define ASC_EISA_REV_IOP_MASK (0x0C83) |
1804 | #define ASC_EISA_PID_IOP_MASK (0x0C80) | ||
1805 | #define ASC_EISA_CFG_IOP_MASK (0x0C86) | 850 | #define ASC_EISA_CFG_IOP_MASK (0x0C86) |
1806 | #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000) | 851 | #define ASC_GET_EISA_SLOT(iop) (PortAddr)((iop) & 0xF000) |
1807 | #define ASC_EISA_ID_740 0x01745004UL | ||
1808 | #define ASC_EISA_ID_750 0x01755004UL | ||
1809 | #define INS_HALTINT (ushort)0x6281 | 852 | #define INS_HALTINT (ushort)0x6281 |
1810 | #define INS_HALT (ushort)0x6280 | 853 | #define INS_HALT (ushort)0x6280 |
1811 | #define INS_SINT (ushort)0x6200 | 854 | #define INS_SINT (ushort)0x6200 |
@@ -1828,11 +871,10 @@ typedef struct asc_mc_saved { | |||
1828 | #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B) | 871 | #define AscGetRiscVarDoneQTail(port) AscReadLramByte((port), ASCV_DONENEXT_B) |
1829 | #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val) | 872 | #define AscPutRiscVarFreeQHead(port, val) AscWriteLramByte((port), ASCV_NEXTRDY_B, val) |
1830 | #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val) | 873 | #define AscPutRiscVarDoneQTail(port, val) AscWriteLramByte((port), ASCV_DONENEXT_B, val) |
1831 | #define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data)); | 874 | #define AscPutMCodeSDTRDoneAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id), (data)) |
1832 | #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id)); | 875 | #define AscGetMCodeSDTRDoneAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DONE_BEG+(ushort)id)) |
1833 | #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data); | 876 | #define AscPutMCodeInitSDTRAtID(port, id, data) AscWriteLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id), data) |
1834 | #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id)); | 877 | #define AscGetMCodeInitSDTRAtID(port, id) AscReadLramByte((port), (ushort)((ushort)ASCV_SDTR_DATA_BEG+(ushort)id)) |
1835 | #define AscSynIndexToPeriod(index) (uchar)(asc_dvc->sdtr_period_tbl[ (index) ]) | ||
1836 | #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE) | 878 | #define AscGetChipSignatureByte(port) (uchar)inp((port)+IOP_SIG_BYTE) |
1837 | #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD) | 879 | #define AscGetChipSignatureWord(port) (ushort)inpw((port)+IOP_SIG_WORD) |
1838 | #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION) | 880 | #define AscGetChipVerNo(port) (uchar)inp((port)+IOP_VERSION) |
@@ -1887,125 +929,6 @@ typedef struct asc_mc_saved { | |||
1887 | #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID) | 929 | #define AscReadChipDvcID(port) (uchar)inp((port)+IOP_REG_ID) |
1888 | #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data) | 930 | #define AscWriteChipDvcID(port, data) outp((port)+IOP_REG_ID, data) |
1889 | 931 | ||
1890 | static int AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg); | ||
1891 | static int AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg); | ||
1892 | static void AscWaitEEPRead(void); | ||
1893 | static void AscWaitEEPWrite(void); | ||
1894 | static ushort AscReadEEPWord(PortAddr, uchar); | ||
1895 | static ushort AscWriteEEPWord(PortAddr, uchar, ushort); | ||
1896 | static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort); | ||
1897 | static int AscSetEEPConfigOnce(PortAddr, ASCEEP_CONFIG *, ushort); | ||
1898 | static int AscSetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort); | ||
1899 | static int AscStartChip(PortAddr); | ||
1900 | static int AscStopChip(PortAddr); | ||
1901 | static void AscSetChipIH(PortAddr, ushort); | ||
1902 | static int AscIsChipHalted(PortAddr); | ||
1903 | static void AscAckInterrupt(PortAddr); | ||
1904 | static void AscDisableInterrupt(PortAddr); | ||
1905 | static void AscEnableInterrupt(PortAddr); | ||
1906 | static void AscSetBank(PortAddr, uchar); | ||
1907 | static int AscResetChipAndScsiBus(ASC_DVC_VAR *); | ||
1908 | #ifdef CONFIG_ISA | ||
1909 | static ushort AscGetIsaDmaChannel(PortAddr); | ||
1910 | static ushort AscSetIsaDmaChannel(PortAddr, ushort); | ||
1911 | static uchar AscSetIsaDmaSpeed(PortAddr, uchar); | ||
1912 | static uchar AscGetIsaDmaSpeed(PortAddr); | ||
1913 | #endif /* CONFIG_ISA */ | ||
1914 | static uchar AscReadLramByte(PortAddr, ushort); | ||
1915 | static ushort AscReadLramWord(PortAddr, ushort); | ||
1916 | #if CC_VERY_LONG_SG_LIST | ||
1917 | static ASC_DCNT AscReadLramDWord(PortAddr, ushort); | ||
1918 | #endif /* CC_VERY_LONG_SG_LIST */ | ||
1919 | static void AscWriteLramWord(PortAddr, ushort, ushort); | ||
1920 | static void AscWriteLramByte(PortAddr, ushort, uchar); | ||
1921 | static ASC_DCNT AscMemSumLramWord(PortAddr, ushort, int); | ||
1922 | static void AscMemWordSetLram(PortAddr, ushort, ushort, int); | ||
1923 | static void AscMemWordCopyPtrToLram(PortAddr, ushort, uchar *, int); | ||
1924 | static void AscMemDWordCopyPtrToLram(PortAddr, ushort, uchar *, int); | ||
1925 | static void AscMemWordCopyPtrFromLram(PortAddr, ushort, uchar *, int); | ||
1926 | static ushort AscInitAscDvcVar(ASC_DVC_VAR *); | ||
1927 | static ushort AscInitFromEEP(ASC_DVC_VAR *); | ||
1928 | static ushort AscInitFromAscDvcVar(ASC_DVC_VAR *); | ||
1929 | static ushort AscInitMicroCodeVar(ASC_DVC_VAR *); | ||
1930 | static int AscTestExternalLram(ASC_DVC_VAR *); | ||
1931 | static uchar AscMsgOutSDTR(ASC_DVC_VAR *, uchar, uchar); | ||
1932 | static uchar AscCalSDTRData(ASC_DVC_VAR *, uchar, uchar); | ||
1933 | static void AscSetChipSDTR(PortAddr, uchar, uchar); | ||
1934 | static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *, uchar); | ||
1935 | static uchar AscAllocFreeQueue(PortAddr, uchar); | ||
1936 | static uchar AscAllocMultipleFreeQueue(PortAddr, uchar, uchar); | ||
1937 | static int AscHostReqRiscHalt(PortAddr); | ||
1938 | static int AscStopQueueExe(PortAddr); | ||
1939 | static int AscSendScsiQueue(ASC_DVC_VAR *, | ||
1940 | ASC_SCSI_Q *scsiq, uchar n_q_required); | ||
1941 | static int AscPutReadyQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar); | ||
1942 | static int AscPutReadySgListQueue(ASC_DVC_VAR *, ASC_SCSI_Q *, uchar); | ||
1943 | static int AscSetChipSynRegAtID(PortAddr, uchar, uchar); | ||
1944 | static int AscSetRunChipSynRegAtID(PortAddr, uchar, uchar); | ||
1945 | static ushort AscInitLram(ASC_DVC_VAR *); | ||
1946 | static ushort AscInitQLinkVar(ASC_DVC_VAR *); | ||
1947 | static int AscSetLibErrorCode(ASC_DVC_VAR *, ushort); | ||
1948 | static int AscIsrChipHalted(ASC_DVC_VAR *); | ||
1949 | static uchar _AscCopyLramScsiDoneQ(PortAddr, ushort, | ||
1950 | ASC_QDONE_INFO *, ASC_DCNT); | ||
1951 | static int AscIsrQDone(ASC_DVC_VAR *); | ||
1952 | static int AscCompareString(uchar *, uchar *, int); | ||
1953 | #ifdef CONFIG_ISA | ||
1954 | static ushort AscGetEisaChipCfg(PortAddr); | ||
1955 | static ASC_DCNT AscGetEisaProductID(PortAddr); | ||
1956 | static PortAddr AscSearchIOPortAddrEISA(PortAddr); | ||
1957 | static PortAddr AscSearchIOPortAddr11(PortAddr); | ||
1958 | static PortAddr AscSearchIOPortAddr(PortAddr, ushort); | ||
1959 | static void AscSetISAPNPWaitForKey(void); | ||
1960 | #endif /* CONFIG_ISA */ | ||
1961 | static uchar AscGetChipScsiCtrl(PortAddr); | ||
1962 | static uchar AscSetChipScsiID(PortAddr, uchar); | ||
1963 | static uchar AscGetChipVersion(PortAddr, ushort); | ||
1964 | static ushort AscGetChipBusType(PortAddr); | ||
1965 | static ASC_DCNT AscLoadMicroCode(PortAddr, ushort, uchar *, ushort); | ||
1966 | static int AscFindSignature(PortAddr); | ||
1967 | static void AscToggleIRQAct(PortAddr); | ||
1968 | static uchar AscGetChipIRQ(PortAddr, ushort); | ||
1969 | static uchar AscSetChipIRQ(PortAddr, uchar, ushort); | ||
1970 | static ushort AscGetChipBiosAddress(PortAddr, ushort); | ||
1971 | static inline ulong DvcEnterCritical(void); | ||
1972 | static inline void DvcLeaveCritical(ulong); | ||
1973 | #ifdef CONFIG_PCI | ||
1974 | static uchar DvcReadPCIConfigByte(ASC_DVC_VAR *, ushort); | ||
1975 | static void DvcWritePCIConfigByte(ASC_DVC_VAR *, ushort, uchar); | ||
1976 | #endif /* CONFIG_PCI */ | ||
1977 | static ushort AscGetChipBiosAddress(PortAddr, ushort); | ||
1978 | static void DvcSleepMilliSecond(ASC_DCNT); | ||
1979 | static void DvcDelayNanoSecond(ASC_DVC_VAR *, ASC_DCNT); | ||
1980 | static void DvcPutScsiQ(PortAddr, ushort, uchar *, int); | ||
1981 | static void DvcGetQinfo(PortAddr, ushort, uchar *, int); | ||
1982 | static ushort AscInitGetConfig(ASC_DVC_VAR *); | ||
1983 | static ushort AscInitSetConfig(ASC_DVC_VAR *); | ||
1984 | static ushort AscInitAsc1000Driver(ASC_DVC_VAR *); | ||
1985 | static void AscAsyncFix(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *); | ||
1986 | static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *); | ||
1987 | static void AscInquiryHandling(ASC_DVC_VAR *, uchar, ASC_SCSI_INQUIRY *); | ||
1988 | static int AscExeScsiQueue(ASC_DVC_VAR *, ASC_SCSI_Q *); | ||
1989 | static int AscISR(ASC_DVC_VAR *); | ||
1990 | static uint AscGetNumOfFreeQueue(ASC_DVC_VAR *, uchar, uchar); | ||
1991 | static int AscSgListToQueue(int); | ||
1992 | #ifdef CONFIG_ISA | ||
1993 | static void AscEnableIsaDma(uchar); | ||
1994 | #endif /* CONFIG_ISA */ | ||
1995 | static ASC_DCNT AscGetMaxDmaCount(ushort); | ||
1996 | static const char *advansys_info(struct Scsi_Host *shost); | ||
1997 | |||
1998 | /* | ||
1999 | * --- Adv Library Constants and Macros | ||
2000 | */ | ||
2001 | |||
2002 | #define ADV_LIB_VERSION_MAJOR 5 | ||
2003 | #define ADV_LIB_VERSION_MINOR 14 | ||
2004 | |||
2005 | /* | ||
2006 | * Define Adv Library required special types. | ||
2007 | */ | ||
2008 | |||
2009 | /* | 932 | /* |
2010 | * Portable Data Types | 933 | * Portable Data Types |
2011 | * | 934 | * |
@@ -2045,12 +968,6 @@ static const char *advansys_info(struct Scsi_Host *shost); | |||
2045 | #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15) | 968 | #define ADV_CARRIER_COUNT (ASC_DEF_MAX_HOST_QNG + 15) |
2046 | 969 | ||
2047 | /* | 970 | /* |
2048 | * For wide boards a CDB length maximum of 16 bytes | ||
2049 | * is supported. | ||
2050 | */ | ||
2051 | #define ADV_MAX_CDB_LEN 16 | ||
2052 | |||
2053 | /* | ||
2054 | * Define total number of simultaneous maximum element scatter-gather | 971 | * Define total number of simultaneous maximum element scatter-gather |
2055 | * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the | 972 | * request blocks per wide adapter. ASC_DEF_MAX_HOST_QNG (253) is the |
2056 | * maximum number of outstanding commands per wide host adapter. Each | 973 | * maximum number of outstanding commands per wide host adapter. Each |
@@ -2058,28 +975,14 @@ static const char *advansys_info(struct Scsi_Host *shost); | |||
2058 | * elements. Allow each command to have at least one ADV_SG_BLOCK structure. | 975 | * elements. Allow each command to have at least one ADV_SG_BLOCK structure. |
2059 | * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK | 976 | * This allows about 15 commands to have the maximum 17 ADV_SG_BLOCK |
2060 | * structures or 255 scatter-gather elements. | 977 | * structures or 255 scatter-gather elements. |
2061 | * | ||
2062 | */ | 978 | */ |
2063 | #define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG | 979 | #define ADV_TOT_SG_BLOCK ASC_DEF_MAX_HOST_QNG |
2064 | 980 | ||
2065 | /* | 981 | /* |
2066 | * Define Adv Library required maximum number of scatter-gather | 982 | * Define maximum number of scatter-gather elements per request. |
2067 | * elements per request. | ||
2068 | */ | 983 | */ |
2069 | #define ADV_MAX_SG_LIST 255 | 984 | #define ADV_MAX_SG_LIST 255 |
2070 | 985 | #define NO_OF_SG_PER_BLOCK 15 | |
2071 | /* Number of SG blocks needed. */ | ||
2072 | #define ADV_NUM_SG_BLOCK \ | ||
2073 | ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK) | ||
2074 | |||
2075 | /* Total contiguous memory needed for SG blocks. */ | ||
2076 | #define ADV_SG_TOTAL_MEM_SIZE \ | ||
2077 | (sizeof(ADV_SG_BLOCK) * ADV_NUM_SG_BLOCK) | ||
2078 | |||
2079 | #define ADV_PAGE_SIZE PAGE_SIZE | ||
2080 | |||
2081 | #define ADV_NUM_PAGE_CROSSING \ | ||
2082 | ((ADV_SG_TOTAL_MEM_SIZE + (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE) | ||
2083 | 986 | ||
2084 | #define ADV_EEP_DVC_CFG_BEGIN (0x00) | 987 | #define ADV_EEP_DVC_CFG_BEGIN (0x00) |
2085 | #define ADV_EEP_DVC_CFG_END (0x15) | 988 | #define ADV_EEP_DVC_CFG_END (0x15) |
@@ -2385,10 +1288,6 @@ typedef struct adveep_38C1600_config { | |||
2385 | * EEPROM Commands | 1288 | * EEPROM Commands |
2386 | */ | 1289 | */ |
2387 | #define ASC_EEP_CMD_DONE 0x0200 | 1290 | #define ASC_EEP_CMD_DONE 0x0200 |
2388 | #define ASC_EEP_CMD_DONE_ERR 0x0001 | ||
2389 | |||
2390 | /* cfg_word */ | ||
2391 | #define EEP_CFG_WORD_BIG_ENDIAN 0x8000 | ||
2392 | 1291 | ||
2393 | /* bios_ctrl */ | 1292 | /* bios_ctrl */ |
2394 | #define BIOS_CTRL_BIOS 0x0001 | 1293 | #define BIOS_CTRL_BIOS 0x0001 |
@@ -2405,10 +1304,8 @@ typedef struct adveep_38C1600_config { | |||
2405 | #define BIOS_CTRL_AIPP_DIS 0x2000 | 1304 | #define BIOS_CTRL_AIPP_DIS 0x2000 |
2406 | 1305 | ||
2407 | #define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */ | 1306 | #define ADV_3550_MEMSIZE 0x2000 /* 8 KB Internal Memory */ |
2408 | #define ADV_3550_IOLEN 0x40 /* I/O Port Range in bytes */ | ||
2409 | 1307 | ||
2410 | #define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */ | 1308 | #define ADV_38C0800_MEMSIZE 0x4000 /* 16 KB Internal Memory */ |
2411 | #define ADV_38C0800_IOLEN 0x100 /* I/O Port Range in bytes */ | ||
2412 | 1309 | ||
2413 | /* | 1310 | /* |
2414 | * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is | 1311 | * XXX - Since ASC38C1600 Rev.3 has a local RAM failure issue, there is |
@@ -2418,8 +1315,6 @@ typedef struct adveep_38C1600_config { | |||
2418 | * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory * | 1315 | * #define ADV_38C1600_MEMSIZE 0x8000L * 32 KB Internal Memory * |
2419 | */ | 1316 | */ |
2420 | #define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */ | 1317 | #define ADV_38C1600_MEMSIZE 0x4000 /* 16 KB Internal Memory */ |
2421 | #define ADV_38C1600_IOLEN 0x100 /* I/O Port Range 256 bytes */ | ||
2422 | #define ADV_38C1600_MEMLEN 0x1000 /* Memory Range 4KB bytes */ | ||
2423 | 1318 | ||
2424 | /* | 1319 | /* |
2425 | * Byte I/O register address from base of 'iop_base'. | 1320 | * Byte I/O register address from base of 'iop_base'. |
@@ -2549,8 +1444,6 @@ typedef struct adveep_38C1600_config { | |||
2549 | #define ADV_CHIP_ID_BYTE 0x25 | 1444 | #define ADV_CHIP_ID_BYTE 0x25 |
2550 | #define ADV_CHIP_ID_WORD 0x04C1 | 1445 | #define ADV_CHIP_ID_WORD 0x04C1 |
2551 | 1446 | ||
2552 | #define ADV_SC_SCSI_BUS_RESET 0x2000 | ||
2553 | |||
2554 | #define ADV_INTR_ENABLE_HOST_INTR 0x01 | 1447 | #define ADV_INTR_ENABLE_HOST_INTR 0x01 |
2555 | #define ADV_INTR_ENABLE_SEL_INTR 0x02 | 1448 | #define ADV_INTR_ENABLE_SEL_INTR 0x02 |
2556 | #define ADV_INTR_ENABLE_DPR_INTR 0x04 | 1449 | #define ADV_INTR_ENABLE_DPR_INTR 0x04 |
@@ -2590,8 +1483,6 @@ typedef struct adveep_38C1600_config { | |||
2590 | #define ADV_TICKLE_B 0x02 | 1483 | #define ADV_TICKLE_B 0x02 |
2591 | #define ADV_TICKLE_C 0x03 | 1484 | #define ADV_TICKLE_C 0x03 |
2592 | 1485 | ||
2593 | #define ADV_SCSI_CTRL_RSTOUT 0x2000 | ||
2594 | |||
2595 | #define AdvIsIntPending(port) \ | 1486 | #define AdvIsIntPending(port) \ |
2596 | (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR) | 1487 | (AdvReadWordRegister(port, IOPW_CTRL_REG) & ADV_CTRL_REG_HOST_INTR) |
2597 | 1488 | ||
@@ -2744,14 +1635,11 @@ typedef struct adveep_38C1600_config { | |||
2744 | */ | 1635 | */ |
2745 | #define INTAB 0x01 | 1636 | #define INTAB 0x01 |
2746 | 1637 | ||
2747 | /* a_advlib.h */ | ||
2748 | |||
2749 | /* | 1638 | /* |
2750 | * Adv Library Status Definitions | 1639 | * Adv Library Status Definitions |
2751 | */ | 1640 | */ |
2752 | #define ADV_TRUE 1 | 1641 | #define ADV_TRUE 1 |
2753 | #define ADV_FALSE 0 | 1642 | #define ADV_FALSE 0 |
2754 | #define ADV_NOERROR 1 | ||
2755 | #define ADV_SUCCESS 1 | 1643 | #define ADV_SUCCESS 1 |
2756 | #define ADV_BUSY 0 | 1644 | #define ADV_BUSY 0 |
2757 | #define ADV_ERROR (-1) | 1645 | #define ADV_ERROR (-1) |
@@ -2762,31 +1650,12 @@ typedef struct adveep_38C1600_config { | |||
2762 | #define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */ | 1650 | #define ASC_WARN_BUSRESET_ERROR 0x0001 /* SCSI Bus Reset error */ |
2763 | #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */ | 1651 | #define ASC_WARN_EEPROM_CHKSUM 0x0002 /* EEP check sum error */ |
2764 | #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */ | 1652 | #define ASC_WARN_EEPROM_TERMINATION 0x0004 /* EEP termination bad field */ |
2765 | #define ASC_WARN_SET_PCI_CONFIG_SPACE 0x0080 /* PCI config space set error */ | ||
2766 | #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */ | 1653 | #define ASC_WARN_ERROR 0xFFFF /* ADV_ERROR return */ |
2767 | 1654 | ||
2768 | #define ADV_MAX_TID 15 /* max. target identifier */ | 1655 | #define ADV_MAX_TID 15 /* max. target identifier */ |
2769 | #define ADV_MAX_LUN 7 /* max. logical unit number */ | 1656 | #define ADV_MAX_LUN 7 /* max. logical unit number */ |
2770 | 1657 | ||
2771 | /* | 1658 | /* |
2772 | * Error code values are set in ADV_DVC_VAR 'err_code'. | ||
2773 | */ | ||
2774 | #define ASC_IERR_WRITE_EEPROM 0x0001 /* write EEPROM error */ | ||
2775 | #define ASC_IERR_MCODE_CHKSUM 0x0002 /* micro code check sum error */ | ||
2776 | #define ASC_IERR_NO_CARRIER 0x0004 /* No more carrier memory. */ | ||
2777 | #define ASC_IERR_START_STOP_CHIP 0x0008 /* start/stop chip failed */ | ||
2778 | #define ASC_IERR_CHIP_VERSION 0x0040 /* wrong chip version */ | ||
2779 | #define ASC_IERR_SET_SCSI_ID 0x0080 /* set SCSI ID failed */ | ||
2780 | #define ASC_IERR_HVD_DEVICE 0x0100 /* HVD attached to LVD connector. */ | ||
2781 | #define ASC_IERR_BAD_SIGNATURE 0x0200 /* signature not found */ | ||
2782 | #define ASC_IERR_ILLEGAL_CONNECTION 0x0400 /* Illegal cable connection */ | ||
2783 | #define ASC_IERR_SINGLE_END_DEVICE 0x0800 /* Single-end used w/differential */ | ||
2784 | #define ASC_IERR_REVERSED_CABLE 0x1000 /* Narrow flat cable reversed */ | ||
2785 | #define ASC_IERR_BIST_PRE_TEST 0x2000 /* BIST pre-test error */ | ||
2786 | #define ASC_IERR_BIST_RAM_TEST 0x4000 /* BIST RAM test error */ | ||
2787 | #define ASC_IERR_BAD_CHIPTYPE 0x8000 /* Invalid 'chip_type' setting. */ | ||
2788 | |||
2789 | /* | ||
2790 | * Fixed locations of microcode operating variables. | 1659 | * Fixed locations of microcode operating variables. |
2791 | */ | 1660 | */ |
2792 | #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */ | 1661 | #define ASC_MC_CODE_BEGIN_ADDR 0x0028 /* microcode start address */ |
@@ -2902,8 +1771,7 @@ typedef struct adv_carr_t { | |||
2902 | #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK) | 1771 | #define ASC_GET_CARRP(carrp) ((carrp) & ASC_NEXT_VPA_MASK) |
2903 | 1772 | ||
2904 | #define ADV_CARRIER_NUM_PAGE_CROSSING \ | 1773 | #define ADV_CARRIER_NUM_PAGE_CROSSING \ |
2905 | (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + \ | 1774 | (((ADV_CARRIER_COUNT * sizeof(ADV_CARR_T)) + (PAGE_SIZE - 1))/PAGE_SIZE) |
2906 | (ADV_PAGE_SIZE - 1))/ADV_PAGE_SIZE) | ||
2907 | 1775 | ||
2908 | #define ADV_CARRIER_BUFSIZE \ | 1776 | #define ADV_CARRIER_BUFSIZE \ |
2909 | ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T)) | 1777 | ((ADV_CARRIER_COUNT + ADV_CARRIER_NUM_PAGE_CROSSING) * sizeof(ADV_CARR_T)) |
@@ -2937,80 +1805,17 @@ typedef struct adv_dvc_cfg { | |||
2937 | ushort disc_enable; /* enable disconnection */ | 1805 | ushort disc_enable; /* enable disconnection */ |
2938 | uchar chip_version; /* chip version */ | 1806 | uchar chip_version; /* chip version */ |
2939 | uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */ | 1807 | uchar termination; /* Term. Ctrl. bits 6-5 of SCSI_CFG1 register */ |
2940 | ushort lib_version; /* Adv Library version number */ | ||
2941 | ushort control_flag; /* Microcode Control Flag */ | 1808 | ushort control_flag; /* Microcode Control Flag */ |
2942 | ushort mcode_date; /* Microcode date */ | 1809 | ushort mcode_date; /* Microcode date */ |
2943 | ushort mcode_version; /* Microcode version */ | 1810 | ushort mcode_version; /* Microcode version */ |
2944 | ushort pci_slot_info; /* high byte device/function number */ | ||
2945 | /* bits 7-3 device num., bits 2-0 function num. */ | ||
2946 | /* low byte bus num. */ | ||
2947 | ushort serial1; /* EEPROM serial number word 1 */ | 1811 | ushort serial1; /* EEPROM serial number word 1 */ |
2948 | ushort serial2; /* EEPROM serial number word 2 */ | 1812 | ushort serial2; /* EEPROM serial number word 2 */ |
2949 | ushort serial3; /* EEPROM serial number word 3 */ | 1813 | ushort serial3; /* EEPROM serial number word 3 */ |
2950 | struct device *dev; /* pointer to the pci dev structure for this board */ | ||
2951 | } ADV_DVC_CFG; | 1814 | } ADV_DVC_CFG; |
2952 | 1815 | ||
2953 | struct adv_dvc_var; | 1816 | struct adv_dvc_var; |
2954 | struct adv_scsi_req_q; | 1817 | struct adv_scsi_req_q; |
2955 | 1818 | ||
2956 | typedef void (*ADV_ISR_CALLBACK) | ||
2957 | (struct adv_dvc_var *, struct adv_scsi_req_q *); | ||
2958 | |||
2959 | typedef void (*ADV_ASYNC_CALLBACK) | ||
2960 | (struct adv_dvc_var *, uchar); | ||
2961 | |||
2962 | /* | ||
2963 | * Adapter operation variable structure. | ||
2964 | * | ||
2965 | * One structure is required per host adapter. | ||
2966 | * | ||
2967 | * Field naming convention: | ||
2968 | * | ||
2969 | * *_able indicates both whether a feature should be enabled or disabled | ||
2970 | * and whether a device isi capable of the feature. At initialization | ||
2971 | * this field may be set, but later if a device is found to be incapable | ||
2972 | * of the feature, the field is cleared. | ||
2973 | */ | ||
2974 | typedef struct adv_dvc_var { | ||
2975 | AdvPortAddr iop_base; /* I/O port address */ | ||
2976 | ushort err_code; /* fatal error code */ | ||
2977 | ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */ | ||
2978 | ADV_ISR_CALLBACK isr_callback; | ||
2979 | ADV_ASYNC_CALLBACK async_callback; | ||
2980 | ushort wdtr_able; /* try WDTR for a device */ | ||
2981 | ushort sdtr_able; /* try SDTR for a device */ | ||
2982 | ushort ultra_able; /* try SDTR Ultra speed for a device */ | ||
2983 | ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */ | ||
2984 | ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */ | ||
2985 | ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */ | ||
2986 | ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */ | ||
2987 | ushort tagqng_able; /* try tagged queuing with a device */ | ||
2988 | ushort ppr_able; /* PPR message capable per TID bitmask. */ | ||
2989 | uchar max_dvc_qng; /* maximum number of tagged commands per device */ | ||
2990 | ushort start_motor; /* start motor command allowed */ | ||
2991 | uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */ | ||
2992 | uchar chip_no; /* should be assigned by caller */ | ||
2993 | uchar max_host_qng; /* maximum number of Q'ed command allowed */ | ||
2994 | uchar irq_no; /* IRQ number */ | ||
2995 | ushort no_scam; /* scam_tolerant of EEPROM */ | ||
2996 | struct asc_board *drv_ptr; /* driver pointer to private structure */ | ||
2997 | uchar chip_scsi_id; /* chip SCSI target ID */ | ||
2998 | uchar chip_type; | ||
2999 | uchar bist_err_code; | ||
3000 | ADV_CARR_T *carrier_buf; | ||
3001 | ADV_CARR_T *carr_freelist; /* Carrier free list. */ | ||
3002 | ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */ | ||
3003 | ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */ | ||
3004 | ushort carr_pending_cnt; /* Count of pending carriers. */ | ||
3005 | /* | ||
3006 | * Note: The following fields will not be used after initialization. The | ||
3007 | * driver may discard the buffer after initialization is done. | ||
3008 | */ | ||
3009 | ADV_DVC_CFG *cfg; /* temporary configuration structure */ | ||
3010 | } ADV_DVC_VAR; | ||
3011 | |||
3012 | #define NO_OF_SG_PER_BLOCK 15 | ||
3013 | |||
3014 | typedef struct asc_sg_block { | 1819 | typedef struct asc_sg_block { |
3015 | uchar reserved1; | 1820 | uchar reserved1; |
3016 | uchar reserved2; | 1821 | uchar reserved2; |
@@ -3069,6 +1874,83 @@ typedef struct adv_scsi_req_q { | |||
3069 | } ADV_SCSI_REQ_Q; | 1874 | } ADV_SCSI_REQ_Q; |
3070 | 1875 | ||
3071 | /* | 1876 | /* |
1877 | * The following two structures are used to process Wide Board requests. | ||
1878 | * | ||
1879 | * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library | ||
1880 | * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the | ||
1881 | * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the | ||
1882 | * Mid-Level SCSI request structure. | ||
1883 | * | ||
1884 | * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each | ||
1885 | * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux | ||
1886 | * up to 255 scatter-gather elements may be used per request or | ||
1887 | * ADV_SCSI_REQ_Q. | ||
1888 | * | ||
1889 | * Both structures must be 32 byte aligned. | ||
1890 | */ | ||
1891 | typedef struct adv_sgblk { | ||
1892 | ADV_SG_BLOCK sg_block; /* Sgblock structure. */ | ||
1893 | uchar align[32]; /* Sgblock structure padding. */ | ||
1894 | struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */ | ||
1895 | } adv_sgblk_t; | ||
1896 | |||
1897 | typedef struct adv_req { | ||
1898 | ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */ | ||
1899 | uchar align[32]; /* Request structure padding. */ | ||
1900 | struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */ | ||
1901 | adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */ | ||
1902 | struct adv_req *next_reqp; /* Next Request Structure. */ | ||
1903 | } adv_req_t; | ||
1904 | |||
1905 | /* | ||
1906 | * Adapter operation variable structure. | ||
1907 | * | ||
1908 | * One structure is required per host adapter. | ||
1909 | * | ||
1910 | * Field naming convention: | ||
1911 | * | ||
1912 | * *_able indicates both whether a feature should be enabled or disabled | ||
1913 | * and whether a device isi capable of the feature. At initialization | ||
1914 | * this field may be set, but later if a device is found to be incapable | ||
1915 | * of the feature, the field is cleared. | ||
1916 | */ | ||
1917 | typedef struct adv_dvc_var { | ||
1918 | AdvPortAddr iop_base; /* I/O port address */ | ||
1919 | ushort err_code; /* fatal error code */ | ||
1920 | ushort bios_ctrl; /* BIOS control word, EEPROM word 12 */ | ||
1921 | ushort wdtr_able; /* try WDTR for a device */ | ||
1922 | ushort sdtr_able; /* try SDTR for a device */ | ||
1923 | ushort ultra_able; /* try SDTR Ultra speed for a device */ | ||
1924 | ushort sdtr_speed1; /* EEPROM SDTR Speed for TID 0-3 */ | ||
1925 | ushort sdtr_speed2; /* EEPROM SDTR Speed for TID 4-7 */ | ||
1926 | ushort sdtr_speed3; /* EEPROM SDTR Speed for TID 8-11 */ | ||
1927 | ushort sdtr_speed4; /* EEPROM SDTR Speed for TID 12-15 */ | ||
1928 | ushort tagqng_able; /* try tagged queuing with a device */ | ||
1929 | ushort ppr_able; /* PPR message capable per TID bitmask. */ | ||
1930 | uchar max_dvc_qng; /* maximum number of tagged commands per device */ | ||
1931 | ushort start_motor; /* start motor command allowed */ | ||
1932 | uchar scsi_reset_wait; /* delay in seconds after scsi bus reset */ | ||
1933 | uchar chip_no; /* should be assigned by caller */ | ||
1934 | uchar max_host_qng; /* maximum number of Q'ed command allowed */ | ||
1935 | ushort no_scam; /* scam_tolerant of EEPROM */ | ||
1936 | struct asc_board *drv_ptr; /* driver pointer to private structure */ | ||
1937 | uchar chip_scsi_id; /* chip SCSI target ID */ | ||
1938 | uchar chip_type; | ||
1939 | uchar bist_err_code; | ||
1940 | ADV_CARR_T *carrier_buf; | ||
1941 | ADV_CARR_T *carr_freelist; /* Carrier free list. */ | ||
1942 | ADV_CARR_T *icq_sp; /* Initiator command queue stopper pointer. */ | ||
1943 | ADV_CARR_T *irq_sp; /* Initiator response queue stopper pointer. */ | ||
1944 | ushort carr_pending_cnt; /* Count of pending carriers. */ | ||
1945 | struct adv_req *orig_reqp; /* adv_req_t memory block. */ | ||
1946 | /* | ||
1947 | * Note: The following fields will not be used after initialization. The | ||
1948 | * driver may discard the buffer after initialization is done. | ||
1949 | */ | ||
1950 | ADV_DVC_CFG *cfg; /* temporary configuration structure */ | ||
1951 | } ADV_DVC_VAR; | ||
1952 | |||
1953 | /* | ||
3072 | * Microcode idle loop commands | 1954 | * Microcode idle loop commands |
3073 | */ | 1955 | */ |
3074 | #define IDLE_CMD_COMPLETED 0 | 1956 | #define IDLE_CMD_COMPLETED 0 |
@@ -3092,10 +1974,8 @@ typedef struct adv_scsi_req_q { | |||
3092 | /* | 1974 | /* |
3093 | * Wait loop time out values. | 1975 | * Wait loop time out values. |
3094 | */ | 1976 | */ |
3095 | #define SCSI_WAIT_10_SEC 10UL /* 10 seconds */ | ||
3096 | #define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */ | 1977 | #define SCSI_WAIT_100_MSEC 100UL /* 100 milliseconds */ |
3097 | #define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */ | 1978 | #define SCSI_US_PER_MSEC 1000 /* microseconds per millisecond */ |
3098 | #define SCSI_MS_PER_SEC 1000UL /* milliseconds per second */ | ||
3099 | #define SCSI_MAX_RETRY 10 /* retry count */ | 1979 | #define SCSI_MAX_RETRY 10 /* retry count */ |
3100 | 1980 | ||
3101 | #define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */ | 1981 | #define ADV_ASYNC_RDMA_FAILURE 0x01 /* Fatal RDMA failure. */ |
@@ -3105,53 +1985,6 @@ typedef struct adv_scsi_req_q { | |||
3105 | 1985 | ||
3106 | #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */ | 1986 | #define ADV_HOST_SCSI_BUS_RESET 0x80 /* Host Initiated SCSI Bus Reset. */ |
3107 | 1987 | ||
3108 | /* | ||
3109 | * Device drivers must define the following functions. | ||
3110 | */ | ||
3111 | static inline ulong DvcEnterCritical(void); | ||
3112 | static inline void DvcLeaveCritical(ulong); | ||
3113 | static void DvcSleepMilliSecond(ADV_DCNT); | ||
3114 | static uchar DvcAdvReadPCIConfigByte(ADV_DVC_VAR *, ushort); | ||
3115 | static void DvcAdvWritePCIConfigByte(ADV_DVC_VAR *, ushort, uchar); | ||
3116 | static ADV_PADDR DvcGetPhyAddr(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *, | ||
3117 | uchar *, ASC_SDCNT *, int); | ||
3118 | static void DvcDelayMicroSecond(ADV_DVC_VAR *, ushort); | ||
3119 | |||
3120 | /* | ||
3121 | * Adv Library functions available to drivers. | ||
3122 | */ | ||
3123 | static int AdvExeScsiQueue(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *); | ||
3124 | static int AdvISR(ADV_DVC_VAR *); | ||
3125 | static int AdvInitGetConfig(ADV_DVC_VAR *); | ||
3126 | static int AdvInitAsc3550Driver(ADV_DVC_VAR *); | ||
3127 | static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *); | ||
3128 | static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *); | ||
3129 | static int AdvResetChipAndSB(ADV_DVC_VAR *); | ||
3130 | static int AdvResetSB(ADV_DVC_VAR *asc_dvc); | ||
3131 | |||
3132 | /* | ||
3133 | * Internal Adv Library functions. | ||
3134 | */ | ||
3135 | static int AdvSendIdleCmd(ADV_DVC_VAR *, ushort, ADV_DCNT); | ||
3136 | static void AdvInquiryHandling(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *); | ||
3137 | static int AdvInitFrom3550EEP(ADV_DVC_VAR *); | ||
3138 | static int AdvInitFrom38C0800EEP(ADV_DVC_VAR *); | ||
3139 | static int AdvInitFrom38C1600EEP(ADV_DVC_VAR *); | ||
3140 | static ushort AdvGet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *); | ||
3141 | static void AdvSet3550EEPConfig(AdvPortAddr, ADVEEP_3550_CONFIG *); | ||
3142 | static ushort AdvGet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *); | ||
3143 | static void AdvSet38C0800EEPConfig(AdvPortAddr, ADVEEP_38C0800_CONFIG *); | ||
3144 | static ushort AdvGet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *); | ||
3145 | static void AdvSet38C1600EEPConfig(AdvPortAddr, ADVEEP_38C1600_CONFIG *); | ||
3146 | static void AdvWaitEEPCmd(AdvPortAddr); | ||
3147 | static ushort AdvReadEEPWord(AdvPortAddr, int); | ||
3148 | |||
3149 | /* | ||
3150 | * PCI Bus Definitions | ||
3151 | */ | ||
3152 | #define AscPCICmdRegBits_BusMastering 0x0007 | ||
3153 | #define AscPCICmdRegBits_ParErrRespCtrl 0x0040 | ||
3154 | |||
3155 | /* Read byte from a register. */ | 1988 | /* Read byte from a register. */ |
3156 | #define AdvReadByteRegister(iop_base, reg_off) \ | 1989 | #define AdvReadByteRegister(iop_base, reg_off) \ |
3157 | (ADV_MEM_READB((iop_base) + (reg_off))) | 1990 | (ADV_MEM_READB((iop_base) + (reg_off))) |
@@ -3319,23 +2152,6 @@ do { \ | |||
3319 | #define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */ | 2152 | #define QHSTA_M_FROZEN_TIDQ 0x46 /* TID Queue frozen. */ |
3320 | #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */ | 2153 | #define QHSTA_M_SGBACKUP_ERROR 0x47 /* Scatter-Gather backup error */ |
3321 | 2154 | ||
3322 | /* | ||
3323 | * Default EEPROM Configuration structure defined in a_init.c. | ||
3324 | */ | ||
3325 | static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config; | ||
3326 | static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config; | ||
3327 | static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config; | ||
3328 | |||
3329 | /* | ||
3330 | * DvcGetPhyAddr() flag arguments | ||
3331 | */ | ||
3332 | #define ADV_IS_SCSIQ_FLAG 0x01 /* 'addr' is ASC_SCSI_REQ_Q pointer */ | ||
3333 | #define ADV_ASCGETSGLIST_VADDR 0x02 /* 'addr' is AscGetSGList() virtual addr */ | ||
3334 | #define ADV_IS_SENSE_FLAG 0x04 /* 'addr' is sense virtual pointer */ | ||
3335 | #define ADV_IS_DATA_FLAG 0x08 /* 'addr' is data virtual pointer */ | ||
3336 | #define ADV_IS_SGLIST_FLAG 0x10 /* 'addr' is sglist virtual pointer */ | ||
3337 | #define ADV_IS_CARRIER_FLAG 0x20 /* 'addr' is ADV_CARR_T pointer */ | ||
3338 | |||
3339 | /* Return the address that is aligned at the next doubleword >= to 'addr'. */ | 2155 | /* Return the address that is aligned at the next doubleword >= to 'addr'. */ |
3340 | #define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7) | 2156 | #define ADV_8BALIGN(addr) (((ulong) (addr) + 0x7) & ~0x7) |
3341 | #define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF) | 2157 | #define ADV_16BALIGN(addr) (((ulong) (addr) + 0xF) & ~0xF) |
@@ -3353,92 +2169,10 @@ static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config; | |||
3353 | (sizeof(ADV_SG_BLOCK) * \ | 2169 | (sizeof(ADV_SG_BLOCK) * \ |
3354 | ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)) | 2170 | ((ADV_MAX_SG_LIST + (NO_OF_SG_PER_BLOCK - 1))/NO_OF_SG_PER_BLOCK)) |
3355 | 2171 | ||
3356 | /* | 2172 | /* struct asc_board flags */ |
3357 | * Inquiry data structure and bitfield macros | ||
3358 | * | ||
3359 | * Using bitfields to access the subchar data isn't portable across | ||
3360 | * endianness, so instead mask and shift. Only quantities of more | ||
3361 | * than 1 bit are shifted, since the others are just tested for true | ||
3362 | * or false. | ||
3363 | */ | ||
3364 | |||
3365 | #define ADV_INQ_DVC_TYPE(inq) ((inq)->periph & 0x1f) | ||
3366 | #define ADV_INQ_QUALIFIER(inq) (((inq)->periph & 0xe0) >> 5) | ||
3367 | #define ADV_INQ_DVC_TYPE_MOD(inq) ((inq)->devtype & 0x7f) | ||
3368 | #define ADV_INQ_REMOVABLE(inq) ((inq)->devtype & 0x80) | ||
3369 | #define ADV_INQ_ANSI_VER(inq) ((inq)->ver & 0x07) | ||
3370 | #define ADV_INQ_ECMA_VER(inq) (((inq)->ver & 0x38) >> 3) | ||
3371 | #define ADV_INQ_ISO_VER(inq) (((inq)->ver & 0xc0) >> 6) | ||
3372 | #define ADV_INQ_RESPONSE_FMT(inq) ((inq)->byte3 & 0x0f) | ||
3373 | #define ADV_INQ_TERM_IO(inq) ((inq)->byte3 & 0x40) | ||
3374 | #define ADV_INQ_ASYNC_NOTIF(inq) ((inq)->byte3 & 0x80) | ||
3375 | #define ADV_INQ_SOFT_RESET(inq) ((inq)->flags & 0x01) | ||
3376 | #define ADV_INQ_CMD_QUEUE(inq) ((inq)->flags & 0x02) | ||
3377 | #define ADV_INQ_LINK_CMD(inq) ((inq)->flags & 0x08) | ||
3378 | #define ADV_INQ_SYNC(inq) ((inq)->flags & 0x10) | ||
3379 | #define ADV_INQ_WIDE16(inq) ((inq)->flags & 0x20) | ||
3380 | #define ADV_INQ_WIDE32(inq) ((inq)->flags & 0x40) | ||
3381 | #define ADV_INQ_REL_ADDR(inq) ((inq)->flags & 0x80) | ||
3382 | #define ADV_INQ_INFO_UNIT(inq) ((inq)->info & 0x01) | ||
3383 | #define ADV_INQ_QUICK_ARB(inq) ((inq)->info & 0x02) | ||
3384 | #define ADV_INQ_CLOCKING(inq) (((inq)->info & 0x0c) >> 2) | ||
3385 | |||
3386 | typedef struct { | ||
3387 | uchar periph; /* peripheral device type [0:4] */ | ||
3388 | /* peripheral qualifier [5:7] */ | ||
3389 | uchar devtype; /* device type modifier (for SCSI I) [0:6] */ | ||
3390 | /* RMB - removable medium bit [7] */ | ||
3391 | uchar ver; /* ANSI approved version [0:2] */ | ||
3392 | /* ECMA version [3:5] */ | ||
3393 | /* ISO version [6:7] */ | ||
3394 | uchar byte3; /* response data format [0:3] */ | ||
3395 | /* 0 SCSI 1 */ | ||
3396 | /* 1 CCS */ | ||
3397 | /* 2 SCSI-2 */ | ||
3398 | /* 3-F reserved */ | ||
3399 | /* reserved [4:5] */ | ||
3400 | /* terminate I/O process bit (see 5.6.22) [6] */ | ||
3401 | /* asynch. event notification (processor) [7] */ | ||
3402 | uchar add_len; /* additional length */ | ||
3403 | uchar res1; /* reserved */ | ||
3404 | uchar res2; /* reserved */ | ||
3405 | uchar flags; /* soft reset implemented [0] */ | ||
3406 | /* command queuing [1] */ | ||
3407 | /* reserved [2] */ | ||
3408 | /* linked command for this logical unit [3] */ | ||
3409 | /* synchronous data transfer [4] */ | ||
3410 | /* wide bus 16 bit data transfer [5] */ | ||
3411 | /* wide bus 32 bit data transfer [6] */ | ||
3412 | /* relative addressing mode [7] */ | ||
3413 | uchar vendor_id[8]; /* vendor identification */ | ||
3414 | uchar product_id[16]; /* product identification */ | ||
3415 | uchar product_rev_level[4]; /* product revision level */ | ||
3416 | uchar vendor_specific[20]; /* vendor specific */ | ||
3417 | uchar info; /* information unit supported [0] */ | ||
3418 | /* quick arbitrate supported [1] */ | ||
3419 | /* clocking field [2:3] */ | ||
3420 | /* reserved [4:7] */ | ||
3421 | uchar res3; /* reserved */ | ||
3422 | } ADV_SCSI_INQUIRY; /* 58 bytes */ | ||
3423 | |||
3424 | /* | ||
3425 | * --- Driver Constants and Macros | ||
3426 | */ | ||
3427 | |||
3428 | #define ASC_NUM_BOARD_SUPPORTED 16 | ||
3429 | #define ASC_NUM_IOPORT_PROBE 4 | ||
3430 | #define ASC_NUM_BUS 4 | ||
3431 | |||
3432 | /* Reference Scsi_Host hostdata */ | ||
3433 | #define ASC_BOARDP(host) ((asc_board_t *) &((host)->hostdata)) | ||
3434 | |||
3435 | /* asc_board_t flags */ | ||
3436 | #define ASC_HOST_IN_RESET 0x01 | ||
3437 | #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */ | 2173 | #define ASC_IS_WIDE_BOARD 0x04 /* AdvanSys Wide Board */ |
3438 | #define ASC_SELECT_QUEUE_DEPTHS 0x08 | ||
3439 | 2174 | ||
3440 | #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0) | 2175 | #define ASC_NARROW_BOARD(boardp) (((boardp)->flags & ASC_IS_WIDE_BOARD) == 0) |
3441 | #define ASC_WIDE_BOARD(boardp) ((boardp)->flags & ASC_IS_WIDE_BOARD) | ||
3442 | 2176 | ||
3443 | #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */ | 2177 | #define NO_ISA_DMA 0xff /* No ISA DMA Channel Used */ |
3444 | 2178 | ||
@@ -3473,82 +2207,14 @@ typedef struct { | |||
3473 | #define HOST_BYTE(byte) ((byte) << 16) | 2207 | #define HOST_BYTE(byte) ((byte) << 16) |
3474 | #define DRIVER_BYTE(byte) ((byte) << 24) | 2208 | #define DRIVER_BYTE(byte) ((byte) << 24) |
3475 | 2209 | ||
3476 | /* | 2210 | #define ASC_STATS(shost, counter) ASC_STATS_ADD(shost, counter, 1) |
3477 | * The following definitions and macros are OS independent interfaces to | ||
3478 | * the queue functions: | ||
3479 | * REQ - SCSI request structure | ||
3480 | * REQP - pointer to SCSI request structure | ||
3481 | * REQPTID(reqp) - reqp's target id | ||
3482 | * REQPNEXT(reqp) - reqp's next pointer | ||
3483 | * REQPNEXTP(reqp) - pointer to reqp's next pointer | ||
3484 | * REQPTIME(reqp) - reqp's time stamp value | ||
3485 | * REQTIMESTAMP() - system time stamp value | ||
3486 | */ | ||
3487 | typedef struct scsi_cmnd REQ, *REQP; | ||
3488 | #define REQPNEXT(reqp) ((REQP) ((reqp)->host_scribble)) | ||
3489 | #define REQPNEXTP(reqp) ((REQP *) &((reqp)->host_scribble)) | ||
3490 | #define REQPTID(reqp) ((reqp)->device->id) | ||
3491 | #define REQPTIME(reqp) ((reqp)->SCp.this_residual) | ||
3492 | #define REQTIMESTAMP() (jiffies) | ||
3493 | |||
3494 | #define REQTIMESTAT(function, ascq, reqp, tid) \ | ||
3495 | { \ | ||
3496 | /* | ||
3497 | * If the request time stamp is less than the system time stamp, then \ | ||
3498 | * maybe the system time stamp wrapped. Set the request time to zero.\ | ||
3499 | */ \ | ||
3500 | if (REQPTIME(reqp) <= REQTIMESTAMP()) { \ | ||
3501 | REQPTIME(reqp) = REQTIMESTAMP() - REQPTIME(reqp); \ | ||
3502 | } else { \ | ||
3503 | /* Indicate an error occurred with the assertion. */ \ | ||
3504 | ASC_ASSERT(REQPTIME(reqp) <= REQTIMESTAMP()); \ | ||
3505 | REQPTIME(reqp) = 0; \ | ||
3506 | } \ | ||
3507 | /* Handle first minimum time case without external initialization. */ \ | ||
3508 | if (((ascq)->q_tot_cnt[tid] == 1) || \ | ||
3509 | (REQPTIME(reqp) < (ascq)->q_min_tim[tid])) { \ | ||
3510 | (ascq)->q_min_tim[tid] = REQPTIME(reqp); \ | ||
3511 | ASC_DBG3(1, "%s: new q_min_tim[%d] %u\n", \ | ||
3512 | (function), (tid), (ascq)->q_min_tim[tid]); \ | ||
3513 | } \ | ||
3514 | if (REQPTIME(reqp) > (ascq)->q_max_tim[tid]) { \ | ||
3515 | (ascq)->q_max_tim[tid] = REQPTIME(reqp); \ | ||
3516 | ASC_DBG3(1, "%s: new q_max_tim[%d] %u\n", \ | ||
3517 | (function), tid, (ascq)->q_max_tim[tid]); \ | ||
3518 | } \ | ||
3519 | (ascq)->q_tot_tim[tid] += REQPTIME(reqp); \ | ||
3520 | /* Reset the time stamp field. */ \ | ||
3521 | REQPTIME(reqp) = 0; \ | ||
3522 | } | ||
3523 | |||
3524 | /* asc_enqueue() flags */ | ||
3525 | #define ASC_FRONT 1 | ||
3526 | #define ASC_BACK 2 | ||
3527 | |||
3528 | /* asc_dequeue_list() argument */ | ||
3529 | #define ASC_TID_ALL (-1) | ||
3530 | |||
3531 | /* Return non-zero, if the queue is empty. */ | ||
3532 | #define ASC_QUEUE_EMPTY(ascq) ((ascq)->q_tidmask == 0) | ||
3533 | |||
3534 | #define PCI_MAX_SLOT 0x1F | ||
3535 | #define PCI_MAX_BUS 0xFF | ||
3536 | #define PCI_IOADDRESS_MASK 0xFFFE | ||
3537 | #define ASC_PCI_DEVICE_ID_CNT 6 /* PCI Device ID count. */ | ||
3538 | |||
3539 | #ifndef ADVANSYS_STATS | 2211 | #ifndef ADVANSYS_STATS |
3540 | #define ASC_STATS(shost, counter) | ||
3541 | #define ASC_STATS_ADD(shost, counter, count) | 2212 | #define ASC_STATS_ADD(shost, counter, count) |
3542 | #else /* ADVANSYS_STATS */ | 2213 | #else /* ADVANSYS_STATS */ |
3543 | #define ASC_STATS(shost, counter) \ | ||
3544 | (ASC_BOARDP(shost)->asc_stats.counter++) | ||
3545 | |||
3546 | #define ASC_STATS_ADD(shost, counter, count) \ | 2214 | #define ASC_STATS_ADD(shost, counter, count) \ |
3547 | (ASC_BOARDP(shost)->asc_stats.counter += (count)) | 2215 | (((struct asc_board *) shost_priv(shost))->asc_stats.counter += (count)) |
3548 | #endif /* ADVANSYS_STATS */ | 2216 | #endif /* ADVANSYS_STATS */ |
3549 | 2217 | ||
3550 | #define ASC_CEILING(val, unit) (((val) + ((unit) - 1))/(unit)) | ||
3551 | |||
3552 | /* If the result wraps when calculating tenths, return 0. */ | 2218 | /* If the result wraps when calculating tenths, return 0. */ |
3553 | #define ASC_TENTHS(num, den) \ | 2219 | #define ASC_TENTHS(num, den) \ |
3554 | (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \ | 2220 | (((10 * ((num)/(den))) > (((num) * 10)/(den))) ? \ |
@@ -3589,13 +2255,8 @@ typedef struct scsi_cmnd REQ, *REQP; | |||
3589 | 2255 | ||
3590 | #ifndef ADVANSYS_DEBUG | 2256 | #ifndef ADVANSYS_DEBUG |
3591 | 2257 | ||
3592 | #define ASC_DBG(lvl, s) | 2258 | #define ASC_DBG(lvl, s...) |
3593 | #define ASC_DBG1(lvl, s, a1) | ||
3594 | #define ASC_DBG2(lvl, s, a1, a2) | ||
3595 | #define ASC_DBG3(lvl, s, a1, a2, a3) | ||
3596 | #define ASC_DBG4(lvl, s, a1, a2, a3, a4) | ||
3597 | #define ASC_DBG_PRT_SCSI_HOST(lvl, s) | 2259 | #define ASC_DBG_PRT_SCSI_HOST(lvl, s) |
3598 | #define ASC_DBG_PRT_SCSI_CMND(lvl, s) | ||
3599 | #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) | 2260 | #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) |
3600 | #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) | 2261 | #define ASC_DBG_PRT_ADV_SCSI_REQ_Q(lvl, scsiqp) |
3601 | #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) | 2262 | #define ASC_DBG_PRT_ASC_QDONE_INFO(lvl, qdone) |
@@ -3614,40 +2275,11 @@ typedef struct scsi_cmnd REQ, *REQP; | |||
3614 | * 2-N: Verbose Tracing | 2275 | * 2-N: Verbose Tracing |
3615 | */ | 2276 | */ |
3616 | 2277 | ||
3617 | #define ASC_DBG(lvl, s) \ | 2278 | #define ASC_DBG(lvl, format, arg...) { \ |
3618 | { \ | 2279 | if (asc_dbglvl >= (lvl)) \ |
3619 | if (asc_dbglvl >= (lvl)) { \ | 2280 | printk(KERN_DEBUG "%s: %s: " format, DRV_NAME, \ |
3620 | printk(s); \ | 2281 | __FUNCTION__ , ## arg); \ |
3621 | } \ | 2282 | } |
3622 | } | ||
3623 | |||
3624 | #define ASC_DBG1(lvl, s, a1) \ | ||
3625 | { \ | ||
3626 | if (asc_dbglvl >= (lvl)) { \ | ||
3627 | printk((s), (a1)); \ | ||
3628 | } \ | ||
3629 | } | ||
3630 | |||
3631 | #define ASC_DBG2(lvl, s, a1, a2) \ | ||
3632 | { \ | ||
3633 | if (asc_dbglvl >= (lvl)) { \ | ||
3634 | printk((s), (a1), (a2)); \ | ||
3635 | } \ | ||
3636 | } | ||
3637 | |||
3638 | #define ASC_DBG3(lvl, s, a1, a2, a3) \ | ||
3639 | { \ | ||
3640 | if (asc_dbglvl >= (lvl)) { \ | ||
3641 | printk((s), (a1), (a2), (a3)); \ | ||
3642 | } \ | ||
3643 | } | ||
3644 | |||
3645 | #define ASC_DBG4(lvl, s, a1, a2, a3, a4) \ | ||
3646 | { \ | ||
3647 | if (asc_dbglvl >= (lvl)) { \ | ||
3648 | printk((s), (a1), (a2), (a3), (a4)); \ | ||
3649 | } \ | ||
3650 | } | ||
3651 | 2283 | ||
3652 | #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \ | 2284 | #define ASC_DBG_PRT_SCSI_HOST(lvl, s) \ |
3653 | { \ | 2285 | { \ |
@@ -3656,13 +2288,6 @@ typedef struct scsi_cmnd REQ, *REQP; | |||
3656 | } \ | 2288 | } \ |
3657 | } | 2289 | } |
3658 | 2290 | ||
3659 | #define ASC_DBG_PRT_SCSI_CMND(lvl, s) \ | ||
3660 | { \ | ||
3661 | if (asc_dbglvl >= (lvl)) { \ | ||
3662 | asc_prt_scsi_cmnd(s); \ | ||
3663 | } \ | ||
3664 | } | ||
3665 | |||
3666 | #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \ | 2291 | #define ASC_DBG_PRT_ASC_SCSI_Q(lvl, scsiqp) \ |
3667 | { \ | 2292 | { \ |
3668 | if (asc_dbglvl >= (lvl)) { \ | 2293 | if (asc_dbglvl >= (lvl)) { \ |
@@ -3701,24 +2326,6 @@ typedef struct scsi_cmnd REQ, *REQP; | |||
3701 | ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len)); | 2326 | ASC_DBG_PRT_HEX((lvl), "INQUIRY", (uchar *) (inq), (len)); |
3702 | #endif /* ADVANSYS_DEBUG */ | 2327 | #endif /* ADVANSYS_DEBUG */ |
3703 | 2328 | ||
3704 | #ifndef ADVANSYS_ASSERT | ||
3705 | #define ASC_ASSERT(a) | ||
3706 | #else /* ADVANSYS_ASSERT */ | ||
3707 | |||
3708 | #define ASC_ASSERT(a) \ | ||
3709 | { \ | ||
3710 | if (!(a)) { \ | ||
3711 | printk("ASC_ASSERT() Failure: file %s, line %d\n", \ | ||
3712 | __FILE__, __LINE__); \ | ||
3713 | } \ | ||
3714 | } | ||
3715 | |||
3716 | #endif /* ADVANSYS_ASSERT */ | ||
3717 | |||
3718 | /* | ||
3719 | * --- Driver Structures | ||
3720 | */ | ||
3721 | |||
3722 | #ifdef ADVANSYS_STATS | 2329 | #ifdef ADVANSYS_STATS |
3723 | 2330 | ||
3724 | /* Per board statistics structure */ | 2331 | /* Per board statistics structure */ |
@@ -3739,72 +2346,23 @@ struct asc_stats { | |||
3739 | ADV_DCNT exe_error; /* # ASC_ERROR returns. */ | 2346 | ADV_DCNT exe_error; /* # ASC_ERROR returns. */ |
3740 | ADV_DCNT exe_unknown; /* # unknown returns. */ | 2347 | ADV_DCNT exe_unknown; /* # unknown returns. */ |
3741 | /* Data Transfer Statistics */ | 2348 | /* Data Transfer Statistics */ |
3742 | ADV_DCNT cont_cnt; /* # non-scatter-gather I/O requests received */ | 2349 | ADV_DCNT xfer_cnt; /* # I/O requests received */ |
3743 | ADV_DCNT cont_xfer; /* # contiguous transfer 512-bytes */ | 2350 | ADV_DCNT xfer_elem; /* # scatter-gather elements */ |
3744 | ADV_DCNT sg_cnt; /* # scatter-gather I/O requests received */ | 2351 | ADV_DCNT xfer_sect; /* # 512-byte blocks */ |
3745 | ADV_DCNT sg_elem; /* # scatter-gather elements */ | ||
3746 | ADV_DCNT sg_xfer; /* # scatter-gather transfer 512-bytes */ | ||
3747 | }; | 2352 | }; |
3748 | #endif /* ADVANSYS_STATS */ | 2353 | #endif /* ADVANSYS_STATS */ |
3749 | 2354 | ||
3750 | /* | 2355 | /* |
3751 | * Request queuing structure | ||
3752 | */ | ||
3753 | typedef struct asc_queue { | ||
3754 | ADV_SCSI_BIT_ID_TYPE q_tidmask; /* queue mask */ | ||
3755 | REQP q_first[ADV_MAX_TID + 1]; /* first queued request */ | ||
3756 | REQP q_last[ADV_MAX_TID + 1]; /* last queued request */ | ||
3757 | #ifdef ADVANSYS_STATS | ||
3758 | short q_cur_cnt[ADV_MAX_TID + 1]; /* current queue count */ | ||
3759 | short q_max_cnt[ADV_MAX_TID + 1]; /* maximum queue count */ | ||
3760 | ADV_DCNT q_tot_cnt[ADV_MAX_TID + 1]; /* total enqueue count */ | ||
3761 | ADV_DCNT q_tot_tim[ADV_MAX_TID + 1]; /* total time queued */ | ||
3762 | ushort q_max_tim[ADV_MAX_TID + 1]; /* maximum time queued */ | ||
3763 | ushort q_min_tim[ADV_MAX_TID + 1]; /* minimum time queued */ | ||
3764 | #endif /* ADVANSYS_STATS */ | ||
3765 | } asc_queue_t; | ||
3766 | |||
3767 | /* | ||
3768 | * Adv Library Request Structures | ||
3769 | * | ||
3770 | * The following two structures are used to process Wide Board requests. | ||
3771 | * | ||
3772 | * The ADV_SCSI_REQ_Q structure in adv_req_t is passed to the Adv Library | ||
3773 | * and microcode with the ADV_SCSI_REQ_Q field 'srb_ptr' pointing to the | ||
3774 | * adv_req_t. The adv_req_t structure 'cmndp' field in turn points to the | ||
3775 | * Mid-Level SCSI request structure. | ||
3776 | * | ||
3777 | * Zero or more ADV_SG_BLOCK are used with each ADV_SCSI_REQ_Q. Each | ||
3778 | * ADV_SG_BLOCK structure holds 15 scatter-gather elements. Under Linux | ||
3779 | * up to 255 scatter-gather elements may be used per request or | ||
3780 | * ADV_SCSI_REQ_Q. | ||
3781 | * | ||
3782 | * Both structures must be 32 byte aligned. | ||
3783 | */ | ||
3784 | typedef struct adv_sgblk { | ||
3785 | ADV_SG_BLOCK sg_block; /* Sgblock structure. */ | ||
3786 | uchar align[32]; /* Sgblock structure padding. */ | ||
3787 | struct adv_sgblk *next_sgblkp; /* Next scatter-gather structure. */ | ||
3788 | } adv_sgblk_t; | ||
3789 | |||
3790 | typedef struct adv_req { | ||
3791 | ADV_SCSI_REQ_Q scsi_req_q; /* Adv Library request structure. */ | ||
3792 | uchar align[32]; /* Request structure padding. */ | ||
3793 | struct scsi_cmnd *cmndp; /* Mid-Level SCSI command pointer. */ | ||
3794 | adv_sgblk_t *sgblkp; /* Adv Library scatter-gather pointer. */ | ||
3795 | struct adv_req *next_reqp; /* Next Request Structure. */ | ||
3796 | } adv_req_t; | ||
3797 | |||
3798 | /* | ||
3799 | * Structure allocated for each board. | 2356 | * Structure allocated for each board. |
3800 | * | 2357 | * |
3801 | * This structure is allocated by scsi_register() at the end | 2358 | * This structure is allocated by scsi_host_alloc() at the end |
3802 | * of the 'Scsi_Host' structure starting at the 'hostdata' | 2359 | * of the 'Scsi_Host' structure starting at the 'hostdata' |
3803 | * field. It is guaranteed to be allocated from DMA-able memory. | 2360 | * field. It is guaranteed to be allocated from DMA-able memory. |
3804 | */ | 2361 | */ |
3805 | typedef struct asc_board { | 2362 | struct asc_board { |
3806 | int id; /* Board Id */ | 2363 | struct device *dev; |
3807 | uint flags; /* Board flags */ | 2364 | uint flags; /* Board flags */ |
2365 | unsigned int irq; | ||
3808 | union { | 2366 | union { |
3809 | ASC_DVC_VAR asc_dvc_var; /* Narrow board */ | 2367 | ASC_DVC_VAR asc_dvc_var; /* Narrow board */ |
3810 | ADV_DVC_VAR adv_dvc_var; /* Wide board */ | 2368 | ADV_DVC_VAR adv_dvc_var; /* Wide board */ |
@@ -3814,11 +2372,7 @@ typedef struct asc_board { | |||
3814 | ADV_DVC_CFG adv_dvc_cfg; /* Wide board */ | 2372 | ADV_DVC_CFG adv_dvc_cfg; /* Wide board */ |
3815 | } dvc_cfg; | 2373 | } dvc_cfg; |
3816 | ushort asc_n_io_port; /* Number I/O ports. */ | 2374 | ushort asc_n_io_port; /* Number I/O ports. */ |
3817 | asc_queue_t active; /* Active command queue */ | ||
3818 | asc_queue_t waiting; /* Waiting command queue */ | ||
3819 | asc_queue_t done; /* Done command queue */ | ||
3820 | ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */ | 2375 | ADV_SCSI_BIT_ID_TYPE init_tidmask; /* Target init./valid mask */ |
3821 | struct scsi_device *device[ADV_MAX_TID + 1]; /* Mid-Level Scsi Device */ | ||
3822 | ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */ | 2376 | ushort reqcnt[ADV_MAX_TID + 1]; /* Starvation request count */ |
3823 | ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */ | 2377 | ADV_SCSI_BIT_ID_TYPE queue_full; /* Queue full mask */ |
3824 | ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */ | 2378 | ushort queue_full_cnt[ADV_MAX_TID + 1]; /* Queue full count */ |
@@ -3829,2409 +2383,529 @@ typedef struct asc_board { | |||
3829 | ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */ | 2383 | ADVEEP_38C1600_CONFIG adv_38C1600_eep; /* 38C1600 EEPROM config. */ |
3830 | } eep_config; | 2384 | } eep_config; |
3831 | ulong last_reset; /* Saved last reset time */ | 2385 | ulong last_reset; /* Saved last reset time */ |
3832 | spinlock_t lock; /* Board spinlock */ | ||
3833 | #ifdef CONFIG_PROC_FS | ||
3834 | /* /proc/scsi/advansys/[0...] */ | 2386 | /* /proc/scsi/advansys/[0...] */ |
3835 | char *prtbuf; /* /proc print buffer */ | 2387 | char *prtbuf; /* /proc print buffer */ |
3836 | #endif /* CONFIG_PROC_FS */ | ||
3837 | #ifdef ADVANSYS_STATS | 2388 | #ifdef ADVANSYS_STATS |
3838 | struct asc_stats asc_stats; /* Board statistics */ | 2389 | struct asc_stats asc_stats; /* Board statistics */ |
3839 | #endif /* ADVANSYS_STATS */ | 2390 | #endif /* ADVANSYS_STATS */ |
3840 | /* | 2391 | /* |
3841 | * The following fields are used only for Narrow Boards. | 2392 | * The following fields are used only for Narrow Boards. |
3842 | */ | 2393 | */ |
3843 | /* The following three structures must be in DMA-able memory. */ | ||
3844 | ASC_SCSI_REQ_Q scsireqq; | ||
3845 | ASC_CAP_INFO cap_info; | ||
3846 | ASC_SCSI_INQUIRY inquiry; | ||
3847 | uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */ | 2394 | uchar sdtr_data[ASC_MAX_TID + 1]; /* SDTR information */ |
3848 | /* | 2395 | /* |
3849 | * The following fields are used only for Wide Boards. | 2396 | * The following fields are used only for Wide Boards. |
3850 | */ | 2397 | */ |
3851 | void __iomem *ioremap_addr; /* I/O Memory remap address. */ | 2398 | void __iomem *ioremap_addr; /* I/O Memory remap address. */ |
3852 | ushort ioport; /* I/O Port address. */ | 2399 | ushort ioport; /* I/O Port address. */ |
3853 | ADV_CARR_T *orig_carrp; /* ADV_CARR_T memory block. */ | ||
3854 | adv_req_t *orig_reqp; /* adv_req_t memory block. */ | ||
3855 | adv_req_t *adv_reqp; /* Request structures. */ | 2400 | adv_req_t *adv_reqp; /* Request structures. */ |
3856 | adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */ | 2401 | adv_sgblk_t *adv_sgblkp; /* Scatter-gather structures. */ |
3857 | ushort bios_signature; /* BIOS Signature. */ | 2402 | ushort bios_signature; /* BIOS Signature. */ |
3858 | ushort bios_version; /* BIOS Version. */ | 2403 | ushort bios_version; /* BIOS Version. */ |
3859 | ushort bios_codeseg; /* BIOS Code Segment. */ | 2404 | ushort bios_codeseg; /* BIOS Code Segment. */ |
3860 | ushort bios_codelen; /* BIOS Code Segment Length. */ | 2405 | ushort bios_codelen; /* BIOS Code Segment Length. */ |
3861 | } asc_board_t; | ||
3862 | |||
3863 | /* | ||
3864 | * PCI configuration structures | ||
3865 | */ | ||
3866 | typedef struct _PCI_DATA_ { | ||
3867 | uchar type; | ||
3868 | uchar bus; | ||
3869 | uchar slot; | ||
3870 | uchar func; | ||
3871 | uchar offset; | ||
3872 | } PCI_DATA; | ||
3873 | |||
3874 | typedef struct _PCI_DEVICE_ { | ||
3875 | ushort vendorID; | ||
3876 | ushort deviceID; | ||
3877 | ushort slotNumber; | ||
3878 | ushort slotFound; | ||
3879 | uchar busNumber; | ||
3880 | uchar maxBusNumber; | ||
3881 | uchar devFunc; | ||
3882 | ushort startSlot; | ||
3883 | ushort endSlot; | ||
3884 | uchar bridge; | ||
3885 | uchar type; | ||
3886 | } PCI_DEVICE; | ||
3887 | |||
3888 | typedef struct _PCI_CONFIG_SPACE_ { | ||
3889 | ushort vendorID; | ||
3890 | ushort deviceID; | ||
3891 | ushort command; | ||
3892 | ushort status; | ||
3893 | uchar revision; | ||
3894 | uchar classCode[3]; | ||
3895 | uchar cacheSize; | ||
3896 | uchar latencyTimer; | ||
3897 | uchar headerType; | ||
3898 | uchar bist; | ||
3899 | ADV_PADDR baseAddress[6]; | ||
3900 | ushort reserved[4]; | ||
3901 | ADV_PADDR optionRomAddr; | ||
3902 | ushort reserved2[4]; | ||
3903 | uchar irqLine; | ||
3904 | uchar irqPin; | ||
3905 | uchar minGnt; | ||
3906 | uchar maxLatency; | ||
3907 | } PCI_CONFIG_SPACE; | ||
3908 | |||
3909 | /* | ||
3910 | * --- Driver Data | ||
3911 | */ | ||
3912 | |||
3913 | /* Note: All driver global data should be initialized. */ | ||
3914 | |||
3915 | /* Number of boards detected in system. */ | ||
3916 | static int asc_board_count = 0; | ||
3917 | static struct Scsi_Host *asc_host[ASC_NUM_BOARD_SUPPORTED] = { NULL }; | ||
3918 | |||
3919 | /* Overrun buffer used by all narrow boards. */ | ||
3920 | static uchar overrun_buf[ASC_OVERRUN_BSIZE] = { 0 }; | ||
3921 | |||
3922 | /* | ||
3923 | * Global structures required to issue a command. | ||
3924 | */ | ||
3925 | static ASC_SCSI_Q asc_scsi_q = { {0} }; | ||
3926 | static ASC_SG_HEAD asc_sg_head = { 0 }; | ||
3927 | |||
3928 | /* List of supported bus types. */ | ||
3929 | static ushort asc_bus[ASC_NUM_BUS] __initdata = { | ||
3930 | ASC_IS_ISA, | ||
3931 | ASC_IS_VL, | ||
3932 | ASC_IS_EISA, | ||
3933 | ASC_IS_PCI, | ||
3934 | }; | 2406 | }; |
3935 | 2407 | ||
3936 | static int asc_iopflag = ASC_FALSE; | 2408 | #define asc_dvc_to_board(asc_dvc) container_of(asc_dvc, struct asc_board, \ |
3937 | static int asc_ioport[ASC_NUM_IOPORT_PROBE] = { 0, 0, 0, 0 }; | 2409 | dvc_var.asc_dvc_var) |
2410 | #define adv_dvc_to_board(adv_dvc) container_of(adv_dvc, struct asc_board, \ | ||
2411 | dvc_var.adv_dvc_var) | ||
2412 | #define adv_dvc_to_pdev(adv_dvc) to_pci_dev(adv_dvc_to_board(adv_dvc)->dev) | ||
3938 | 2413 | ||
3939 | #ifdef ADVANSYS_DEBUG | 2414 | #ifdef ADVANSYS_DEBUG |
3940 | static char *asc_bus_name[ASC_NUM_BUS] = { | ||
3941 | "ASC_IS_ISA", | ||
3942 | "ASC_IS_VL", | ||
3943 | "ASC_IS_EISA", | ||
3944 | "ASC_IS_PCI", | ||
3945 | }; | ||
3946 | |||
3947 | static int asc_dbglvl = 3; | 2415 | static int asc_dbglvl = 3; |
3948 | #endif /* ADVANSYS_DEBUG */ | ||
3949 | |||
3950 | /* Declaration for Asc Library internal data referenced by driver. */ | ||
3951 | static PortAddr _asc_def_iop_base[]; | ||
3952 | |||
3953 | /* | ||
3954 | * --- Driver Function Prototypes | ||
3955 | * | ||
3956 | * advansys.h contains function prototypes for functions global to Linux. | ||
3957 | */ | ||
3958 | |||
3959 | static irqreturn_t advansys_interrupt(int, void *); | ||
3960 | static int advansys_slave_configure(struct scsi_device *); | ||
3961 | static void asc_scsi_done_list(struct scsi_cmnd *); | ||
3962 | static int asc_execute_scsi_cmnd(struct scsi_cmnd *); | ||
3963 | static int asc_build_req(asc_board_t *, struct scsi_cmnd *); | ||
3964 | static int adv_build_req(asc_board_t *, struct scsi_cmnd *, ADV_SCSI_REQ_Q **); | ||
3965 | static int adv_get_sglist(asc_board_t *, adv_req_t *, struct scsi_cmnd *, int); | ||
3966 | static void asc_isr_callback(ASC_DVC_VAR *, ASC_QDONE_INFO *); | ||
3967 | static void adv_isr_callback(ADV_DVC_VAR *, ADV_SCSI_REQ_Q *); | ||
3968 | static void adv_async_callback(ADV_DVC_VAR *, uchar); | ||
3969 | static void asc_enqueue(asc_queue_t *, REQP, int); | ||
3970 | static REQP asc_dequeue(asc_queue_t *, int); | ||
3971 | static REQP asc_dequeue_list(asc_queue_t *, REQP *, int); | ||
3972 | static int asc_rmqueue(asc_queue_t *, REQP); | ||
3973 | static void asc_execute_queue(asc_queue_t *); | ||
3974 | #ifdef CONFIG_PROC_FS | ||
3975 | static int asc_proc_copy(off_t, off_t, char *, int, char *, int); | ||
3976 | static int asc_prt_board_devices(struct Scsi_Host *, char *, int); | ||
3977 | static int asc_prt_adv_bios(struct Scsi_Host *, char *, int); | ||
3978 | static int asc_get_eeprom_string(ushort *serialnum, uchar *cp); | ||
3979 | static int asc_prt_asc_board_eeprom(struct Scsi_Host *, char *, int); | ||
3980 | static int asc_prt_adv_board_eeprom(struct Scsi_Host *, char *, int); | ||
3981 | static int asc_prt_driver_conf(struct Scsi_Host *, char *, int); | ||
3982 | static int asc_prt_asc_board_info(struct Scsi_Host *, char *, int); | ||
3983 | static int asc_prt_adv_board_info(struct Scsi_Host *, char *, int); | ||
3984 | static int asc_prt_line(char *, int, char *fmt, ...); | ||
3985 | #endif /* CONFIG_PROC_FS */ | ||
3986 | |||
3987 | /* Declaration for Asc Library internal functions referenced by driver. */ | ||
3988 | static int AscFindSignature(PortAddr); | ||
3989 | static ushort AscGetEEPConfig(PortAddr, ASCEEP_CONFIG *, ushort); | ||
3990 | |||
3991 | /* Statistics function prototypes. */ | ||
3992 | #ifdef ADVANSYS_STATS | ||
3993 | #ifdef CONFIG_PROC_FS | ||
3994 | static int asc_prt_board_stats(struct Scsi_Host *, char *, int); | ||
3995 | static int asc_prt_target_stats(struct Scsi_Host *, int, char *, int); | ||
3996 | #endif /* CONFIG_PROC_FS */ | ||
3997 | #endif /* ADVANSYS_STATS */ | ||
3998 | |||
3999 | /* Debug function prototypes. */ | ||
4000 | #ifdef ADVANSYS_DEBUG | ||
4001 | static void asc_prt_scsi_host(struct Scsi_Host *); | ||
4002 | static void asc_prt_scsi_cmnd(struct scsi_cmnd *); | ||
4003 | static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *); | ||
4004 | static void asc_prt_asc_dvc_var(ASC_DVC_VAR *); | ||
4005 | static void asc_prt_asc_scsi_q(ASC_SCSI_Q *); | ||
4006 | static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *); | ||
4007 | static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *); | ||
4008 | static void asc_prt_adv_dvc_var(ADV_DVC_VAR *); | ||
4009 | static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *); | ||
4010 | static void asc_prt_adv_sgblock(int, ADV_SG_BLOCK *); | ||
4011 | static void asc_prt_hex(char *f, uchar *, int); | ||
4012 | #endif /* ADVANSYS_DEBUG */ | ||
4013 | 2416 | ||
4014 | #ifdef CONFIG_PROC_FS | ||
4015 | /* | 2417 | /* |
4016 | * advansys_proc_info() - /proc/scsi/advansys/[0-(ASC_NUM_BOARD_SUPPORTED-1)] | 2418 | * asc_prt_asc_dvc_var() |
4017 | * | ||
4018 | * *buffer: I/O buffer | ||
4019 | * **start: if inout == FALSE pointer into buffer where user read should start | ||
4020 | * offset: current offset into a /proc/scsi/advansys/[0...] file | ||
4021 | * length: length of buffer | ||
4022 | * hostno: Scsi_Host host_no | ||
4023 | * inout: TRUE - user is writing; FALSE - user is reading | ||
4024 | * | ||
4025 | * Return the number of bytes read from or written to a | ||
4026 | * /proc/scsi/advansys/[0...] file. | ||
4027 | * | ||
4028 | * Note: This function uses the per board buffer 'prtbuf' which is | ||
4029 | * allocated when the board is initialized in advansys_detect(). The | ||
4030 | * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is | ||
4031 | * used to write to the buffer. The way asc_proc_copy() is written | ||
4032 | * if 'prtbuf' is too small it will not be overwritten. Instead the | ||
4033 | * user just won't get all the available statistics. | ||
4034 | */ | 2419 | */ |
4035 | static int | 2420 | static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h) |
4036 | advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | ||
4037 | off_t offset, int length, int inout) | ||
4038 | { | 2421 | { |
4039 | struct Scsi_Host *shp; | 2422 | printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h); |
4040 | asc_board_t *boardp; | ||
4041 | int i; | ||
4042 | char *cp; | ||
4043 | int cplen; | ||
4044 | int cnt; | ||
4045 | int totcnt; | ||
4046 | int leftlen; | ||
4047 | char *curbuf; | ||
4048 | off_t advoffset; | ||
4049 | #ifdef ADVANSYS_STATS | ||
4050 | int tgt_id; | ||
4051 | #endif /* ADVANSYS_STATS */ | ||
4052 | |||
4053 | ASC_DBG(1, "advansys_proc_info: begin\n"); | ||
4054 | |||
4055 | /* | ||
4056 | * User write not supported. | ||
4057 | */ | ||
4058 | if (inout == TRUE) { | ||
4059 | return (-ENOSYS); | ||
4060 | } | ||
4061 | |||
4062 | /* | ||
4063 | * User read of /proc/scsi/advansys/[0...] file. | ||
4064 | */ | ||
4065 | |||
4066 | /* Find the specified board. */ | ||
4067 | for (i = 0; i < asc_board_count; i++) { | ||
4068 | if (asc_host[i]->host_no == shost->host_no) { | ||
4069 | break; | ||
4070 | } | ||
4071 | } | ||
4072 | if (i == asc_board_count) { | ||
4073 | return (-ENOENT); | ||
4074 | } | ||
4075 | |||
4076 | shp = asc_host[i]; | ||
4077 | boardp = ASC_BOARDP(shp); | ||
4078 | |||
4079 | /* Copy read data starting at the beginning of the buffer. */ | ||
4080 | *start = buffer; | ||
4081 | curbuf = buffer; | ||
4082 | advoffset = 0; | ||
4083 | totcnt = 0; | ||
4084 | leftlen = length; | ||
4085 | |||
4086 | /* | ||
4087 | * Get board configuration information. | ||
4088 | * | ||
4089 | * advansys_info() returns the board string from its own static buffer. | ||
4090 | */ | ||
4091 | cp = (char *)advansys_info(shp); | ||
4092 | strcat(cp, "\n"); | ||
4093 | cplen = strlen(cp); | ||
4094 | /* Copy board information. */ | ||
4095 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4096 | totcnt += cnt; | ||
4097 | leftlen -= cnt; | ||
4098 | if (leftlen == 0) { | ||
4099 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | ||
4100 | return totcnt; | ||
4101 | } | ||
4102 | advoffset += cplen; | ||
4103 | curbuf += cnt; | ||
4104 | |||
4105 | /* | ||
4106 | * Display Wide Board BIOS Information. | ||
4107 | */ | ||
4108 | if (ASC_WIDE_BOARD(boardp)) { | ||
4109 | cp = boardp->prtbuf; | ||
4110 | cplen = asc_prt_adv_bios(shp, cp, ASC_PRTBUF_SIZE); | ||
4111 | ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); | ||
4112 | cnt = | ||
4113 | asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, | ||
4114 | cplen); | ||
4115 | totcnt += cnt; | ||
4116 | leftlen -= cnt; | ||
4117 | if (leftlen == 0) { | ||
4118 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | ||
4119 | return totcnt; | ||
4120 | } | ||
4121 | advoffset += cplen; | ||
4122 | curbuf += cnt; | ||
4123 | } | ||
4124 | |||
4125 | /* | ||
4126 | * Display driver information for each device attached to the board. | ||
4127 | */ | ||
4128 | cp = boardp->prtbuf; | ||
4129 | cplen = asc_prt_board_devices(shp, cp, ASC_PRTBUF_SIZE); | ||
4130 | ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); | ||
4131 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4132 | totcnt += cnt; | ||
4133 | leftlen -= cnt; | ||
4134 | if (leftlen == 0) { | ||
4135 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | ||
4136 | return totcnt; | ||
4137 | } | ||
4138 | advoffset += cplen; | ||
4139 | curbuf += cnt; | ||
4140 | |||
4141 | /* | ||
4142 | * Display EEPROM configuration for the board. | ||
4143 | */ | ||
4144 | cp = boardp->prtbuf; | ||
4145 | if (ASC_NARROW_BOARD(boardp)) { | ||
4146 | cplen = asc_prt_asc_board_eeprom(shp, cp, ASC_PRTBUF_SIZE); | ||
4147 | } else { | ||
4148 | cplen = asc_prt_adv_board_eeprom(shp, cp, ASC_PRTBUF_SIZE); | ||
4149 | } | ||
4150 | ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); | ||
4151 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4152 | totcnt += cnt; | ||
4153 | leftlen -= cnt; | ||
4154 | if (leftlen == 0) { | ||
4155 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | ||
4156 | return totcnt; | ||
4157 | } | ||
4158 | advoffset += cplen; | ||
4159 | curbuf += cnt; | ||
4160 | |||
4161 | /* | ||
4162 | * Display driver configuration and information for the board. | ||
4163 | */ | ||
4164 | cp = boardp->prtbuf; | ||
4165 | cplen = asc_prt_driver_conf(shp, cp, ASC_PRTBUF_SIZE); | ||
4166 | ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); | ||
4167 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4168 | totcnt += cnt; | ||
4169 | leftlen -= cnt; | ||
4170 | if (leftlen == 0) { | ||
4171 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | ||
4172 | return totcnt; | ||
4173 | } | ||
4174 | advoffset += cplen; | ||
4175 | curbuf += cnt; | ||
4176 | 2423 | ||
4177 | #ifdef ADVANSYS_STATS | 2424 | printk(" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl " |
4178 | /* | 2425 | "%d,\n", h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl); |
4179 | * Display driver statistics for the board. | ||
4180 | */ | ||
4181 | cp = boardp->prtbuf; | ||
4182 | cplen = asc_prt_board_stats(shp, cp, ASC_PRTBUF_SIZE); | ||
4183 | ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE); | ||
4184 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4185 | totcnt += cnt; | ||
4186 | leftlen -= cnt; | ||
4187 | if (leftlen == 0) { | ||
4188 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | ||
4189 | return totcnt; | ||
4190 | } | ||
4191 | advoffset += cplen; | ||
4192 | curbuf += cnt; | ||
4193 | 2426 | ||
4194 | /* | 2427 | printk(" bus_type %d, init_sdtr 0x%x,\n", h->bus_type, |
4195 | * Display driver statistics for each target. | 2428 | (unsigned)h->init_sdtr); |
4196 | */ | ||
4197 | for (tgt_id = 0; tgt_id <= ADV_MAX_TID; tgt_id++) { | ||
4198 | cp = boardp->prtbuf; | ||
4199 | cplen = asc_prt_target_stats(shp, tgt_id, cp, ASC_PRTBUF_SIZE); | ||
4200 | ASC_ASSERT(cplen <= ASC_PRTBUF_SIZE); | ||
4201 | cnt = | ||
4202 | asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, | ||
4203 | cplen); | ||
4204 | totcnt += cnt; | ||
4205 | leftlen -= cnt; | ||
4206 | if (leftlen == 0) { | ||
4207 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | ||
4208 | return totcnt; | ||
4209 | } | ||
4210 | advoffset += cplen; | ||
4211 | curbuf += cnt; | ||
4212 | } | ||
4213 | #endif /* ADVANSYS_STATS */ | ||
4214 | 2429 | ||
4215 | /* | 2430 | printk(" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, " |
4216 | * Display Asc Library dynamic configuration information | 2431 | "chip_no 0x%x,\n", (unsigned)h->sdtr_done, |
4217 | * for the board. | 2432 | (unsigned)h->use_tagged_qng, (unsigned)h->unit_not_ready, |
4218 | */ | 2433 | (unsigned)h->chip_no); |
4219 | cp = boardp->prtbuf; | ||
4220 | if (ASC_NARROW_BOARD(boardp)) { | ||
4221 | cplen = asc_prt_asc_board_info(shp, cp, ASC_PRTBUF_SIZE); | ||
4222 | } else { | ||
4223 | cplen = asc_prt_adv_board_info(shp, cp, ASC_PRTBUF_SIZE); | ||
4224 | } | ||
4225 | ASC_ASSERT(cplen < ASC_PRTBUF_SIZE); | ||
4226 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4227 | totcnt += cnt; | ||
4228 | leftlen -= cnt; | ||
4229 | if (leftlen == 0) { | ||
4230 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | ||
4231 | return totcnt; | ||
4232 | } | ||
4233 | advoffset += cplen; | ||
4234 | curbuf += cnt; | ||
4235 | 2434 | ||
4236 | ASC_DBG1(1, "advansys_proc_info: totcnt %d\n", totcnt); | 2435 | printk(" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait " |
2436 | "%u,\n", (unsigned)h->queue_full_or_busy, | ||
2437 | (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait); | ||
4237 | 2438 | ||
4238 | return totcnt; | 2439 | printk(" is_in_int %u, max_total_qng %u, cur_total_qng %u, " |
4239 | } | 2440 | "in_critical_cnt %u,\n", (unsigned)h->is_in_int, |
4240 | #endif /* CONFIG_PROC_FS */ | 2441 | (unsigned)h->max_total_qng, (unsigned)h->cur_total_qng, |
2442 | (unsigned)h->in_critical_cnt); | ||
4241 | 2443 | ||
4242 | /* | 2444 | printk(" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, " |
4243 | * advansys_info() | 2445 | "pci_fix_asyn_xfer 0x%x,\n", (unsigned)h->last_q_shortage, |
4244 | * | 2446 | (unsigned)h->init_state, (unsigned)h->no_scam, |
4245 | * Return suitable for printing on the console with the argument | 2447 | (unsigned)h->pci_fix_asyn_xfer); |
4246 | * adapter's configuration information. | ||
4247 | * | ||
4248 | * Note: The information line should not exceed ASC_INFO_SIZE bytes, | ||
4249 | * otherwise the static 'info' array will be overrun. | ||
4250 | */ | ||
4251 | static const char *advansys_info(struct Scsi_Host *shost) | ||
4252 | { | ||
4253 | static char info[ASC_INFO_SIZE]; | ||
4254 | asc_board_t *boardp; | ||
4255 | ASC_DVC_VAR *asc_dvc_varp; | ||
4256 | ADV_DVC_VAR *adv_dvc_varp; | ||
4257 | char *busname; | ||
4258 | int iolen; | ||
4259 | char *widename = NULL; | ||
4260 | 2448 | ||
4261 | boardp = ASC_BOARDP(shost); | 2449 | printk(" cfg 0x%lx\n", (ulong)h->cfg); |
4262 | if (ASC_NARROW_BOARD(boardp)) { | ||
4263 | asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; | ||
4264 | ASC_DBG(1, "advansys_info: begin\n"); | ||
4265 | if (asc_dvc_varp->bus_type & ASC_IS_ISA) { | ||
4266 | if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == | ||
4267 | ASC_IS_ISAPNP) { | ||
4268 | busname = "ISA PnP"; | ||
4269 | } else { | ||
4270 | busname = "ISA"; | ||
4271 | } | ||
4272 | /* Don't reference 'shost->n_io_port'; It may be truncated. */ | ||
4273 | sprintf(info, | ||
4274 | "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X", | ||
4275 | ASC_VERSION, busname, | ||
4276 | (ulong)shost->io_port, | ||
4277 | (ulong)shost->io_port + boardp->asc_n_io_port - | ||
4278 | 1, shost->irq, shost->dma_channel); | ||
4279 | } else { | ||
4280 | if (asc_dvc_varp->bus_type & ASC_IS_VL) { | ||
4281 | busname = "VL"; | ||
4282 | } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) { | ||
4283 | busname = "EISA"; | ||
4284 | } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) { | ||
4285 | if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA) | ||
4286 | == ASC_IS_PCI_ULTRA) { | ||
4287 | busname = "PCI Ultra"; | ||
4288 | } else { | ||
4289 | busname = "PCI"; | ||
4290 | } | ||
4291 | } else { | ||
4292 | busname = "?"; | ||
4293 | ASC_PRINT2 | ||
4294 | ("advansys_info: board %d: unknown bus type %d\n", | ||
4295 | boardp->id, asc_dvc_varp->bus_type); | ||
4296 | } | ||
4297 | /* Don't reference 'shost->n_io_port'; It may be truncated. */ | ||
4298 | sprintf(info, | ||
4299 | "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X", | ||
4300 | ASC_VERSION, busname, | ||
4301 | (ulong)shost->io_port, | ||
4302 | (ulong)shost->io_port + boardp->asc_n_io_port - | ||
4303 | 1, shost->irq); | ||
4304 | } | ||
4305 | } else { | ||
4306 | /* | ||
4307 | * Wide Adapter Information | ||
4308 | * | ||
4309 | * Memory-mapped I/O is used instead of I/O space to access | ||
4310 | * the adapter, but display the I/O Port range. The Memory | ||
4311 | * I/O address is displayed through the driver /proc file. | ||
4312 | */ | ||
4313 | adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; | ||
4314 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { | ||
4315 | iolen = ADV_3550_IOLEN; | ||
4316 | widename = "Ultra-Wide"; | ||
4317 | } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { | ||
4318 | iolen = ADV_38C0800_IOLEN; | ||
4319 | widename = "Ultra2-Wide"; | ||
4320 | } else { | ||
4321 | iolen = ADV_38C1600_IOLEN; | ||
4322 | widename = "Ultra3-Wide"; | ||
4323 | } | ||
4324 | sprintf(info, | ||
4325 | "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X", | ||
4326 | ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base, | ||
4327 | (ulong)adv_dvc_varp->iop_base + iolen - 1, shost->irq); | ||
4328 | } | ||
4329 | ASC_ASSERT(strlen(info) < ASC_INFO_SIZE); | ||
4330 | ASC_DBG(1, "advansys_info: end\n"); | ||
4331 | return info; | ||
4332 | } | 2450 | } |
4333 | 2451 | ||
4334 | /* | 2452 | /* |
4335 | * advansys_queuecommand() - interrupt-driven I/O entrypoint. | 2453 | * asc_prt_asc_dvc_cfg() |
4336 | * | ||
4337 | * This function always returns 0. Command return status is saved | ||
4338 | * in the 'scp' result field. | ||
4339 | */ | 2454 | */ |
4340 | static int | 2455 | static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h) |
4341 | advansys_queuecommand(struct scsi_cmnd *scp, void (*done) (struct scsi_cmnd *)) | ||
4342 | { | 2456 | { |
4343 | struct Scsi_Host *shost; | 2457 | printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h); |
4344 | asc_board_t *boardp; | ||
4345 | ulong flags; | ||
4346 | struct scsi_cmnd *done_scp; | ||
4347 | |||
4348 | shost = scp->device->host; | ||
4349 | boardp = ASC_BOARDP(shost); | ||
4350 | ASC_STATS(shost, queuecommand); | ||
4351 | |||
4352 | /* host_lock taken by mid-level prior to call but need to protect */ | ||
4353 | /* against own ISR */ | ||
4354 | spin_lock_irqsave(&boardp->lock, flags); | ||
4355 | |||
4356 | /* | ||
4357 | * Block new commands while handling a reset or abort request. | ||
4358 | */ | ||
4359 | if (boardp->flags & ASC_HOST_IN_RESET) { | ||
4360 | ASC_DBG1(1, | ||
4361 | "advansys_queuecommand: scp 0x%lx blocked for reset request\n", | ||
4362 | (ulong)scp); | ||
4363 | scp->result = HOST_BYTE(DID_RESET); | ||
4364 | |||
4365 | /* | ||
4366 | * Add blocked requests to the board's 'done' queue. The queued | ||
4367 | * requests will be completed at the end of the abort or reset | ||
4368 | * handling. | ||
4369 | */ | ||
4370 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
4371 | spin_unlock_irqrestore(&boardp->lock, flags); | ||
4372 | return 0; | ||
4373 | } | ||
4374 | 2458 | ||
4375 | /* | 2459 | printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n", |
4376 | * Attempt to execute any waiting commands for the board. | 2460 | h->can_tagged_qng, h->cmd_qng_enabled); |
4377 | */ | 2461 | printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n", |
4378 | if (!ASC_QUEUE_EMPTY(&boardp->waiting)) { | 2462 | h->disc_enable, h->sdtr_enable); |
4379 | ASC_DBG(1, | ||
4380 | "advansys_queuecommand: before asc_execute_queue() waiting\n"); | ||
4381 | asc_execute_queue(&boardp->waiting); | ||
4382 | } | ||
4383 | 2463 | ||
4384 | /* | 2464 | printk(" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, " |
4385 | * Save the function pointer to Linux mid-level 'done' function | 2465 | "chip_version %d,\n", h->chip_scsi_id, h->isa_dma_speed, |
4386 | * and attempt to execute the command. | 2466 | h->isa_dma_channel, h->chip_version); |
4387 | * | ||
4388 | * If ASC_NOERROR is returned the request has been added to the | ||
4389 | * board's 'active' queue and will be completed by the interrupt | ||
4390 | * handler. | ||
4391 | * | ||
4392 | * If ASC_BUSY is returned add the request to the board's per | ||
4393 | * target waiting list. This is the first time the request has | ||
4394 | * been tried. Add it to the back of the waiting list. It will be | ||
4395 | * retried later. | ||
4396 | * | ||
4397 | * If an error occurred, the request will have been placed on the | ||
4398 | * board's 'done' queue and must be completed before returning. | ||
4399 | */ | ||
4400 | scp->scsi_done = done; | ||
4401 | switch (asc_execute_scsi_cmnd(scp)) { | ||
4402 | case ASC_NOERROR: | ||
4403 | break; | ||
4404 | case ASC_BUSY: | ||
4405 | asc_enqueue(&boardp->waiting, scp, ASC_BACK); | ||
4406 | break; | ||
4407 | case ASC_ERROR: | ||
4408 | default: | ||
4409 | done_scp = asc_dequeue_list(&boardp->done, NULL, ASC_TID_ALL); | ||
4410 | /* Interrupts could be enabled here. */ | ||
4411 | asc_scsi_done_list(done_scp); | ||
4412 | break; | ||
4413 | } | ||
4414 | spin_unlock_irqrestore(&boardp->lock, flags); | ||
4415 | 2467 | ||
4416 | return 0; | 2468 | printk(" mcode_date 0x%x, mcode_version %d\n", |
2469 | h->mcode_date, h->mcode_version); | ||
4417 | } | 2470 | } |
4418 | 2471 | ||
4419 | /* | 2472 | /* |
4420 | * advansys_reset() | 2473 | * asc_prt_adv_dvc_var() |
4421 | * | ||
4422 | * Reset the bus associated with the command 'scp'. | ||
4423 | * | 2474 | * |
4424 | * This function runs its own thread. Interrupts must be blocked but | 2475 | * Display an ADV_DVC_VAR structure. |
4425 | * sleeping is allowed and no locking other than for host structures is | ||
4426 | * required. Returns SUCCESS or FAILED. | ||
4427 | */ | 2476 | */ |
4428 | static int advansys_reset(struct scsi_cmnd *scp) | 2477 | static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h) |
4429 | { | 2478 | { |
4430 | struct Scsi_Host *shost; | 2479 | printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h); |
4431 | asc_board_t *boardp; | ||
4432 | ASC_DVC_VAR *asc_dvc_varp; | ||
4433 | ADV_DVC_VAR *adv_dvc_varp; | ||
4434 | ulong flags; | ||
4435 | struct scsi_cmnd *done_scp = NULL, *last_scp = NULL; | ||
4436 | struct scsi_cmnd *tscp, *new_last_scp; | ||
4437 | int status; | ||
4438 | int ret = SUCCESS; | ||
4439 | |||
4440 | ASC_DBG1(1, "advansys_reset: 0x%lx\n", (ulong)scp); | ||
4441 | |||
4442 | #ifdef ADVANSYS_STATS | ||
4443 | if (scp->device->host != NULL) { | ||
4444 | ASC_STATS(scp->device->host, reset); | ||
4445 | } | ||
4446 | #endif /* ADVANSYS_STATS */ | ||
4447 | |||
4448 | if ((shost = scp->device->host) == NULL) { | ||
4449 | scp->result = HOST_BYTE(DID_ERROR); | ||
4450 | return FAILED; | ||
4451 | } | ||
4452 | |||
4453 | boardp = ASC_BOARDP(shost); | ||
4454 | |||
4455 | ASC_PRINT1("advansys_reset: board %d: SCSI bus reset started...\n", | ||
4456 | boardp->id); | ||
4457 | /* | ||
4458 | * Check for re-entrancy. | ||
4459 | */ | ||
4460 | spin_lock_irqsave(&boardp->lock, flags); | ||
4461 | if (boardp->flags & ASC_HOST_IN_RESET) { | ||
4462 | spin_unlock_irqrestore(&boardp->lock, flags); | ||
4463 | return FAILED; | ||
4464 | } | ||
4465 | boardp->flags |= ASC_HOST_IN_RESET; | ||
4466 | spin_unlock_irqrestore(&boardp->lock, flags); | ||
4467 | |||
4468 | if (ASC_NARROW_BOARD(boardp)) { | ||
4469 | /* | ||
4470 | * Narrow Board | ||
4471 | */ | ||
4472 | asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; | ||
4473 | |||
4474 | /* | ||
4475 | * Reset the chip and SCSI bus. | ||
4476 | */ | ||
4477 | ASC_DBG(1, "advansys_reset: before AscInitAsc1000Driver()\n"); | ||
4478 | status = AscInitAsc1000Driver(asc_dvc_varp); | ||
4479 | |||
4480 | /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */ | ||
4481 | if (asc_dvc_varp->err_code) { | ||
4482 | ASC_PRINT2 | ||
4483 | ("advansys_reset: board %d: SCSI bus reset error: 0x%x\n", | ||
4484 | boardp->id, asc_dvc_varp->err_code); | ||
4485 | ret = FAILED; | ||
4486 | } else if (status) { | ||
4487 | ASC_PRINT2 | ||
4488 | ("advansys_reset: board %d: SCSI bus reset warning: 0x%x\n", | ||
4489 | boardp->id, status); | ||
4490 | } else { | ||
4491 | ASC_PRINT1 | ||
4492 | ("advansys_reset: board %d: SCSI bus reset successful.\n", | ||
4493 | boardp->id); | ||
4494 | } | ||
4495 | |||
4496 | ASC_DBG(1, "advansys_reset: after AscInitAsc1000Driver()\n"); | ||
4497 | spin_lock_irqsave(&boardp->lock, flags); | ||
4498 | |||
4499 | } else { | ||
4500 | /* | ||
4501 | * Wide Board | ||
4502 | * | ||
4503 | * If the suggest reset bus flags are set, then reset the bus. | ||
4504 | * Otherwise only reset the device. | ||
4505 | */ | ||
4506 | adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; | ||
4507 | |||
4508 | /* | ||
4509 | * Reset the target's SCSI bus. | ||
4510 | */ | ||
4511 | ASC_DBG(1, "advansys_reset: before AdvResetChipAndSB()\n"); | ||
4512 | switch (AdvResetChipAndSB(adv_dvc_varp)) { | ||
4513 | case ASC_TRUE: | ||
4514 | ASC_PRINT1 | ||
4515 | ("advansys_reset: board %d: SCSI bus reset successful.\n", | ||
4516 | boardp->id); | ||
4517 | break; | ||
4518 | case ASC_FALSE: | ||
4519 | default: | ||
4520 | ASC_PRINT1 | ||
4521 | ("advansys_reset: board %d: SCSI bus reset error.\n", | ||
4522 | boardp->id); | ||
4523 | ret = FAILED; | ||
4524 | break; | ||
4525 | } | ||
4526 | spin_lock_irqsave(&boardp->lock, flags); | ||
4527 | (void)AdvISR(adv_dvc_varp); | ||
4528 | } | ||
4529 | /* Board lock is held. */ | ||
4530 | |||
4531 | /* | ||
4532 | * Dequeue all board 'done' requests. A pointer to the last request | ||
4533 | * is returned in 'last_scp'. | ||
4534 | */ | ||
4535 | done_scp = asc_dequeue_list(&boardp->done, &last_scp, ASC_TID_ALL); | ||
4536 | |||
4537 | /* | ||
4538 | * Dequeue all board 'active' requests for all devices and set | ||
4539 | * the request status to DID_RESET. A pointer to the last request | ||
4540 | * is returned in 'last_scp'. | ||
4541 | */ | ||
4542 | if (done_scp == NULL) { | ||
4543 | done_scp = | ||
4544 | asc_dequeue_list(&boardp->active, &last_scp, ASC_TID_ALL); | ||
4545 | for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) { | ||
4546 | tscp->result = HOST_BYTE(DID_RESET); | ||
4547 | } | ||
4548 | } else { | ||
4549 | /* Append to 'done_scp' at the end with 'last_scp'. */ | ||
4550 | ASC_ASSERT(last_scp != NULL); | ||
4551 | last_scp->host_scribble = | ||
4552 | (unsigned char *)asc_dequeue_list(&boardp->active, | ||
4553 | &new_last_scp, | ||
4554 | ASC_TID_ALL); | ||
4555 | if (new_last_scp != NULL) { | ||
4556 | ASC_ASSERT(REQPNEXT(last_scp) != NULL); | ||
4557 | for (tscp = REQPNEXT(last_scp); tscp; | ||
4558 | tscp = REQPNEXT(tscp)) { | ||
4559 | tscp->result = HOST_BYTE(DID_RESET); | ||
4560 | } | ||
4561 | last_scp = new_last_scp; | ||
4562 | } | ||
4563 | } | ||
4564 | |||
4565 | /* | ||
4566 | * Dequeue all 'waiting' requests and set the request status | ||
4567 | * to DID_RESET. | ||
4568 | */ | ||
4569 | if (done_scp == NULL) { | ||
4570 | done_scp = | ||
4571 | asc_dequeue_list(&boardp->waiting, &last_scp, ASC_TID_ALL); | ||
4572 | for (tscp = done_scp; tscp; tscp = REQPNEXT(tscp)) { | ||
4573 | tscp->result = HOST_BYTE(DID_RESET); | ||
4574 | } | ||
4575 | } else { | ||
4576 | /* Append to 'done_scp' at the end with 'last_scp'. */ | ||
4577 | ASC_ASSERT(last_scp != NULL); | ||
4578 | last_scp->host_scribble = | ||
4579 | (unsigned char *)asc_dequeue_list(&boardp->waiting, | ||
4580 | &new_last_scp, | ||
4581 | ASC_TID_ALL); | ||
4582 | if (new_last_scp != NULL) { | ||
4583 | ASC_ASSERT(REQPNEXT(last_scp) != NULL); | ||
4584 | for (tscp = REQPNEXT(last_scp); tscp; | ||
4585 | tscp = REQPNEXT(tscp)) { | ||
4586 | tscp->result = HOST_BYTE(DID_RESET); | ||
4587 | } | ||
4588 | last_scp = new_last_scp; | ||
4589 | } | ||
4590 | } | ||
4591 | 2480 | ||
4592 | /* Save the time of the most recently completed reset. */ | 2481 | printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n", |
4593 | boardp->last_reset = jiffies; | 2482 | (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able); |
4594 | 2483 | ||
4595 | /* Clear reset flag. */ | 2484 | printk(" sdtr_able 0x%x, wdtr_able 0x%x\n", |
4596 | boardp->flags &= ~ASC_HOST_IN_RESET; | 2485 | (unsigned)h->sdtr_able, (unsigned)h->wdtr_able); |
4597 | spin_unlock_irqrestore(&boardp->lock, flags); | ||
4598 | 2486 | ||
4599 | /* | 2487 | printk(" start_motor 0x%x, scsi_reset_wait 0x%x\n", |
4600 | * Complete all the 'done_scp' requests. | 2488 | (unsigned)h->start_motor, (unsigned)h->scsi_reset_wait); |
4601 | */ | ||
4602 | if (done_scp != NULL) { | ||
4603 | asc_scsi_done_list(done_scp); | ||
4604 | } | ||
4605 | 2489 | ||
4606 | ASC_DBG1(1, "advansys_reset: ret %d\n", ret); | 2490 | printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n", |
2491 | (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng, | ||
2492 | (ulong)h->carr_freelist); | ||
4607 | 2493 | ||
4608 | return ret; | 2494 | printk(" icq_sp 0x%lx, irq_sp 0x%lx\n", |
4609 | } | 2495 | (ulong)h->icq_sp, (ulong)h->irq_sp); |
4610 | 2496 | ||
4611 | /* | 2497 | printk(" no_scam 0x%x, tagqng_able 0x%x\n", |
4612 | * advansys_biosparam() | 2498 | (unsigned)h->no_scam, (unsigned)h->tagqng_able); |
4613 | * | ||
4614 | * Translate disk drive geometry if the "BIOS greater than 1 GB" | ||
4615 | * support is enabled for a drive. | ||
4616 | * | ||
4617 | * ip (information pointer) is an int array with the following definition: | ||
4618 | * ip[0]: heads | ||
4619 | * ip[1]: sectors | ||
4620 | * ip[2]: cylinders | ||
4621 | */ | ||
4622 | static int | ||
4623 | advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev, | ||
4624 | sector_t capacity, int ip[]) | ||
4625 | { | ||
4626 | asc_board_t *boardp; | ||
4627 | 2499 | ||
4628 | ASC_DBG(1, "advansys_biosparam: begin\n"); | 2500 | printk(" chip_scsi_id 0x%x, cfg 0x%lx\n", |
4629 | ASC_STATS(sdev->host, biosparam); | 2501 | (unsigned)h->chip_scsi_id, (ulong)h->cfg); |
4630 | boardp = ASC_BOARDP(sdev->host); | ||
4631 | if (ASC_NARROW_BOARD(boardp)) { | ||
4632 | if ((boardp->dvc_var.asc_dvc_var.dvc_cntl & | ||
4633 | ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) { | ||
4634 | ip[0] = 255; | ||
4635 | ip[1] = 63; | ||
4636 | } else { | ||
4637 | ip[0] = 64; | ||
4638 | ip[1] = 32; | ||
4639 | } | ||
4640 | } else { | ||
4641 | if ((boardp->dvc_var.adv_dvc_var.bios_ctrl & | ||
4642 | BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) { | ||
4643 | ip[0] = 255; | ||
4644 | ip[1] = 63; | ||
4645 | } else { | ||
4646 | ip[0] = 64; | ||
4647 | ip[1] = 32; | ||
4648 | } | ||
4649 | } | ||
4650 | ip[2] = (unsigned long)capacity / (ip[0] * ip[1]); | ||
4651 | ASC_DBG(1, "advansys_biosparam: end\n"); | ||
4652 | return 0; | ||
4653 | } | 2502 | } |
4654 | 2503 | ||
4655 | static int __init advansys_detect(struct scsi_host_template *tpnt); | ||
4656 | static int advansys_release(struct Scsi_Host *shp); | ||
4657 | |||
4658 | static struct scsi_host_template driver_template = { | ||
4659 | .proc_name = "advansys", | ||
4660 | #ifdef CONFIG_PROC_FS | ||
4661 | .proc_info = advansys_proc_info, | ||
4662 | #endif | ||
4663 | .name = "advansys", | ||
4664 | .detect = advansys_detect, | ||
4665 | .release = advansys_release, | ||
4666 | .info = advansys_info, | ||
4667 | .queuecommand = advansys_queuecommand, | ||
4668 | .eh_bus_reset_handler = advansys_reset, | ||
4669 | .bios_param = advansys_biosparam, | ||
4670 | .slave_configure = advansys_slave_configure, | ||
4671 | /* | ||
4672 | * Because the driver may control an ISA adapter 'unchecked_isa_dma' | ||
4673 | * must be set. The flag will be cleared in advansys_detect for non-ISA | ||
4674 | * adapters. Refer to the comment in scsi_module.c for more information. | ||
4675 | */ | ||
4676 | .unchecked_isa_dma = 1, | ||
4677 | /* | ||
4678 | * All adapters controlled by this driver are capable of large | ||
4679 | * scatter-gather lists. According to the mid-level SCSI documentation | ||
4680 | * this obviates any performance gain provided by setting | ||
4681 | * 'use_clustering'. But empirically while CPU utilization is increased | ||
4682 | * by enabling clustering, I/O throughput increases as well. | ||
4683 | */ | ||
4684 | .use_clustering = ENABLE_CLUSTERING, | ||
4685 | }; | ||
4686 | |||
4687 | #include "scsi_module.c" | ||
4688 | |||
4689 | /* | ||
4690 | * --- Miscellaneous Driver Functions | ||
4691 | */ | ||
4692 | |||
4693 | /* | 2504 | /* |
4694 | * First-level interrupt handler. | 2505 | * asc_prt_adv_dvc_cfg() |
4695 | * | 2506 | * |
4696 | * 'dev_id' is a pointer to the interrupting adapter's asc_board_t. Because | 2507 | * Display an ADV_DVC_CFG structure. |
4697 | * all boards are currently checked for interrupts on each interrupt, 'dev_id' | ||
4698 | * is not referenced. 'dev_id' could be used to identify an interrupt passed | ||
4699 | * to the AdvanSys driver which is for a device sharing an interrupt with | ||
4700 | * an AdvanSys adapter. | ||
4701 | */ | 2508 | */ |
4702 | static irqreturn_t advansys_interrupt(int irq, void *dev_id) | 2509 | static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h) |
4703 | { | 2510 | { |
4704 | ulong flags; | 2511 | printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h); |
4705 | int i; | ||
4706 | asc_board_t *boardp; | ||
4707 | struct scsi_cmnd *done_scp = NULL, *last_scp = NULL; | ||
4708 | struct scsi_cmnd *new_last_scp; | ||
4709 | struct Scsi_Host *shost; | ||
4710 | |||
4711 | ASC_DBG(1, "advansys_interrupt: begin\n"); | ||
4712 | |||
4713 | /* | ||
4714 | * Check for interrupts on all boards. | ||
4715 | * AscISR() will call asc_isr_callback(). | ||
4716 | */ | ||
4717 | for (i = 0; i < asc_board_count; i++) { | ||
4718 | shost = asc_host[i]; | ||
4719 | boardp = ASC_BOARDP(shost); | ||
4720 | ASC_DBG2(2, "advansys_interrupt: i %d, boardp 0x%lx\n", | ||
4721 | i, (ulong)boardp); | ||
4722 | spin_lock_irqsave(&boardp->lock, flags); | ||
4723 | if (ASC_NARROW_BOARD(boardp)) { | ||
4724 | /* | ||
4725 | * Narrow Board | ||
4726 | */ | ||
4727 | if (AscIsIntPending(shost->io_port)) { | ||
4728 | ASC_STATS(shost, interrupt); | ||
4729 | ASC_DBG(1, | ||
4730 | "advansys_interrupt: before AscISR()\n"); | ||
4731 | AscISR(&boardp->dvc_var.asc_dvc_var); | ||
4732 | } | ||
4733 | } else { | ||
4734 | /* | ||
4735 | * Wide Board | ||
4736 | */ | ||
4737 | ASC_DBG(1, "advansys_interrupt: before AdvISR()\n"); | ||
4738 | if (AdvISR(&boardp->dvc_var.adv_dvc_var)) { | ||
4739 | ASC_STATS(shost, interrupt); | ||
4740 | } | ||
4741 | } | ||
4742 | |||
4743 | /* | ||
4744 | * Start waiting requests and create a list of completed requests. | ||
4745 | * | ||
4746 | * If a reset request is being performed for the board, the reset | ||
4747 | * handler will complete pending requests after it has completed. | ||
4748 | */ | ||
4749 | if ((boardp->flags & ASC_HOST_IN_RESET) == 0) { | ||
4750 | ASC_DBG2(1, | ||
4751 | "advansys_interrupt: done_scp 0x%lx, last_scp 0x%lx\n", | ||
4752 | (ulong)done_scp, (ulong)last_scp); | ||
4753 | |||
4754 | /* Start any waiting commands for the board. */ | ||
4755 | if (!ASC_QUEUE_EMPTY(&boardp->waiting)) { | ||
4756 | ASC_DBG(1, | ||
4757 | "advansys_interrupt: before asc_execute_queue()\n"); | ||
4758 | asc_execute_queue(&boardp->waiting); | ||
4759 | } | ||
4760 | |||
4761 | /* | ||
4762 | * Add to the list of requests that must be completed. | ||
4763 | * | ||
4764 | * 'done_scp' will always be NULL on the first iteration | ||
4765 | * of this loop. 'last_scp' is set at the same time as | ||
4766 | * 'done_scp'. | ||
4767 | */ | ||
4768 | if (done_scp == NULL) { | ||
4769 | done_scp = | ||
4770 | asc_dequeue_list(&boardp->done, &last_scp, | ||
4771 | ASC_TID_ALL); | ||
4772 | } else { | ||
4773 | ASC_ASSERT(last_scp != NULL); | ||
4774 | last_scp->host_scribble = | ||
4775 | (unsigned char *)asc_dequeue_list(&boardp-> | ||
4776 | done, | ||
4777 | &new_last_scp, | ||
4778 | ASC_TID_ALL); | ||
4779 | if (new_last_scp != NULL) { | ||
4780 | ASC_ASSERT(REQPNEXT(last_scp) != NULL); | ||
4781 | last_scp = new_last_scp; | ||
4782 | } | ||
4783 | } | ||
4784 | } | ||
4785 | spin_unlock_irqrestore(&boardp->lock, flags); | ||
4786 | } | ||
4787 | |||
4788 | /* | ||
4789 | * If interrupts were enabled on entry, then they | ||
4790 | * are now enabled here. | ||
4791 | * | ||
4792 | * Complete all requests on the done list. | ||
4793 | */ | ||
4794 | |||
4795 | asc_scsi_done_list(done_scp); | ||
4796 | 2512 | ||
4797 | ASC_DBG(1, "advansys_interrupt: end\n"); | 2513 | printk(" disc_enable 0x%x, termination 0x%x\n", |
4798 | return IRQ_HANDLED; | 2514 | h->disc_enable, h->termination); |
4799 | } | ||
4800 | 2515 | ||
4801 | /* | 2516 | printk(" chip_version 0x%x, mcode_date 0x%x\n", |
4802 | * Set the number of commands to queue per device for the | 2517 | h->chip_version, h->mcode_date); |
4803 | * specified host adapter. | ||
4804 | */ | ||
4805 | static int advansys_slave_configure(struct scsi_device *device) | ||
4806 | { | ||
4807 | asc_board_t *boardp; | ||
4808 | 2518 | ||
4809 | boardp = ASC_BOARDP(device->host); | 2519 | printk(" mcode_version 0x%x, control_flag 0x%x\n", |
4810 | boardp->flags |= ASC_SELECT_QUEUE_DEPTHS; | 2520 | h->mcode_version, h->control_flag); |
4811 | /* | ||
4812 | * Save a pointer to the device and set its initial/maximum | ||
4813 | * queue depth. Only save the pointer for a lun0 dev though. | ||
4814 | */ | ||
4815 | if (device->lun == 0) | ||
4816 | boardp->device[device->id] = device; | ||
4817 | if (device->tagged_supported) { | ||
4818 | if (ASC_NARROW_BOARD(boardp)) { | ||
4819 | scsi_adjust_queue_depth(device, MSG_ORDERED_TAG, | ||
4820 | boardp->dvc_var.asc_dvc_var. | ||
4821 | max_dvc_qng[device->id]); | ||
4822 | } else { | ||
4823 | scsi_adjust_queue_depth(device, MSG_ORDERED_TAG, | ||
4824 | boardp->dvc_var.adv_dvc_var. | ||
4825 | max_dvc_qng); | ||
4826 | } | ||
4827 | } else { | ||
4828 | scsi_adjust_queue_depth(device, 0, device->host->cmd_per_lun); | ||
4829 | } | ||
4830 | ASC_DBG4(1, | ||
4831 | "advansys_slave_configure: device 0x%lx, boardp 0x%lx, id %d, depth %d\n", | ||
4832 | (ulong)device, (ulong)boardp, device->id, device->queue_depth); | ||
4833 | return 0; | ||
4834 | } | 2521 | } |
4835 | 2522 | ||
4836 | /* | 2523 | /* |
4837 | * Complete all requests on the singly linked list pointed | 2524 | * asc_prt_scsi_host() |
4838 | * to by 'scp'. | ||
4839 | * | ||
4840 | * Interrupts can be enabled on entry. | ||
4841 | */ | 2525 | */ |
4842 | static void asc_scsi_done_list(struct scsi_cmnd *scp) | 2526 | static void asc_prt_scsi_host(struct Scsi_Host *s) |
4843 | { | 2527 | { |
4844 | struct scsi_cmnd *tscp; | 2528 | struct asc_board *boardp = shost_priv(s); |
4845 | |||
4846 | ASC_DBG(2, "asc_scsi_done_list: begin\n"); | ||
4847 | while (scp != NULL) { | ||
4848 | asc_board_t *boardp; | ||
4849 | struct device *dev; | ||
4850 | 2529 | ||
4851 | ASC_DBG1(3, "asc_scsi_done_list: scp 0x%lx\n", (ulong)scp); | 2530 | printk("Scsi_Host at addr 0x%p, device %s\n", s, boardp->dev->bus_id); |
4852 | tscp = REQPNEXT(scp); | 2531 | printk(" host_busy %u, host_no %d, last_reset %d,\n", |
4853 | scp->host_scribble = NULL; | 2532 | s->host_busy, s->host_no, (unsigned)s->last_reset); |
4854 | |||
4855 | boardp = ASC_BOARDP(scp->device->host); | ||
4856 | |||
4857 | if (ASC_NARROW_BOARD(boardp)) | ||
4858 | dev = boardp->dvc_cfg.asc_dvc_cfg.dev; | ||
4859 | else | ||
4860 | dev = boardp->dvc_cfg.adv_dvc_cfg.dev; | ||
4861 | 2533 | ||
4862 | if (scp->use_sg) | 2534 | printk(" base 0x%lx, io_port 0x%lx, irq %d,\n", |
4863 | dma_unmap_sg(dev, | 2535 | (ulong)s->base, (ulong)s->io_port, boardp->irq); |
4864 | (struct scatterlist *)scp->request_buffer, | ||
4865 | scp->use_sg, scp->sc_data_direction); | ||
4866 | else if (scp->request_bufflen) | ||
4867 | dma_unmap_single(dev, scp->SCp.dma_handle, | ||
4868 | scp->request_bufflen, | ||
4869 | scp->sc_data_direction); | ||
4870 | 2536 | ||
4871 | ASC_STATS(scp->device->host, done); | 2537 | printk(" dma_channel %d, this_id %d, can_queue %d,\n", |
4872 | ASC_ASSERT(scp->scsi_done != NULL); | 2538 | s->dma_channel, s->this_id, s->can_queue); |
4873 | 2539 | ||
4874 | scp->scsi_done(scp); | 2540 | printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n", |
2541 | s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma); | ||
4875 | 2542 | ||
4876 | scp = tscp; | 2543 | if (ASC_NARROW_BOARD(boardp)) { |
2544 | asc_prt_asc_dvc_var(&boardp->dvc_var.asc_dvc_var); | ||
2545 | asc_prt_asc_dvc_cfg(&boardp->dvc_cfg.asc_dvc_cfg); | ||
2546 | } else { | ||
2547 | asc_prt_adv_dvc_var(&boardp->dvc_var.adv_dvc_var); | ||
2548 | asc_prt_adv_dvc_cfg(&boardp->dvc_cfg.adv_dvc_cfg); | ||
4877 | } | 2549 | } |
4878 | ASC_DBG(2, "asc_scsi_done_list: done\n"); | ||
4879 | return; | ||
4880 | } | 2550 | } |
4881 | 2551 | ||
4882 | /* | 2552 | /* |
4883 | * Execute a single 'Scsi_Cmnd'. | 2553 | * asc_prt_hex() |
4884 | * | ||
4885 | * The function 'done' is called when the request has been completed. | ||
4886 | * | ||
4887 | * Scsi_Cmnd: | ||
4888 | * | ||
4889 | * host - board controlling device | ||
4890 | * device - device to send command | ||
4891 | * target - target of device | ||
4892 | * lun - lun of device | ||
4893 | * cmd_len - length of SCSI CDB | ||
4894 | * cmnd - buffer for SCSI 8, 10, or 12 byte CDB | ||
4895 | * use_sg - if non-zero indicates scatter-gather request with use_sg elements | ||
4896 | * | ||
4897 | * if (use_sg == 0) { | ||
4898 | * request_buffer - buffer address for request | ||
4899 | * request_bufflen - length of request buffer | ||
4900 | * } else { | ||
4901 | * request_buffer - pointer to scatterlist structure | ||
4902 | * } | ||
4903 | * | ||
4904 | * sense_buffer - sense command buffer | ||
4905 | * | ||
4906 | * result (4 bytes of an int): | ||
4907 | * Byte Meaning | ||
4908 | * 0 SCSI Status Byte Code | ||
4909 | * 1 SCSI One Byte Message Code | ||
4910 | * 2 Host Error Code | ||
4911 | * 3 Mid-Level Error Code | ||
4912 | * | ||
4913 | * host driver fields: | ||
4914 | * SCp - Scsi_Pointer used for command processing status | ||
4915 | * scsi_done - used to save caller's done function | ||
4916 | * host_scribble - used for pointer to another struct scsi_cmnd | ||
4917 | * | ||
4918 | * If this function returns ASC_NOERROR the request has been enqueued | ||
4919 | * on the board's 'active' queue and will be completed from the | ||
4920 | * interrupt handler. | ||
4921 | * | ||
4922 | * If this function returns ASC_NOERROR the request has been enqueued | ||
4923 | * on the board's 'done' queue and must be completed by the caller. | ||
4924 | * | 2554 | * |
4925 | * If ASC_BUSY is returned the request will be enqueued by the | 2555 | * Print hexadecimal output in 4 byte groupings 32 bytes |
4926 | * caller on the target's waiting queue and re-tried later. | 2556 | * or 8 double-words per line. |
4927 | */ | 2557 | */ |
4928 | static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) | 2558 | static void asc_prt_hex(char *f, uchar *s, int l) |
4929 | { | 2559 | { |
4930 | asc_board_t *boardp; | 2560 | int i; |
4931 | ASC_DVC_VAR *asc_dvc_varp; | 2561 | int j; |
4932 | ADV_DVC_VAR *adv_dvc_varp; | 2562 | int k; |
4933 | ADV_SCSI_REQ_Q *adv_scsiqp; | 2563 | int m; |
4934 | struct scsi_device *device; | ||
4935 | int ret; | ||
4936 | |||
4937 | ASC_DBG2(1, "asc_execute_scsi_cmnd: scp 0x%lx, done 0x%lx\n", | ||
4938 | (ulong)scp, (ulong)scp->scsi_done); | ||
4939 | |||
4940 | boardp = ASC_BOARDP(scp->device->host); | ||
4941 | device = boardp->device[scp->device->id]; | ||
4942 | 2564 | ||
4943 | if (ASC_NARROW_BOARD(boardp)) { | 2565 | printk("%s: (%d bytes)\n", f, l); |
4944 | /* | ||
4945 | * Build and execute Narrow Board request. | ||
4946 | */ | ||
4947 | 2566 | ||
4948 | asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; | 2567 | for (i = 0; i < l; i += 32) { |
4949 | 2568 | ||
4950 | /* | 2569 | /* Display a maximum of 8 double-words per line. */ |
4951 | * Build Asc Library request structure using the | 2570 | if ((k = (l - i) / 4) >= 8) { |
4952 | * global structures 'asc_scsi_req' and 'asc_sg_head'. | 2571 | k = 8; |
4953 | * | 2572 | m = 0; |
4954 | * If an error is returned, then the request has been | 2573 | } else { |
4955 | * queued on the board done queue. It will be completed | 2574 | m = (l - i) % 4; |
4956 | * by the caller. | ||
4957 | * | ||
4958 | * asc_build_req() can not return ASC_BUSY. | ||
4959 | */ | ||
4960 | if (asc_build_req(boardp, scp) == ASC_ERROR) { | ||
4961 | ASC_STATS(scp->device->host, build_error); | ||
4962 | return ASC_ERROR; | ||
4963 | } | 2575 | } |
4964 | 2576 | ||
4965 | /* | 2577 | for (j = 0; j < k; j++) { |
4966 | * Execute the command. If there is no error, add the command | 2578 | printk(" %2.2X%2.2X%2.2X%2.2X", |
4967 | * to the active queue. | 2579 | (unsigned)s[i + (j * 4)], |
4968 | */ | 2580 | (unsigned)s[i + (j * 4) + 1], |
4969 | switch (ret = AscExeScsiQueue(asc_dvc_varp, &asc_scsi_q)) { | 2581 | (unsigned)s[i + (j * 4) + 2], |
4970 | case ASC_NOERROR: | 2582 | (unsigned)s[i + (j * 4) + 3]); |
4971 | ASC_STATS(scp->device->host, exe_noerror); | ||
4972 | /* | ||
4973 | * Increment monotonically increasing per device successful | ||
4974 | * request counter. Wrapping doesn't matter. | ||
4975 | */ | ||
4976 | boardp->reqcnt[scp->device->id]++; | ||
4977 | asc_enqueue(&boardp->active, scp, ASC_BACK); | ||
4978 | ASC_DBG(1, | ||
4979 | "asc_execute_scsi_cmnd: AscExeScsiQueue(), ASC_NOERROR\n"); | ||
4980 | break; | ||
4981 | case ASC_BUSY: | ||
4982 | /* | ||
4983 | * Caller will enqueue request on the target's waiting queue | ||
4984 | * and retry later. | ||
4985 | */ | ||
4986 | ASC_STATS(scp->device->host, exe_busy); | ||
4987 | break; | ||
4988 | case ASC_ERROR: | ||
4989 | ASC_PRINT2 | ||
4990 | ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() ASC_ERROR, err_code 0x%x\n", | ||
4991 | boardp->id, asc_dvc_varp->err_code); | ||
4992 | ASC_STATS(scp->device->host, exe_error); | ||
4993 | scp->result = HOST_BYTE(DID_ERROR); | ||
4994 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
4995 | break; | ||
4996 | default: | ||
4997 | ASC_PRINT2 | ||
4998 | ("asc_execute_scsi_cmnd: board %d: AscExeScsiQueue() unknown, err_code 0x%x\n", | ||
4999 | boardp->id, asc_dvc_varp->err_code); | ||
5000 | ASC_STATS(scp->device->host, exe_unknown); | ||
5001 | scp->result = HOST_BYTE(DID_ERROR); | ||
5002 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
5003 | break; | ||
5004 | } | 2583 | } |
5005 | } else { | ||
5006 | /* | ||
5007 | * Build and execute Wide Board request. | ||
5008 | */ | ||
5009 | adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; | ||
5010 | 2584 | ||
5011 | /* | 2585 | switch (m) { |
5012 | * Build and get a pointer to an Adv Library request structure. | 2586 | case 0: |
5013 | * | ||
5014 | * If the request is successfully built then send it below, | ||
5015 | * otherwise return with an error. | ||
5016 | */ | ||
5017 | switch (adv_build_req(boardp, scp, &adv_scsiqp)) { | ||
5018 | case ASC_NOERROR: | ||
5019 | ASC_DBG(3, | ||
5020 | "asc_execute_scsi_cmnd: adv_build_req ASC_NOERROR\n"); | ||
5021 | break; | ||
5022 | case ASC_BUSY: | ||
5023 | ASC_DBG(1, | ||
5024 | "asc_execute_scsi_cmnd: adv_build_req ASC_BUSY\n"); | ||
5025 | /* | ||
5026 | * If busy is returned the request has not been enqueued. | ||
5027 | * It will be enqueued by the caller on the target's waiting | ||
5028 | * queue and retried later. | ||
5029 | * | ||
5030 | * The asc_stats fields 'adv_build_noreq' and 'adv_build_nosg' | ||
5031 | * count wide board busy conditions. They are updated in | ||
5032 | * adv_build_req and adv_get_sglist, respectively. | ||
5033 | */ | ||
5034 | return ASC_BUSY; | ||
5035 | case ASC_ERROR: | ||
5036 | /* | ||
5037 | * If an error is returned, then the request has been | ||
5038 | * queued on the board done queue. It will be completed | ||
5039 | * by the caller. | ||
5040 | */ | ||
5041 | default: | 2587 | default: |
5042 | ASC_DBG(1, | ||
5043 | "asc_execute_scsi_cmnd: adv_build_req ASC_ERROR\n"); | ||
5044 | ASC_STATS(scp->device->host, build_error); | ||
5045 | return ASC_ERROR; | ||
5046 | } | ||
5047 | |||
5048 | /* | ||
5049 | * Execute the command. If there is no error, add the command | ||
5050 | * to the active queue. | ||
5051 | */ | ||
5052 | switch (ret = AdvExeScsiQueue(adv_dvc_varp, adv_scsiqp)) { | ||
5053 | case ASC_NOERROR: | ||
5054 | ASC_STATS(scp->device->host, exe_noerror); | ||
5055 | /* | ||
5056 | * Increment monotonically increasing per device successful | ||
5057 | * request counter. Wrapping doesn't matter. | ||
5058 | */ | ||
5059 | boardp->reqcnt[scp->device->id]++; | ||
5060 | asc_enqueue(&boardp->active, scp, ASC_BACK); | ||
5061 | ASC_DBG(1, | ||
5062 | "asc_execute_scsi_cmnd: AdvExeScsiQueue(), ASC_NOERROR\n"); | ||
5063 | break; | 2588 | break; |
5064 | case ASC_BUSY: | 2589 | case 1: |
5065 | /* | 2590 | printk(" %2.2X", (unsigned)s[i + (j * 4)]); |
5066 | * Caller will enqueue request on the target's waiting queue | ||
5067 | * and retry later. | ||
5068 | */ | ||
5069 | ASC_STATS(scp->device->host, exe_busy); | ||
5070 | break; | 2591 | break; |
5071 | case ASC_ERROR: | 2592 | case 2: |
5072 | ASC_PRINT2 | 2593 | printk(" %2.2X%2.2X", |
5073 | ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() ASC_ERROR, err_code 0x%x\n", | 2594 | (unsigned)s[i + (j * 4)], |
5074 | boardp->id, adv_dvc_varp->err_code); | 2595 | (unsigned)s[i + (j * 4) + 1]); |
5075 | ASC_STATS(scp->device->host, exe_error); | ||
5076 | scp->result = HOST_BYTE(DID_ERROR); | ||
5077 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
5078 | break; | 2596 | break; |
5079 | default: | 2597 | case 3: |
5080 | ASC_PRINT2 | 2598 | printk(" %2.2X%2.2X%2.2X", |
5081 | ("asc_execute_scsi_cmnd: board %d: AdvExeScsiQueue() unknown, err_code 0x%x\n", | 2599 | (unsigned)s[i + (j * 4) + 1], |
5082 | boardp->id, adv_dvc_varp->err_code); | 2600 | (unsigned)s[i + (j * 4) + 2], |
5083 | ASC_STATS(scp->device->host, exe_unknown); | 2601 | (unsigned)s[i + (j * 4) + 3]); |
5084 | scp->result = HOST_BYTE(DID_ERROR); | ||
5085 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
5086 | break; | 2602 | break; |
5087 | } | 2603 | } |
5088 | } | ||
5089 | |||
5090 | ASC_DBG(1, "asc_execute_scsi_cmnd: end\n"); | ||
5091 | return ret; | ||
5092 | } | ||
5093 | 2604 | ||
5094 | /* | 2605 | printk("\n"); |
5095 | * Build a request structure for the Asc Library (Narrow Board). | ||
5096 | * | ||
5097 | * The global structures 'asc_scsi_q' and 'asc_sg_head' are | ||
5098 | * used to build the request. | ||
5099 | * | ||
5100 | * If an error occurs, then queue the request on the board done | ||
5101 | * queue and return ASC_ERROR. | ||
5102 | */ | ||
5103 | static int asc_build_req(asc_board_t *boardp, struct scsi_cmnd *scp) | ||
5104 | { | ||
5105 | struct device *dev = boardp->dvc_cfg.asc_dvc_cfg.dev; | ||
5106 | |||
5107 | /* | ||
5108 | * Mutually exclusive access is required to 'asc_scsi_q' and | ||
5109 | * 'asc_sg_head' until after the request is started. | ||
5110 | */ | ||
5111 | memset(&asc_scsi_q, 0, sizeof(ASC_SCSI_Q)); | ||
5112 | |||
5113 | /* | ||
5114 | * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'. | ||
5115 | */ | ||
5116 | asc_scsi_q.q2.srb_ptr = ASC_VADDR_TO_U32(scp); | ||
5117 | |||
5118 | /* | ||
5119 | * Build the ASC_SCSI_Q request. | ||
5120 | * | ||
5121 | * For narrow boards a CDB length maximum of 12 bytes | ||
5122 | * is supported. | ||
5123 | */ | ||
5124 | if (scp->cmd_len > ASC_MAX_CDB_LEN) { | ||
5125 | ASC_PRINT3 | ||
5126 | ("asc_build_req: board %d: cmd_len %d > ASC_MAX_CDB_LEN %d\n", | ||
5127 | boardp->id, scp->cmd_len, ASC_MAX_CDB_LEN); | ||
5128 | scp->result = HOST_BYTE(DID_ERROR); | ||
5129 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
5130 | return ASC_ERROR; | ||
5131 | } | ||
5132 | asc_scsi_q.cdbptr = &scp->cmnd[0]; | ||
5133 | asc_scsi_q.q2.cdb_len = scp->cmd_len; | ||
5134 | asc_scsi_q.q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id); | ||
5135 | asc_scsi_q.q1.target_lun = scp->device->lun; | ||
5136 | asc_scsi_q.q2.target_ix = | ||
5137 | ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun); | ||
5138 | asc_scsi_q.q1.sense_addr = | ||
5139 | cpu_to_le32(virt_to_bus(&scp->sense_buffer[0])); | ||
5140 | asc_scsi_q.q1.sense_len = sizeof(scp->sense_buffer); | ||
5141 | |||
5142 | /* | ||
5143 | * If there are any outstanding requests for the current target, | ||
5144 | * then every 255th request send an ORDERED request. This heuristic | ||
5145 | * tries to retain the benefit of request sorting while preventing | ||
5146 | * request starvation. 255 is the max number of tags or pending commands | ||
5147 | * a device may have outstanding. | ||
5148 | * | ||
5149 | * The request count is incremented below for every successfully | ||
5150 | * started request. | ||
5151 | * | ||
5152 | */ | ||
5153 | if ((boardp->dvc_var.asc_dvc_var.cur_dvc_qng[scp->device->id] > 0) && | ||
5154 | (boardp->reqcnt[scp->device->id] % 255) == 0) { | ||
5155 | asc_scsi_q.q2.tag_code = MSG_ORDERED_TAG; | ||
5156 | } else { | ||
5157 | asc_scsi_q.q2.tag_code = MSG_SIMPLE_TAG; | ||
5158 | } | ||
5159 | |||
5160 | /* | ||
5161 | * Build ASC_SCSI_Q for a contiguous buffer or a scatter-gather | ||
5162 | * buffer command. | ||
5163 | */ | ||
5164 | if (scp->use_sg == 0) { | ||
5165 | /* | ||
5166 | * CDB request of single contiguous buffer. | ||
5167 | */ | ||
5168 | ASC_STATS(scp->device->host, cont_cnt); | ||
5169 | scp->SCp.dma_handle = scp->request_bufflen ? | ||
5170 | dma_map_single(dev, scp->request_buffer, | ||
5171 | scp->request_bufflen, | ||
5172 | scp->sc_data_direction) : 0; | ||
5173 | asc_scsi_q.q1.data_addr = cpu_to_le32(scp->SCp.dma_handle); | ||
5174 | asc_scsi_q.q1.data_cnt = cpu_to_le32(scp->request_bufflen); | ||
5175 | ASC_STATS_ADD(scp->device->host, cont_xfer, | ||
5176 | ASC_CEILING(scp->request_bufflen, 512)); | ||
5177 | asc_scsi_q.q1.sg_queue_cnt = 0; | ||
5178 | asc_scsi_q.sg_head = NULL; | ||
5179 | } else { | ||
5180 | /* | ||
5181 | * CDB scatter-gather request list. | ||
5182 | */ | ||
5183 | int sgcnt; | ||
5184 | int use_sg; | ||
5185 | struct scatterlist *slp; | ||
5186 | |||
5187 | slp = (struct scatterlist *)scp->request_buffer; | ||
5188 | use_sg = | ||
5189 | dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction); | ||
5190 | |||
5191 | if (use_sg > scp->device->host->sg_tablesize) { | ||
5192 | ASC_PRINT3 | ||
5193 | ("asc_build_req: board %d: use_sg %d > sg_tablesize %d\n", | ||
5194 | boardp->id, use_sg, | ||
5195 | scp->device->host->sg_tablesize); | ||
5196 | dma_unmap_sg(dev, slp, scp->use_sg, | ||
5197 | scp->sc_data_direction); | ||
5198 | scp->result = HOST_BYTE(DID_ERROR); | ||
5199 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
5200 | return ASC_ERROR; | ||
5201 | } | ||
5202 | |||
5203 | ASC_STATS(scp->device->host, sg_cnt); | ||
5204 | |||
5205 | /* | ||
5206 | * Use global ASC_SG_HEAD structure and set the ASC_SCSI_Q | ||
5207 | * structure to point to it. | ||
5208 | */ | ||
5209 | memset(&asc_sg_head, 0, sizeof(ASC_SG_HEAD)); | ||
5210 | |||
5211 | asc_scsi_q.q1.cntl |= QC_SG_HEAD; | ||
5212 | asc_scsi_q.sg_head = &asc_sg_head; | ||
5213 | asc_scsi_q.q1.data_cnt = 0; | ||
5214 | asc_scsi_q.q1.data_addr = 0; | ||
5215 | /* This is a byte value, otherwise it would need to be swapped. */ | ||
5216 | asc_sg_head.entry_cnt = asc_scsi_q.q1.sg_queue_cnt = use_sg; | ||
5217 | ASC_STATS_ADD(scp->device->host, sg_elem, | ||
5218 | asc_sg_head.entry_cnt); | ||
5219 | |||
5220 | /* | ||
5221 | * Convert scatter-gather list into ASC_SG_HEAD list. | ||
5222 | */ | ||
5223 | for (sgcnt = 0; sgcnt < use_sg; sgcnt++, slp++) { | ||
5224 | asc_sg_head.sg_list[sgcnt].addr = | ||
5225 | cpu_to_le32(sg_dma_address(slp)); | ||
5226 | asc_sg_head.sg_list[sgcnt].bytes = | ||
5227 | cpu_to_le32(sg_dma_len(slp)); | ||
5228 | ASC_STATS_ADD(scp->device->host, sg_xfer, | ||
5229 | ASC_CEILING(sg_dma_len(slp), 512)); | ||
5230 | } | ||
5231 | } | 2606 | } |
5232 | |||
5233 | ASC_DBG_PRT_ASC_SCSI_Q(2, &asc_scsi_q); | ||
5234 | ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len); | ||
5235 | |||
5236 | return ASC_NOERROR; | ||
5237 | } | 2607 | } |
5238 | 2608 | ||
5239 | /* | 2609 | /* |
5240 | * Build a request structure for the Adv Library (Wide Board). | 2610 | * asc_prt_asc_scsi_q() |
5241 | * | ||
5242 | * If an adv_req_t can not be allocated to issue the request, | ||
5243 | * then return ASC_BUSY. If an error occurs, then return ASC_ERROR. | ||
5244 | * | ||
5245 | * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the | ||
5246 | * microcode for DMA addresses or math operations are byte swapped | ||
5247 | * to little-endian order. | ||
5248 | */ | 2611 | */ |
5249 | static int | 2612 | static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q) |
5250 | adv_build_req(asc_board_t *boardp, struct scsi_cmnd *scp, | ||
5251 | ADV_SCSI_REQ_Q **adv_scsiqpp) | ||
5252 | { | 2613 | { |
5253 | adv_req_t *reqp; | 2614 | ASC_SG_HEAD *sgp; |
5254 | ADV_SCSI_REQ_Q *scsiqp; | ||
5255 | int i; | 2615 | int i; |
5256 | int ret; | ||
5257 | struct device *dev = boardp->dvc_cfg.adv_dvc_cfg.dev; | ||
5258 | 2616 | ||
5259 | /* | 2617 | printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q); |
5260 | * Allocate an adv_req_t structure from the board to execute | ||
5261 | * the command. | ||
5262 | */ | ||
5263 | if (boardp->adv_reqp == NULL) { | ||
5264 | ASC_DBG(1, "adv_build_req: no free adv_req_t\n"); | ||
5265 | ASC_STATS(scp->device->host, adv_build_noreq); | ||
5266 | return ASC_BUSY; | ||
5267 | } else { | ||
5268 | reqp = boardp->adv_reqp; | ||
5269 | boardp->adv_reqp = reqp->next_reqp; | ||
5270 | reqp->next_reqp = NULL; | ||
5271 | } | ||
5272 | |||
5273 | /* | ||
5274 | * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers. | ||
5275 | */ | ||
5276 | scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q); | ||
5277 | |||
5278 | /* | ||
5279 | * Initialize the structure. | ||
5280 | */ | ||
5281 | scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0; | ||
5282 | |||
5283 | /* | ||
5284 | * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure. | ||
5285 | */ | ||
5286 | scsiqp->srb_ptr = ASC_VADDR_TO_U32(reqp); | ||
5287 | |||
5288 | /* | ||
5289 | * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure. | ||
5290 | */ | ||
5291 | reqp->cmndp = scp; | ||
5292 | |||
5293 | /* | ||
5294 | * Build the ADV_SCSI_REQ_Q request. | ||
5295 | */ | ||
5296 | |||
5297 | /* | ||
5298 | * Set CDB length and copy it to the request structure. | ||
5299 | * For wide boards a CDB length maximum of 16 bytes | ||
5300 | * is supported. | ||
5301 | */ | ||
5302 | if (scp->cmd_len > ADV_MAX_CDB_LEN) { | ||
5303 | ASC_PRINT3 | ||
5304 | ("adv_build_req: board %d: cmd_len %d > ADV_MAX_CDB_LEN %d\n", | ||
5305 | boardp->id, scp->cmd_len, ADV_MAX_CDB_LEN); | ||
5306 | scp->result = HOST_BYTE(DID_ERROR); | ||
5307 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
5308 | return ASC_ERROR; | ||
5309 | } | ||
5310 | scsiqp->cdb_len = scp->cmd_len; | ||
5311 | /* Copy first 12 CDB bytes to cdb[]. */ | ||
5312 | for (i = 0; i < scp->cmd_len && i < 12; i++) { | ||
5313 | scsiqp->cdb[i] = scp->cmnd[i]; | ||
5314 | } | ||
5315 | /* Copy last 4 CDB bytes, if present, to cdb16[]. */ | ||
5316 | for (; i < scp->cmd_len; i++) { | ||
5317 | scsiqp->cdb16[i - 12] = scp->cmnd[i]; | ||
5318 | } | ||
5319 | |||
5320 | scsiqp->target_id = scp->device->id; | ||
5321 | scsiqp->target_lun = scp->device->lun; | ||
5322 | |||
5323 | scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0])); | ||
5324 | scsiqp->sense_len = sizeof(scp->sense_buffer); | ||
5325 | |||
5326 | /* | ||
5327 | * Build ADV_SCSI_REQ_Q for a contiguous buffer or a scatter-gather | ||
5328 | * buffer command. | ||
5329 | */ | ||
5330 | |||
5331 | scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen); | ||
5332 | scsiqp->vdata_addr = scp->request_buffer; | ||
5333 | scsiqp->data_addr = cpu_to_le32(virt_to_bus(scp->request_buffer)); | ||
5334 | |||
5335 | if (scp->use_sg == 0) { | ||
5336 | /* | ||
5337 | * CDB request of single contiguous buffer. | ||
5338 | */ | ||
5339 | reqp->sgblkp = NULL; | ||
5340 | scsiqp->data_cnt = cpu_to_le32(scp->request_bufflen); | ||
5341 | if (scp->request_bufflen) { | ||
5342 | scsiqp->vdata_addr = scp->request_buffer; | ||
5343 | scp->SCp.dma_handle = | ||
5344 | dma_map_single(dev, scp->request_buffer, | ||
5345 | scp->request_bufflen, | ||
5346 | scp->sc_data_direction); | ||
5347 | } else { | ||
5348 | scsiqp->vdata_addr = NULL; | ||
5349 | scp->SCp.dma_handle = 0; | ||
5350 | } | ||
5351 | scsiqp->data_addr = cpu_to_le32(scp->SCp.dma_handle); | ||
5352 | scsiqp->sg_list_ptr = NULL; | ||
5353 | scsiqp->sg_real_addr = 0; | ||
5354 | ASC_STATS(scp->device->host, cont_cnt); | ||
5355 | ASC_STATS_ADD(scp->device->host, cont_xfer, | ||
5356 | ASC_CEILING(scp->request_bufflen, 512)); | ||
5357 | } else { | ||
5358 | /* | ||
5359 | * CDB scatter-gather request list. | ||
5360 | */ | ||
5361 | struct scatterlist *slp; | ||
5362 | int use_sg; | ||
5363 | |||
5364 | slp = (struct scatterlist *)scp->request_buffer; | ||
5365 | use_sg = | ||
5366 | dma_map_sg(dev, slp, scp->use_sg, scp->sc_data_direction); | ||
5367 | |||
5368 | if (use_sg > ADV_MAX_SG_LIST) { | ||
5369 | ASC_PRINT3 | ||
5370 | ("adv_build_req: board %d: use_sg %d > ADV_MAX_SG_LIST %d\n", | ||
5371 | boardp->id, use_sg, | ||
5372 | scp->device->host->sg_tablesize); | ||
5373 | dma_unmap_sg(dev, slp, scp->use_sg, | ||
5374 | scp->sc_data_direction); | ||
5375 | scp->result = HOST_BYTE(DID_ERROR); | ||
5376 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
5377 | 2618 | ||
5378 | /* | 2619 | printk |
5379 | * Free the 'adv_req_t' structure by adding it back to the | 2620 | (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n", |
5380 | * board free list. | 2621 | q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr, |
5381 | */ | 2622 | q->q2.tag_code); |
5382 | reqp->next_reqp = boardp->adv_reqp; | ||
5383 | boardp->adv_reqp = reqp; | ||
5384 | 2623 | ||
5385 | return ASC_ERROR; | 2624 | printk |
5386 | } | 2625 | (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n", |
2626 | (ulong)le32_to_cpu(q->q1.data_addr), | ||
2627 | (ulong)le32_to_cpu(q->q1.data_cnt), | ||
2628 | (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len); | ||
5387 | 2629 | ||
5388 | if ((ret = | 2630 | printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n", |
5389 | adv_get_sglist(boardp, reqp, scp, | 2631 | (ulong)q->cdbptr, q->q2.cdb_len, |
5390 | use_sg)) != ADV_SUCCESS) { | 2632 | (ulong)q->sg_head, q->q1.sg_queue_cnt); |
5391 | /* | ||
5392 | * Free the adv_req_t structure by adding it back to the | ||
5393 | * board free list. | ||
5394 | */ | ||
5395 | reqp->next_reqp = boardp->adv_reqp; | ||
5396 | boardp->adv_reqp = reqp; | ||
5397 | 2633 | ||
5398 | return ret; | 2634 | if (q->sg_head) { |
2635 | sgp = q->sg_head; | ||
2636 | printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp); | ||
2637 | printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, | ||
2638 | sgp->queue_cnt); | ||
2639 | for (i = 0; i < sgp->entry_cnt; i++) { | ||
2640 | printk(" [%u]: addr 0x%lx, bytes %lu\n", | ||
2641 | i, (ulong)le32_to_cpu(sgp->sg_list[i].addr), | ||
2642 | (ulong)le32_to_cpu(sgp->sg_list[i].bytes)); | ||
5399 | } | 2643 | } |
5400 | 2644 | ||
5401 | ASC_STATS(scp->device->host, sg_cnt); | ||
5402 | ASC_STATS_ADD(scp->device->host, sg_elem, use_sg); | ||
5403 | } | 2645 | } |
5404 | |||
5405 | ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp); | ||
5406 | ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len); | ||
5407 | |||
5408 | *adv_scsiqpp = scsiqp; | ||
5409 | |||
5410 | return ASC_NOERROR; | ||
5411 | } | 2646 | } |
5412 | 2647 | ||
5413 | /* | 2648 | /* |
5414 | * Build scatter-gather list for Adv Library (Wide Board). | 2649 | * asc_prt_asc_qdone_info() |
5415 | * | ||
5416 | * Additional ADV_SG_BLOCK structures will need to be allocated | ||
5417 | * if the total number of scatter-gather elements exceeds | ||
5418 | * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are | ||
5419 | * assumed to be physically contiguous. | ||
5420 | * | ||
5421 | * Return: | ||
5422 | * ADV_SUCCESS(1) - SG List successfully created | ||
5423 | * ADV_ERROR(-1) - SG List creation failed | ||
5424 | */ | 2650 | */ |
5425 | static int | 2651 | static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q) |
5426 | adv_get_sglist(asc_board_t *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, | ||
5427 | int use_sg) | ||
5428 | { | 2652 | { |
5429 | adv_sgblk_t *sgblkp; | 2653 | printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q); |
5430 | ADV_SCSI_REQ_Q *scsiqp; | 2654 | printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n", |
5431 | struct scatterlist *slp; | 2655 | (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len, |
5432 | int sg_elem_cnt; | 2656 | q->d2.tag_code); |
5433 | ADV_SG_BLOCK *sg_block, *prev_sg_block; | 2657 | printk |
5434 | ADV_PADDR sg_block_paddr; | 2658 | (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n", |
5435 | int i; | 2659 | q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg); |
5436 | |||
5437 | scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q); | ||
5438 | slp = (struct scatterlist *)scp->request_buffer; | ||
5439 | sg_elem_cnt = use_sg; | ||
5440 | prev_sg_block = NULL; | ||
5441 | reqp->sgblkp = NULL; | ||
5442 | |||
5443 | do { | ||
5444 | /* | ||
5445 | * Allocate a 'adv_sgblk_t' structure from the board free | ||
5446 | * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK | ||
5447 | * (15) scatter-gather elements. | ||
5448 | */ | ||
5449 | if ((sgblkp = boardp->adv_sgblkp) == NULL) { | ||
5450 | ASC_DBG(1, "adv_get_sglist: no free adv_sgblk_t\n"); | ||
5451 | ASC_STATS(scp->device->host, adv_build_nosg); | ||
5452 | |||
5453 | /* | ||
5454 | * Allocation failed. Free 'adv_sgblk_t' structures already | ||
5455 | * allocated for the request. | ||
5456 | */ | ||
5457 | while ((sgblkp = reqp->sgblkp) != NULL) { | ||
5458 | /* Remove 'sgblkp' from the request list. */ | ||
5459 | reqp->sgblkp = sgblkp->next_sgblkp; | ||
5460 | |||
5461 | /* Add 'sgblkp' to the board free list. */ | ||
5462 | sgblkp->next_sgblkp = boardp->adv_sgblkp; | ||
5463 | boardp->adv_sgblkp = sgblkp; | ||
5464 | } | ||
5465 | return ASC_BUSY; | ||
5466 | } else { | ||
5467 | /* Complete 'adv_sgblk_t' board allocation. */ | ||
5468 | boardp->adv_sgblkp = sgblkp->next_sgblkp; | ||
5469 | sgblkp->next_sgblkp = NULL; | ||
5470 | |||
5471 | /* | ||
5472 | * Get 8 byte aligned virtual and physical addresses for | ||
5473 | * the allocated ADV_SG_BLOCK structure. | ||
5474 | */ | ||
5475 | sg_block = | ||
5476 | (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block); | ||
5477 | sg_block_paddr = virt_to_bus(sg_block); | ||
5478 | |||
5479 | /* | ||
5480 | * Check if this is the first 'adv_sgblk_t' for the request. | ||
5481 | */ | ||
5482 | if (reqp->sgblkp == NULL) { | ||
5483 | /* Request's first scatter-gather block. */ | ||
5484 | reqp->sgblkp = sgblkp; | ||
5485 | |||
5486 | /* | ||
5487 | * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical | ||
5488 | * address pointers. | ||
5489 | */ | ||
5490 | scsiqp->sg_list_ptr = sg_block; | ||
5491 | scsiqp->sg_real_addr = | ||
5492 | cpu_to_le32(sg_block_paddr); | ||
5493 | } else { | ||
5494 | /* Request's second or later scatter-gather block. */ | ||
5495 | sgblkp->next_sgblkp = reqp->sgblkp; | ||
5496 | reqp->sgblkp = sgblkp; | ||
5497 | |||
5498 | /* | ||
5499 | * Point the previous ADV_SG_BLOCK structure to | ||
5500 | * the newly allocated ADV_SG_BLOCK structure. | ||
5501 | */ | ||
5502 | ASC_ASSERT(prev_sg_block != NULL); | ||
5503 | prev_sg_block->sg_ptr = | ||
5504 | cpu_to_le32(sg_block_paddr); | ||
5505 | } | ||
5506 | } | ||
5507 | |||
5508 | for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) { | ||
5509 | sg_block->sg_list[i].sg_addr = | ||
5510 | cpu_to_le32(sg_dma_address(slp)); | ||
5511 | sg_block->sg_list[i].sg_count = | ||
5512 | cpu_to_le32(sg_dma_len(slp)); | ||
5513 | ASC_STATS_ADD(scp->device->host, sg_xfer, | ||
5514 | ASC_CEILING(sg_dma_len(slp), 512)); | ||
5515 | |||
5516 | if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */ | ||
5517 | sg_block->sg_cnt = i + 1; | ||
5518 | sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */ | ||
5519 | return ADV_SUCCESS; | ||
5520 | } | ||
5521 | slp++; | ||
5522 | } | ||
5523 | sg_block->sg_cnt = NO_OF_SG_PER_BLOCK; | ||
5524 | prev_sg_block = sg_block; | ||
5525 | } | ||
5526 | while (1); | ||
5527 | /* NOTREACHED */ | ||
5528 | } | 2660 | } |
5529 | 2661 | ||
5530 | /* | 2662 | /* |
5531 | * asc_isr_callback() - Second Level Interrupt Handler called by AscISR(). | 2663 | * asc_prt_adv_sgblock() |
5532 | * | 2664 | * |
5533 | * Interrupt callback function for the Narrow SCSI Asc Library. | 2665 | * Display an ADV_SG_BLOCK structure. |
5534 | */ | 2666 | */ |
5535 | static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) | 2667 | static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b) |
5536 | { | 2668 | { |
5537 | asc_board_t *boardp; | ||
5538 | struct scsi_cmnd *scp; | ||
5539 | struct Scsi_Host *shost; | ||
5540 | int i; | 2669 | int i; |
5541 | 2670 | ||
5542 | ASC_DBG2(1, "asc_isr_callback: asc_dvc_varp 0x%lx, qdonep 0x%lx\n", | 2671 | printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n", |
5543 | (ulong)asc_dvc_varp, (ulong)qdonep); | 2672 | (ulong)b, sgblockno); |
5544 | ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep); | 2673 | printk(" sg_cnt %u, sg_ptr 0x%lx\n", |
5545 | 2674 | b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr)); | |
5546 | /* | 2675 | BUG_ON(b->sg_cnt > NO_OF_SG_PER_BLOCK); |
5547 | * Get the struct scsi_cmnd structure and Scsi_Host structure for the | 2676 | if (b->sg_ptr != 0) |
5548 | * command that has been completed. | 2677 | BUG_ON(b->sg_cnt != NO_OF_SG_PER_BLOCK); |
5549 | */ | 2678 | for (i = 0; i < b->sg_cnt; i++) { |
5550 | scp = (struct scsi_cmnd *)ASC_U32_TO_VADDR(qdonep->d2.srb_ptr); | 2679 | printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n", |
5551 | ASC_DBG1(1, "asc_isr_callback: scp 0x%lx\n", (ulong)scp); | 2680 | i, (ulong)b->sg_list[i].sg_addr, |
5552 | 2681 | (ulong)b->sg_list[i].sg_count); | |
5553 | if (scp == NULL) { | ||
5554 | ASC_PRINT("asc_isr_callback: scp is NULL\n"); | ||
5555 | return; | ||
5556 | } | ||
5557 | ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len); | ||
5558 | |||
5559 | /* | ||
5560 | * If the request's host pointer is not valid, display a | ||
5561 | * message and return. | ||
5562 | */ | ||
5563 | shost = scp->device->host; | ||
5564 | for (i = 0; i < asc_board_count; i++) { | ||
5565 | if (asc_host[i] == shost) { | ||
5566 | break; | ||
5567 | } | ||
5568 | } | ||
5569 | if (i == asc_board_count) { | ||
5570 | ASC_PRINT2 | ||
5571 | ("asc_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n", | ||
5572 | (ulong)scp, (ulong)shost); | ||
5573 | return; | ||
5574 | } | ||
5575 | |||
5576 | ASC_STATS(shost, callback); | ||
5577 | ASC_DBG1(1, "asc_isr_callback: shost 0x%lx\n", (ulong)shost); | ||
5578 | |||
5579 | /* | ||
5580 | * If the request isn't found on the active queue, it may | ||
5581 | * have been removed to handle a reset request. | ||
5582 | * Display a message and return. | ||
5583 | */ | ||
5584 | boardp = ASC_BOARDP(shost); | ||
5585 | ASC_ASSERT(asc_dvc_varp == &boardp->dvc_var.asc_dvc_var); | ||
5586 | if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) { | ||
5587 | ASC_PRINT2 | ||
5588 | ("asc_isr_callback: board %d: scp 0x%lx not on active queue\n", | ||
5589 | boardp->id, (ulong)scp); | ||
5590 | return; | ||
5591 | } | ||
5592 | |||
5593 | /* | ||
5594 | * 'qdonep' contains the command's ending status. | ||
5595 | */ | ||
5596 | switch (qdonep->d3.done_stat) { | ||
5597 | case QD_NO_ERROR: | ||
5598 | ASC_DBG(2, "asc_isr_callback: QD_NO_ERROR\n"); | ||
5599 | scp->result = 0; | ||
5600 | |||
5601 | /* | ||
5602 | * If an INQUIRY command completed successfully, then call | ||
5603 | * the AscInquiryHandling() function to set-up the device. | ||
5604 | */ | ||
5605 | if (scp->cmnd[0] == INQUIRY && scp->device->lun == 0 && | ||
5606 | (scp->request_bufflen - qdonep->remain_bytes) >= 8) { | ||
5607 | AscInquiryHandling(asc_dvc_varp, scp->device->id & 0x7, | ||
5608 | (ASC_SCSI_INQUIRY *)scp-> | ||
5609 | request_buffer); | ||
5610 | } | ||
5611 | |||
5612 | /* | ||
5613 | * Check for an underrun condition. | ||
5614 | * | ||
5615 | * If there was no error and an underrun condition, then | ||
5616 | * then return the number of underrun bytes. | ||
5617 | */ | ||
5618 | if (scp->request_bufflen != 0 && qdonep->remain_bytes != 0 && | ||
5619 | qdonep->remain_bytes <= scp->request_bufflen) { | ||
5620 | ASC_DBG1(1, | ||
5621 | "asc_isr_callback: underrun condition %u bytes\n", | ||
5622 | (unsigned)qdonep->remain_bytes); | ||
5623 | scp->resid = qdonep->remain_bytes; | ||
5624 | } | ||
5625 | break; | ||
5626 | |||
5627 | case QD_WITH_ERROR: | ||
5628 | ASC_DBG(2, "asc_isr_callback: QD_WITH_ERROR\n"); | ||
5629 | switch (qdonep->d3.host_stat) { | ||
5630 | case QHSTA_NO_ERROR: | ||
5631 | if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) { | ||
5632 | ASC_DBG(2, | ||
5633 | "asc_isr_callback: SAM_STAT_CHECK_CONDITION\n"); | ||
5634 | ASC_DBG_PRT_SENSE(2, scp->sense_buffer, | ||
5635 | sizeof(scp->sense_buffer)); | ||
5636 | /* | ||
5637 | * Note: The 'status_byte()' macro used by target drivers | ||
5638 | * defined in scsi.h shifts the status byte returned by | ||
5639 | * host drivers right by 1 bit. This is why target drivers | ||
5640 | * also use right shifted status byte definitions. For | ||
5641 | * instance target drivers use CHECK_CONDITION, defined to | ||
5642 | * 0x1, instead of the SCSI defined check condition value | ||
5643 | * of 0x2. Host drivers are supposed to return the status | ||
5644 | * byte as it is defined by SCSI. | ||
5645 | */ | ||
5646 | scp->result = DRIVER_BYTE(DRIVER_SENSE) | | ||
5647 | STATUS_BYTE(qdonep->d3.scsi_stat); | ||
5648 | } else { | ||
5649 | scp->result = STATUS_BYTE(qdonep->d3.scsi_stat); | ||
5650 | } | ||
5651 | break; | ||
5652 | |||
5653 | default: | ||
5654 | /* QHSTA error occurred */ | ||
5655 | ASC_DBG1(1, "asc_isr_callback: host_stat 0x%x\n", | ||
5656 | qdonep->d3.host_stat); | ||
5657 | scp->result = HOST_BYTE(DID_BAD_TARGET); | ||
5658 | break; | ||
5659 | } | ||
5660 | break; | ||
5661 | |||
5662 | case QD_ABORTED_BY_HOST: | ||
5663 | ASC_DBG(1, "asc_isr_callback: QD_ABORTED_BY_HOST\n"); | ||
5664 | scp->result = | ||
5665 | HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3. | ||
5666 | scsi_msg) | | ||
5667 | STATUS_BYTE(qdonep->d3.scsi_stat); | ||
5668 | break; | ||
5669 | |||
5670 | default: | ||
5671 | ASC_DBG1(1, "asc_isr_callback: done_stat 0x%x\n", | ||
5672 | qdonep->d3.done_stat); | ||
5673 | scp->result = | ||
5674 | HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3. | ||
5675 | scsi_msg) | | ||
5676 | STATUS_BYTE(qdonep->d3.scsi_stat); | ||
5677 | break; | ||
5678 | } | ||
5679 | |||
5680 | /* | ||
5681 | * If the 'init_tidmask' bit isn't already set for the target and the | ||
5682 | * current request finished normally, then set the bit for the target | ||
5683 | * to indicate that a device is present. | ||
5684 | */ | ||
5685 | if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 && | ||
5686 | qdonep->d3.done_stat == QD_NO_ERROR && | ||
5687 | qdonep->d3.host_stat == QHSTA_NO_ERROR) { | ||
5688 | boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id); | ||
5689 | } | 2682 | } |
5690 | |||
5691 | /* | ||
5692 | * Because interrupts may be enabled by the 'struct scsi_cmnd' done | ||
5693 | * function, add the command to the end of the board's done queue. | ||
5694 | * The done function for the command will be called from | ||
5695 | * advansys_interrupt(). | ||
5696 | */ | ||
5697 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
5698 | |||
5699 | return; | ||
5700 | } | 2683 | } |
5701 | 2684 | ||
5702 | /* | 2685 | /* |
5703 | * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR(). | 2686 | * asc_prt_adv_scsi_req_q() |
5704 | * | 2687 | * |
5705 | * Callback function for the Wide SCSI Adv Library. | 2688 | * Display an ADV_SCSI_REQ_Q structure. |
5706 | */ | 2689 | */ |
5707 | static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) | 2690 | static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q) |
5708 | { | 2691 | { |
5709 | asc_board_t *boardp; | 2692 | int sg_blk_cnt; |
5710 | adv_req_t *reqp; | 2693 | struct asc_sg_block *sg_ptr; |
5711 | adv_sgblk_t *sgblkp; | ||
5712 | struct scsi_cmnd *scp; | ||
5713 | struct Scsi_Host *shost; | ||
5714 | int i; | ||
5715 | ADV_DCNT resid_cnt; | ||
5716 | |||
5717 | ASC_DBG2(1, "adv_isr_callback: adv_dvc_varp 0x%lx, scsiqp 0x%lx\n", | ||
5718 | (ulong)adv_dvc_varp, (ulong)scsiqp); | ||
5719 | ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp); | ||
5720 | 2694 | ||
5721 | /* | 2695 | printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q); |
5722 | * Get the adv_req_t structure for the command that has been | ||
5723 | * completed. The adv_req_t structure actually contains the | ||
5724 | * completed ADV_SCSI_REQ_Q structure. | ||
5725 | */ | ||
5726 | reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr); | ||
5727 | ASC_DBG1(1, "adv_isr_callback: reqp 0x%lx\n", (ulong)reqp); | ||
5728 | if (reqp == NULL) { | ||
5729 | ASC_PRINT("adv_isr_callback: reqp is NULL\n"); | ||
5730 | return; | ||
5731 | } | ||
5732 | 2696 | ||
5733 | /* | 2697 | printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n", |
5734 | * Get the struct scsi_cmnd structure and Scsi_Host structure for the | 2698 | q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag); |
5735 | * command that has been completed. | ||
5736 | * | ||
5737 | * Note: The adv_req_t request structure and adv_sgblk_t structure, | ||
5738 | * if any, are dropped, because a board structure pointer can not be | ||
5739 | * determined. | ||
5740 | */ | ||
5741 | scp = reqp->cmndp; | ||
5742 | ASC_DBG1(1, "adv_isr_callback: scp 0x%lx\n", (ulong)scp); | ||
5743 | if (scp == NULL) { | ||
5744 | ASC_PRINT | ||
5745 | ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n"); | ||
5746 | return; | ||
5747 | } | ||
5748 | ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len); | ||
5749 | 2699 | ||
5750 | /* | 2700 | printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n", |
5751 | * If the request's host pointer is not valid, display a message | 2701 | q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr); |
5752 | * and return. | ||
5753 | */ | ||
5754 | shost = scp->device->host; | ||
5755 | for (i = 0; i < asc_board_count; i++) { | ||
5756 | if (asc_host[i] == shost) { | ||
5757 | break; | ||
5758 | } | ||
5759 | } | ||
5760 | /* | ||
5761 | * Note: If the host structure is not found, the adv_req_t request | ||
5762 | * structure and adv_sgblk_t structure, if any, is dropped. | ||
5763 | */ | ||
5764 | if (i == asc_board_count) { | ||
5765 | ASC_PRINT2 | ||
5766 | ("adv_isr_callback: scp 0x%lx has bad host pointer, host 0x%lx\n", | ||
5767 | (ulong)scp, (ulong)shost); | ||
5768 | return; | ||
5769 | } | ||
5770 | 2702 | ||
5771 | ASC_STATS(shost, callback); | 2703 | printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n", |
5772 | ASC_DBG1(1, "adv_isr_callback: shost 0x%lx\n", (ulong)shost); | 2704 | (ulong)le32_to_cpu(q->data_cnt), |
2705 | (ulong)le32_to_cpu(q->sense_addr), q->sense_len); | ||
5773 | 2706 | ||
5774 | /* | 2707 | printk |
5775 | * If the request isn't found on the active queue, it may have been | 2708 | (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n", |
5776 | * removed to handle a reset request. Display a message and return. | 2709 | q->cdb_len, q->done_status, q->host_status, q->scsi_status); |
5777 | * | ||
5778 | * Note: Because the structure may still be in use don't attempt | ||
5779 | * to free the adv_req_t and adv_sgblk_t, if any, structures. | ||
5780 | */ | ||
5781 | boardp = ASC_BOARDP(shost); | ||
5782 | ASC_ASSERT(adv_dvc_varp == &boardp->dvc_var.adv_dvc_var); | ||
5783 | if (asc_rmqueue(&boardp->active, scp) == ASC_FALSE) { | ||
5784 | ASC_PRINT2 | ||
5785 | ("adv_isr_callback: board %d: scp 0x%lx not on active queue\n", | ||
5786 | boardp->id, (ulong)scp); | ||
5787 | return; | ||
5788 | } | ||
5789 | 2710 | ||
5790 | /* | 2711 | printk(" sg_working_ix 0x%x, target_cmd %u\n", |
5791 | * 'done_status' contains the command's ending status. | 2712 | q->sg_working_ix, q->target_cmd); |
5792 | */ | ||
5793 | switch (scsiqp->done_status) { | ||
5794 | case QD_NO_ERROR: | ||
5795 | ASC_DBG(2, "adv_isr_callback: QD_NO_ERROR\n"); | ||
5796 | scp->result = 0; | ||
5797 | 2713 | ||
5798 | /* | 2714 | printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n", |
5799 | * Check for an underrun condition. | 2715 | (ulong)le32_to_cpu(q->scsiq_rptr), |
5800 | * | 2716 | (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr); |
5801 | * If there was no error and an underrun condition, then | ||
5802 | * then return the number of underrun bytes. | ||
5803 | */ | ||
5804 | resid_cnt = le32_to_cpu(scsiqp->data_cnt); | ||
5805 | if (scp->request_bufflen != 0 && resid_cnt != 0 && | ||
5806 | resid_cnt <= scp->request_bufflen) { | ||
5807 | ASC_DBG1(1, | ||
5808 | "adv_isr_callback: underrun condition %lu bytes\n", | ||
5809 | (ulong)resid_cnt); | ||
5810 | scp->resid = resid_cnt; | ||
5811 | } | ||
5812 | break; | ||
5813 | 2717 | ||
5814 | case QD_WITH_ERROR: | 2718 | /* Display the request's ADV_SG_BLOCK structures. */ |
5815 | ASC_DBG(2, "adv_isr_callback: QD_WITH_ERROR\n"); | 2719 | if (q->sg_list_ptr != NULL) { |
5816 | switch (scsiqp->host_status) { | 2720 | sg_blk_cnt = 0; |
5817 | case QHSTA_NO_ERROR: | 2721 | while (1) { |
5818 | if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) { | 2722 | /* |
5819 | ASC_DBG(2, | 2723 | * 'sg_ptr' is a physical address. Convert it to a virtual |
5820 | "adv_isr_callback: SAM_STAT_CHECK_CONDITION\n"); | 2724 | * address by indexing 'sg_blk_cnt' into the virtual address |
5821 | ASC_DBG_PRT_SENSE(2, scp->sense_buffer, | 2725 | * array 'sg_list_ptr'. |
5822 | sizeof(scp->sense_buffer)); | 2726 | * |
5823 | /* | 2727 | * XXX - Assumes all SG physical blocks are virtually contiguous. |
5824 | * Note: The 'status_byte()' macro used by target drivers | 2728 | */ |
5825 | * defined in scsi.h shifts the status byte returned by | 2729 | sg_ptr = |
5826 | * host drivers right by 1 bit. This is why target drivers | 2730 | &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]); |
5827 | * also use right shifted status byte definitions. For | 2731 | asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr); |
5828 | * instance target drivers use CHECK_CONDITION, defined to | 2732 | if (sg_ptr->sg_ptr == 0) { |
5829 | * 0x1, instead of the SCSI defined check condition value | 2733 | break; |
5830 | * of 0x2. Host drivers are supposed to return the status | ||
5831 | * byte as it is defined by SCSI. | ||
5832 | */ | ||
5833 | scp->result = DRIVER_BYTE(DRIVER_SENSE) | | ||
5834 | STATUS_BYTE(scsiqp->scsi_status); | ||
5835 | } else { | ||
5836 | scp->result = STATUS_BYTE(scsiqp->scsi_status); | ||
5837 | } | 2734 | } |
5838 | break; | 2735 | sg_blk_cnt++; |
5839 | |||
5840 | default: | ||
5841 | /* Some other QHSTA error occurred. */ | ||
5842 | ASC_DBG1(1, "adv_isr_callback: host_status 0x%x\n", | ||
5843 | scsiqp->host_status); | ||
5844 | scp->result = HOST_BYTE(DID_BAD_TARGET); | ||
5845 | break; | ||
5846 | } | 2736 | } |
5847 | break; | ||
5848 | |||
5849 | case QD_ABORTED_BY_HOST: | ||
5850 | ASC_DBG(1, "adv_isr_callback: QD_ABORTED_BY_HOST\n"); | ||
5851 | scp->result = | ||
5852 | HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status); | ||
5853 | break; | ||
5854 | |||
5855 | default: | ||
5856 | ASC_DBG1(1, "adv_isr_callback: done_status 0x%x\n", | ||
5857 | scsiqp->done_status); | ||
5858 | scp->result = | ||
5859 | HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status); | ||
5860 | break; | ||
5861 | } | ||
5862 | |||
5863 | /* | ||
5864 | * If the 'init_tidmask' bit isn't already set for the target and the | ||
5865 | * current request finished normally, then set the bit for the target | ||
5866 | * to indicate that a device is present. | ||
5867 | */ | ||
5868 | if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 && | ||
5869 | scsiqp->done_status == QD_NO_ERROR && | ||
5870 | scsiqp->host_status == QHSTA_NO_ERROR) { | ||
5871 | boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id); | ||
5872 | } | ||
5873 | |||
5874 | /* | ||
5875 | * Because interrupts may be enabled by the 'struct scsi_cmnd' done | ||
5876 | * function, add the command to the end of the board's done queue. | ||
5877 | * The done function for the command will be called from | ||
5878 | * advansys_interrupt(). | ||
5879 | */ | ||
5880 | asc_enqueue(&boardp->done, scp, ASC_BACK); | ||
5881 | |||
5882 | /* | ||
5883 | * Free all 'adv_sgblk_t' structures allocated for the request. | ||
5884 | */ | ||
5885 | while ((sgblkp = reqp->sgblkp) != NULL) { | ||
5886 | /* Remove 'sgblkp' from the request list. */ | ||
5887 | reqp->sgblkp = sgblkp->next_sgblkp; | ||
5888 | |||
5889 | /* Add 'sgblkp' to the board free list. */ | ||
5890 | sgblkp->next_sgblkp = boardp->adv_sgblkp; | ||
5891 | boardp->adv_sgblkp = sgblkp; | ||
5892 | } | 2737 | } |
5893 | |||
5894 | /* | ||
5895 | * Free the adv_req_t structure used with the command by adding | ||
5896 | * it back to the board free list. | ||
5897 | */ | ||
5898 | reqp->next_reqp = boardp->adv_reqp; | ||
5899 | boardp->adv_reqp = reqp; | ||
5900 | |||
5901 | ASC_DBG(1, "adv_isr_callback: done\n"); | ||
5902 | |||
5903 | return; | ||
5904 | } | 2738 | } |
2739 | #endif /* ADVANSYS_DEBUG */ | ||
5905 | 2740 | ||
5906 | /* | 2741 | /* |
5907 | * adv_async_callback() - Adv Library asynchronous event callback function. | 2742 | * The advansys chip/microcode contains a 32-bit identifier for each command |
2743 | * known as the 'srb'. I don't know what it stands for. The driver used | ||
2744 | * to encode the scsi_cmnd pointer by calling virt_to_bus and retrieve it | ||
2745 | * with bus_to_virt. Now the driver keeps a per-host map of integers to | ||
2746 | * pointers. It auto-expands when full, unless it can't allocate memory. | ||
2747 | * Note that an srb of 0 is treated specially by the chip/firmware, hence | ||
2748 | * the return of i+1 in this routine, and the corresponding subtraction in | ||
2749 | * the inverse routine. | ||
5908 | */ | 2750 | */ |
5909 | static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code) | 2751 | #define BAD_SRB 0 |
2752 | static u32 advansys_ptr_to_srb(struct asc_dvc_var *asc_dvc, void *ptr) | ||
5910 | { | 2753 | { |
5911 | switch (code) { | 2754 | int i; |
5912 | case ADV_ASYNC_SCSI_BUS_RESET_DET: | 2755 | void **new_ptr; |
5913 | /* | ||
5914 | * The firmware detected a SCSI Bus reset. | ||
5915 | */ | ||
5916 | ASC_DBG(0, | ||
5917 | "adv_async_callback: ADV_ASYNC_SCSI_BUS_RESET_DET\n"); | ||
5918 | break; | ||
5919 | 2756 | ||
5920 | case ADV_ASYNC_RDMA_FAILURE: | 2757 | for (i = 0; i < asc_dvc->ptr_map_count; i++) { |
5921 | /* | 2758 | if (!asc_dvc->ptr_map[i]) |
5922 | * Handle RDMA failure by resetting the SCSI Bus and | 2759 | goto out; |
5923 | * possibly the chip if it is unresponsive. Log the error | 2760 | } |
5924 | * with a unique code. | ||
5925 | */ | ||
5926 | ASC_DBG(0, "adv_async_callback: ADV_ASYNC_RDMA_FAILURE\n"); | ||
5927 | AdvResetChipAndSB(adv_dvc_varp); | ||
5928 | break; | ||
5929 | 2761 | ||
5930 | case ADV_HOST_SCSI_BUS_RESET: | 2762 | if (asc_dvc->ptr_map_count == 0) |
5931 | /* | 2763 | asc_dvc->ptr_map_count = 1; |
5932 | * Host generated SCSI bus reset occurred. | 2764 | else |
5933 | */ | 2765 | asc_dvc->ptr_map_count *= 2; |
5934 | ASC_DBG(0, "adv_async_callback: ADV_HOST_SCSI_BUS_RESET\n"); | ||
5935 | break; | ||
5936 | 2766 | ||
5937 | default: | 2767 | new_ptr = krealloc(asc_dvc->ptr_map, |
5938 | ASC_DBG1(0, "DvcAsyncCallBack: unknown code 0x%x\n", code); | 2768 | asc_dvc->ptr_map_count * sizeof(void *), GFP_ATOMIC); |
5939 | break; | 2769 | if (!new_ptr) |
5940 | } | 2770 | return BAD_SRB; |
2771 | asc_dvc->ptr_map = new_ptr; | ||
2772 | out: | ||
2773 | ASC_DBG(3, "Putting ptr %p into array offset %d\n", ptr, i); | ||
2774 | asc_dvc->ptr_map[i] = ptr; | ||
2775 | return i + 1; | ||
5941 | } | 2776 | } |
5942 | 2777 | ||
5943 | /* | 2778 | static void * advansys_srb_to_ptr(struct asc_dvc_var *asc_dvc, u32 srb) |
5944 | * Add a 'REQP' to the end of specified queue. Set 'tidmask' | ||
5945 | * to indicate a command is queued for the device. | ||
5946 | * | ||
5947 | * 'flag' may be either ASC_FRONT or ASC_BACK. | ||
5948 | * | ||
5949 | * 'REQPNEXT(reqp)' returns reqp's next pointer. | ||
5950 | */ | ||
5951 | static void asc_enqueue(asc_queue_t *ascq, REQP reqp, int flag) | ||
5952 | { | 2779 | { |
5953 | int tid; | 2780 | void *ptr; |
5954 | |||
5955 | ASC_DBG3(3, "asc_enqueue: ascq 0x%lx, reqp 0x%lx, flag %d\n", | ||
5956 | (ulong)ascq, (ulong)reqp, flag); | ||
5957 | ASC_ASSERT(reqp != NULL); | ||
5958 | ASC_ASSERT(flag == ASC_FRONT || flag == ASC_BACK); | ||
5959 | tid = REQPTID(reqp); | ||
5960 | ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID); | ||
5961 | if (flag == ASC_FRONT) { | ||
5962 | reqp->host_scribble = (unsigned char *)ascq->q_first[tid]; | ||
5963 | ascq->q_first[tid] = reqp; | ||
5964 | /* If the queue was empty, set the last pointer. */ | ||
5965 | if (ascq->q_last[tid] == NULL) { | ||
5966 | ascq->q_last[tid] = reqp; | ||
5967 | } | ||
5968 | } else { /* ASC_BACK */ | ||
5969 | if (ascq->q_last[tid] != NULL) { | ||
5970 | ascq->q_last[tid]->host_scribble = | ||
5971 | (unsigned char *)reqp; | ||
5972 | } | ||
5973 | ascq->q_last[tid] = reqp; | ||
5974 | reqp->host_scribble = NULL; | ||
5975 | /* If the queue was empty, set the first pointer. */ | ||
5976 | if (ascq->q_first[tid] == NULL) { | ||
5977 | ascq->q_first[tid] = reqp; | ||
5978 | } | ||
5979 | } | ||
5980 | /* The queue has at least one entry, set its bit. */ | ||
5981 | ascq->q_tidmask |= ADV_TID_TO_TIDMASK(tid); | ||
5982 | #ifdef ADVANSYS_STATS | ||
5983 | /* Maintain request queue statistics. */ | ||
5984 | ascq->q_tot_cnt[tid]++; | ||
5985 | ascq->q_cur_cnt[tid]++; | ||
5986 | if (ascq->q_cur_cnt[tid] > ascq->q_max_cnt[tid]) { | ||
5987 | ascq->q_max_cnt[tid] = ascq->q_cur_cnt[tid]; | ||
5988 | ASC_DBG2(2, "asc_enqueue: new q_max_cnt[%d] %d\n", | ||
5989 | tid, ascq->q_max_cnt[tid]); | ||
5990 | } | ||
5991 | REQPTIME(reqp) = REQTIMESTAMP(); | ||
5992 | #endif /* ADVANSYS_STATS */ | ||
5993 | ASC_DBG1(3, "asc_enqueue: reqp 0x%lx\n", (ulong)reqp); | ||
5994 | return; | ||
5995 | } | ||
5996 | 2781 | ||
5997 | /* | 2782 | srb--; |
5998 | * Return first queued 'REQP' on the specified queue for | 2783 | if (srb >= asc_dvc->ptr_map_count) { |
5999 | * the specified target device. Clear the 'tidmask' bit for | 2784 | printk("advansys: bad SRB %u, max %u\n", srb, |
6000 | * the device if no more commands are left queued for it. | 2785 | asc_dvc->ptr_map_count); |
6001 | * | 2786 | return NULL; |
6002 | * 'REQPNEXT(reqp)' returns reqp's next pointer. | ||
6003 | */ | ||
6004 | static REQP asc_dequeue(asc_queue_t *ascq, int tid) | ||
6005 | { | ||
6006 | REQP reqp; | ||
6007 | |||
6008 | ASC_DBG2(3, "asc_dequeue: ascq 0x%lx, tid %d\n", (ulong)ascq, tid); | ||
6009 | ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID); | ||
6010 | if ((reqp = ascq->q_first[tid]) != NULL) { | ||
6011 | ASC_ASSERT(ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)); | ||
6012 | ascq->q_first[tid] = REQPNEXT(reqp); | ||
6013 | /* If the queue is empty, clear its bit and the last pointer. */ | ||
6014 | if (ascq->q_first[tid] == NULL) { | ||
6015 | ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid); | ||
6016 | ASC_ASSERT(ascq->q_last[tid] == reqp); | ||
6017 | ascq->q_last[tid] = NULL; | ||
6018 | } | ||
6019 | #ifdef ADVANSYS_STATS | ||
6020 | /* Maintain request queue statistics. */ | ||
6021 | ascq->q_cur_cnt[tid]--; | ||
6022 | ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0); | ||
6023 | REQTIMESTAT("asc_dequeue", ascq, reqp, tid); | ||
6024 | #endif /* ADVANSYS_STATS */ | ||
6025 | } | 2787 | } |
6026 | ASC_DBG1(3, "asc_dequeue: reqp 0x%lx\n", (ulong)reqp); | 2788 | ptr = asc_dvc->ptr_map[srb]; |
6027 | return reqp; | 2789 | asc_dvc->ptr_map[srb] = NULL; |
2790 | ASC_DBG(3, "Returning ptr %p from array offset %d\n", ptr, srb); | ||
2791 | return ptr; | ||
6028 | } | 2792 | } |
6029 | 2793 | ||
6030 | /* | 2794 | /* |
6031 | * Return a pointer to a singly linked list of all the requests queued | 2795 | * advansys_info() |
6032 | * for 'tid' on the 'asc_queue_t' pointed to by 'ascq'. | ||
6033 | * | ||
6034 | * If 'lastpp' is not NULL, '*lastpp' will be set to point to the | ||
6035 | * the last request returned in the singly linked list. | ||
6036 | * | ||
6037 | * 'tid' should either be a valid target id or if it is ASC_TID_ALL, | ||
6038 | * then all queued requests are concatenated into one list and | ||
6039 | * returned. | ||
6040 | * | 2796 | * |
6041 | * Note: If 'lastpp' is used to append a new list to the end of | 2797 | * Return suitable for printing on the console with the argument |
6042 | * an old list, only change the old list last pointer if '*lastpp' | 2798 | * adapter's configuration information. |
6043 | * (or the function return value) is not NULL, i.e. use a temporary | ||
6044 | * variable for 'lastpp' and check its value after the function return | ||
6045 | * before assigning it to the list last pointer. | ||
6046 | * | 2799 | * |
6047 | * Unfortunately collecting queuing time statistics adds overhead to | 2800 | * Note: The information line should not exceed ASC_INFO_SIZE bytes, |
6048 | * the function that isn't inherent to the function's algorithm. | 2801 | * otherwise the static 'info' array will be overrun. |
6049 | */ | 2802 | */ |
6050 | static REQP asc_dequeue_list(asc_queue_t *ascq, REQP *lastpp, int tid) | 2803 | static const char *advansys_info(struct Scsi_Host *shost) |
6051 | { | 2804 | { |
6052 | REQP firstp, lastp; | 2805 | static char info[ASC_INFO_SIZE]; |
6053 | int i; | 2806 | struct asc_board *boardp = shost_priv(shost); |
6054 | 2807 | ASC_DVC_VAR *asc_dvc_varp; | |
6055 | ASC_DBG2(3, "asc_dequeue_list: ascq 0x%lx, tid %d\n", (ulong)ascq, tid); | 2808 | ADV_DVC_VAR *adv_dvc_varp; |
6056 | ASC_ASSERT((tid == ASC_TID_ALL) || (tid >= 0 && tid <= ADV_MAX_TID)); | 2809 | char *busname; |
2810 | char *widename = NULL; | ||
6057 | 2811 | ||
6058 | /* | 2812 | if (ASC_NARROW_BOARD(boardp)) { |
6059 | * If 'tid' is not ASC_TID_ALL, return requests only for | 2813 | asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; |
6060 | * the specified 'tid'. If 'tid' is ASC_TID_ALL, return all | 2814 | ASC_DBG(1, "begin\n"); |
6061 | * requests for all tids. | 2815 | if (asc_dvc_varp->bus_type & ASC_IS_ISA) { |
6062 | */ | 2816 | if ((asc_dvc_varp->bus_type & ASC_IS_ISAPNP) == |
6063 | if (tid != ASC_TID_ALL) { | 2817 | ASC_IS_ISAPNP) { |
6064 | /* Return all requests for the specified 'tid'. */ | 2818 | busname = "ISA PnP"; |
6065 | if ((ascq->q_tidmask & ADV_TID_TO_TIDMASK(tid)) == 0) { | 2819 | } else { |
6066 | /* List is empty; Set first and last return pointers to NULL. */ | 2820 | busname = "ISA"; |
6067 | firstp = lastp = NULL; | ||
6068 | } else { | ||
6069 | firstp = ascq->q_first[tid]; | ||
6070 | lastp = ascq->q_last[tid]; | ||
6071 | ascq->q_first[tid] = ascq->q_last[tid] = NULL; | ||
6072 | ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid); | ||
6073 | #ifdef ADVANSYS_STATS | ||
6074 | { | ||
6075 | REQP reqp; | ||
6076 | ascq->q_cur_cnt[tid] = 0; | ||
6077 | for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) { | ||
6078 | REQTIMESTAT("asc_dequeue_list", ascq, | ||
6079 | reqp, tid); | ||
6080 | } | ||
6081 | } | 2821 | } |
6082 | #endif /* ADVANSYS_STATS */ | 2822 | sprintf(info, |
6083 | } | 2823 | "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X, DMA 0x%X", |
6084 | } else { | 2824 | ASC_VERSION, busname, |
6085 | /* Return all requests for all tids. */ | 2825 | (ulong)shost->io_port, |
6086 | firstp = lastp = NULL; | 2826 | (ulong)shost->io_port + ASC_IOADR_GAP - 1, |
6087 | for (i = 0; i <= ADV_MAX_TID; i++) { | 2827 | boardp->irq, shost->dma_channel); |
6088 | if (ascq->q_tidmask & ADV_TID_TO_TIDMASK(i)) { | 2828 | } else { |
6089 | if (firstp == NULL) { | 2829 | if (asc_dvc_varp->bus_type & ASC_IS_VL) { |
6090 | firstp = ascq->q_first[i]; | 2830 | busname = "VL"; |
6091 | lastp = ascq->q_last[i]; | 2831 | } else if (asc_dvc_varp->bus_type & ASC_IS_EISA) { |
2832 | busname = "EISA"; | ||
2833 | } else if (asc_dvc_varp->bus_type & ASC_IS_PCI) { | ||
2834 | if ((asc_dvc_varp->bus_type & ASC_IS_PCI_ULTRA) | ||
2835 | == ASC_IS_PCI_ULTRA) { | ||
2836 | busname = "PCI Ultra"; | ||
6092 | } else { | 2837 | } else { |
6093 | ASC_ASSERT(lastp != NULL); | 2838 | busname = "PCI"; |
6094 | lastp->host_scribble = | ||
6095 | (unsigned char *)ascq->q_first[i]; | ||
6096 | lastp = ascq->q_last[i]; | ||
6097 | } | 2839 | } |
6098 | ascq->q_first[i] = ascq->q_last[i] = NULL; | 2840 | } else { |
6099 | ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(i); | 2841 | busname = "?"; |
6100 | #ifdef ADVANSYS_STATS | 2842 | shost_printk(KERN_ERR, shost, "unknown bus " |
6101 | ascq->q_cur_cnt[i] = 0; | 2843 | "type %d\n", asc_dvc_varp->bus_type); |
6102 | #endif /* ADVANSYS_STATS */ | ||
6103 | } | ||
6104 | } | ||
6105 | #ifdef ADVANSYS_STATS | ||
6106 | { | ||
6107 | REQP reqp; | ||
6108 | for (reqp = firstp; reqp; reqp = REQPNEXT(reqp)) { | ||
6109 | REQTIMESTAT("asc_dequeue_list", ascq, reqp, | ||
6110 | reqp->device->id); | ||
6111 | } | 2844 | } |
2845 | sprintf(info, | ||
2846 | "AdvanSys SCSI %s: %s: IO 0x%lX-0x%lX, IRQ 0x%X", | ||
2847 | ASC_VERSION, busname, (ulong)shost->io_port, | ||
2848 | (ulong)shost->io_port + ASC_IOADR_GAP - 1, | ||
2849 | boardp->irq); | ||
6112 | } | 2850 | } |
6113 | #endif /* ADVANSYS_STATS */ | 2851 | } else { |
6114 | } | ||
6115 | if (lastpp) { | ||
6116 | *lastpp = lastp; | ||
6117 | } | ||
6118 | ASC_DBG1(3, "asc_dequeue_list: firstp 0x%lx\n", (ulong)firstp); | ||
6119 | return firstp; | ||
6120 | } | ||
6121 | |||
6122 | /* | ||
6123 | * Remove the specified 'REQP' from the specified queue for | ||
6124 | * the specified target device. Clear the 'tidmask' bit for the | ||
6125 | * device if no more commands are left queued for it. | ||
6126 | * | ||
6127 | * 'REQPNEXT(reqp)' returns reqp's the next pointer. | ||
6128 | * | ||
6129 | * Return ASC_TRUE if the command was found and removed, | ||
6130 | * otherwise return ASC_FALSE. | ||
6131 | */ | ||
6132 | static int asc_rmqueue(asc_queue_t *ascq, REQP reqp) | ||
6133 | { | ||
6134 | REQP currp, prevp; | ||
6135 | int tid; | ||
6136 | int ret = ASC_FALSE; | ||
6137 | |||
6138 | ASC_DBG2(3, "asc_rmqueue: ascq 0x%lx, reqp 0x%lx\n", | ||
6139 | (ulong)ascq, (ulong)reqp); | ||
6140 | ASC_ASSERT(reqp != NULL); | ||
6141 | |||
6142 | tid = REQPTID(reqp); | ||
6143 | ASC_ASSERT(tid >= 0 && tid <= ADV_MAX_TID); | ||
6144 | |||
6145 | /* | ||
6146 | * Handle the common case of 'reqp' being the first | ||
6147 | * entry on the queue. | ||
6148 | */ | ||
6149 | if (reqp == ascq->q_first[tid]) { | ||
6150 | ret = ASC_TRUE; | ||
6151 | ascq->q_first[tid] = REQPNEXT(reqp); | ||
6152 | /* If the queue is now empty, clear its bit and the last pointer. */ | ||
6153 | if (ascq->q_first[tid] == NULL) { | ||
6154 | ascq->q_tidmask &= ~ADV_TID_TO_TIDMASK(tid); | ||
6155 | ASC_ASSERT(ascq->q_last[tid] == reqp); | ||
6156 | ascq->q_last[tid] = NULL; | ||
6157 | } | ||
6158 | } else if (ascq->q_first[tid] != NULL) { | ||
6159 | ASC_ASSERT(ascq->q_last[tid] != NULL); | ||
6160 | /* | 2852 | /* |
6161 | * Because the case of 'reqp' being the first entry has been | 2853 | * Wide Adapter Information |
6162 | * handled above and it is known the queue is not empty, if | ||
6163 | * 'reqp' is found on the queue it is guaranteed the queue will | ||
6164 | * not become empty and that 'q_first[tid]' will not be changed. | ||
6165 | * | 2854 | * |
6166 | * Set 'prevp' to the first entry, 'currp' to the second entry, | 2855 | * Memory-mapped I/O is used instead of I/O space to access |
6167 | * and search for 'reqp'. | 2856 | * the adapter, but display the I/O Port range. The Memory |
2857 | * I/O address is displayed through the driver /proc file. | ||
6168 | */ | 2858 | */ |
6169 | for (prevp = ascq->q_first[tid], currp = REQPNEXT(prevp); | 2859 | adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; |
6170 | currp; prevp = currp, currp = REQPNEXT(currp)) { | 2860 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { |
6171 | if (currp == reqp) { | 2861 | widename = "Ultra-Wide"; |
6172 | ret = ASC_TRUE; | 2862 | } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { |
6173 | prevp->host_scribble = | 2863 | widename = "Ultra2-Wide"; |
6174 | (unsigned char *)REQPNEXT(currp); | 2864 | } else { |
6175 | reqp->host_scribble = NULL; | 2865 | widename = "Ultra3-Wide"; |
6176 | if (ascq->q_last[tid] == reqp) { | ||
6177 | ascq->q_last[tid] = prevp; | ||
6178 | } | ||
6179 | break; | ||
6180 | } | ||
6181 | } | 2866 | } |
2867 | sprintf(info, | ||
2868 | "AdvanSys SCSI %s: PCI %s: PCIMEM 0x%lX-0x%lX, IRQ 0x%X", | ||
2869 | ASC_VERSION, widename, (ulong)adv_dvc_varp->iop_base, | ||
2870 | (ulong)adv_dvc_varp->iop_base + boardp->asc_n_io_port - 1, boardp->irq); | ||
6182 | } | 2871 | } |
6183 | #ifdef ADVANSYS_STATS | 2872 | BUG_ON(strlen(info) >= ASC_INFO_SIZE); |
6184 | /* Maintain request queue statistics. */ | 2873 | ASC_DBG(1, "end\n"); |
6185 | if (ret == ASC_TRUE) { | 2874 | return info; |
6186 | ascq->q_cur_cnt[tid]--; | ||
6187 | REQTIMESTAT("asc_rmqueue", ascq, reqp, tid); | ||
6188 | } | ||
6189 | ASC_ASSERT(ascq->q_cur_cnt[tid] >= 0); | ||
6190 | #endif /* ADVANSYS_STATS */ | ||
6191 | ASC_DBG2(3, "asc_rmqueue: reqp 0x%lx, ret %d\n", (ulong)reqp, ret); | ||
6192 | return ret; | ||
6193 | } | 2875 | } |
6194 | 2876 | ||
2877 | #ifdef CONFIG_PROC_FS | ||
6195 | /* | 2878 | /* |
6196 | * Execute as many queued requests as possible for the specified queue. | 2879 | * asc_prt_line() |
2880 | * | ||
2881 | * If 'cp' is NULL print to the console, otherwise print to a buffer. | ||
6197 | * | 2882 | * |
6198 | * Calls asc_execute_scsi_cmnd() to execute a REQP/struct scsi_cmnd. | 2883 | * Return 0 if printing to the console, otherwise return the number of |
2884 | * bytes written to the buffer. | ||
2885 | * | ||
2886 | * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack | ||
2887 | * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes. | ||
6199 | */ | 2888 | */ |
6200 | static void asc_execute_queue(asc_queue_t *ascq) | 2889 | static int asc_prt_line(char *buf, int buflen, char *fmt, ...) |
6201 | { | 2890 | { |
6202 | ADV_SCSI_BIT_ID_TYPE scan_tidmask; | 2891 | va_list args; |
6203 | REQP reqp; | 2892 | int ret; |
6204 | int i; | 2893 | char s[ASC_PRTLINE_SIZE]; |
6205 | 2894 | ||
6206 | ASC_DBG1(1, "asc_execute_queue: ascq 0x%lx\n", (ulong)ascq); | 2895 | va_start(args, fmt); |
6207 | /* | 2896 | ret = vsprintf(s, fmt, args); |
6208 | * Execute queued commands for devices attached to | 2897 | BUG_ON(ret >= ASC_PRTLINE_SIZE); |
6209 | * the current board in round-robin fashion. | 2898 | if (buf == NULL) { |
6210 | */ | 2899 | (void)printk(s); |
6211 | scan_tidmask = ascq->q_tidmask; | 2900 | ret = 0; |
6212 | do { | 2901 | } else { |
6213 | for (i = 0; i <= ADV_MAX_TID; i++) { | 2902 | ret = min(buflen, ret); |
6214 | if (scan_tidmask & ADV_TID_TO_TIDMASK(i)) { | 2903 | memcpy(buf, s, ret); |
6215 | if ((reqp = asc_dequeue(ascq, i)) == NULL) { | 2904 | } |
6216 | scan_tidmask &= ~ADV_TID_TO_TIDMASK(i); | 2905 | va_end(args); |
6217 | } else | 2906 | return ret; |
6218 | if (asc_execute_scsi_cmnd | ||
6219 | ((struct scsi_cmnd *)reqp) | ||
6220 | == ASC_BUSY) { | ||
6221 | scan_tidmask &= ~ADV_TID_TO_TIDMASK(i); | ||
6222 | /* | ||
6223 | * The request returned ASC_BUSY. Enqueue at the front of | ||
6224 | * target's waiting list to maintain correct ordering. | ||
6225 | */ | ||
6226 | asc_enqueue(ascq, reqp, ASC_FRONT); | ||
6227 | } | ||
6228 | } | ||
6229 | } | ||
6230 | } while (scan_tidmask); | ||
6231 | return; | ||
6232 | } | 2907 | } |
6233 | 2908 | ||
6234 | #ifdef CONFIG_PROC_FS | ||
6235 | /* | 2909 | /* |
6236 | * asc_prt_board_devices() | 2910 | * asc_prt_board_devices() |
6237 | * | 2911 | * |
@@ -6245,14 +2919,13 @@ static void asc_execute_queue(asc_queue_t *ascq) | |||
6245 | */ | 2919 | */ |
6246 | static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen) | 2920 | static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen) |
6247 | { | 2921 | { |
6248 | asc_board_t *boardp; | 2922 | struct asc_board *boardp = shost_priv(shost); |
6249 | int leftlen; | 2923 | int leftlen; |
6250 | int totlen; | 2924 | int totlen; |
6251 | int len; | 2925 | int len; |
6252 | int chip_scsi_id; | 2926 | int chip_scsi_id; |
6253 | int i; | 2927 | int i; |
6254 | 2928 | ||
6255 | boardp = ASC_BOARDP(shost); | ||
6256 | leftlen = cplen; | 2929 | leftlen = cplen; |
6257 | totlen = len = 0; | 2930 | totlen = len = 0; |
6258 | 2931 | ||
@@ -6286,13 +2959,12 @@ static int asc_prt_board_devices(struct Scsi_Host *shost, char *cp, int cplen) | |||
6286 | */ | 2959 | */ |
6287 | static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen) | 2960 | static int asc_prt_adv_bios(struct Scsi_Host *shost, char *cp, int cplen) |
6288 | { | 2961 | { |
6289 | asc_board_t *boardp; | 2962 | struct asc_board *boardp = shost_priv(shost); |
6290 | int leftlen; | 2963 | int leftlen; |
6291 | int totlen; | 2964 | int totlen; |
6292 | int len; | 2965 | int len; |
6293 | ushort major, minor, letter; | 2966 | ushort major, minor, letter; |
6294 | 2967 | ||
6295 | boardp = ASC_BOARDP(shost); | ||
6296 | leftlen = cplen; | 2968 | leftlen = cplen; |
6297 | totlen = len = 0; | 2969 | totlen = len = 0; |
6298 | 2970 | ||
@@ -6452,7 +3124,7 @@ static int asc_get_eeprom_string(ushort *serialnum, uchar *cp) | |||
6452 | */ | 3124 | */ |
6453 | static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen) | 3125 | static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen) |
6454 | { | 3126 | { |
6455 | asc_board_t *boardp; | 3127 | struct asc_board *boardp = shost_priv(shost); |
6456 | ASC_DVC_VAR *asc_dvc_varp; | 3128 | ASC_DVC_VAR *asc_dvc_varp; |
6457 | int leftlen; | 3129 | int leftlen; |
6458 | int totlen; | 3130 | int totlen; |
@@ -6464,7 +3136,6 @@ static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen | |||
6464 | #endif /* CONFIG_ISA */ | 3136 | #endif /* CONFIG_ISA */ |
6465 | uchar serialstr[13]; | 3137 | uchar serialstr[13]; |
6466 | 3138 | ||
6467 | boardp = ASC_BOARDP(shost); | ||
6468 | asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; | 3139 | asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; |
6469 | ep = &boardp->eep_config.asc_eep; | 3140 | ep = &boardp->eep_config.asc_eep; |
6470 | 3141 | ||
@@ -6586,7 +3257,7 @@ static int asc_prt_asc_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen | |||
6586 | */ | 3257 | */ |
6587 | static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen) | 3258 | static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen) |
6588 | { | 3259 | { |
6589 | asc_board_t *boardp; | 3260 | struct asc_board *boardp = shost_priv(shost); |
6590 | ADV_DVC_VAR *adv_dvc_varp; | 3261 | ADV_DVC_VAR *adv_dvc_varp; |
6591 | int leftlen; | 3262 | int leftlen; |
6592 | int totlen; | 3263 | int totlen; |
@@ -6601,7 +3272,6 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen | |||
6601 | ushort *wordp; | 3272 | ushort *wordp; |
6602 | ushort sdtr_speed = 0; | 3273 | ushort sdtr_speed = 0; |
6603 | 3274 | ||
6604 | boardp = ASC_BOARDP(shost); | ||
6605 | adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; | 3275 | adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; |
6606 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { | 3276 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { |
6607 | ep_3550 = &boardp->eep_config.adv_3550_eep; | 3277 | ep_3550 = &boardp->eep_config.adv_3550_eep; |
@@ -6873,14 +3543,12 @@ static int asc_prt_adv_board_eeprom(struct Scsi_Host *shost, char *cp, int cplen | |||
6873 | */ | 3543 | */ |
6874 | static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen) | 3544 | static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen) |
6875 | { | 3545 | { |
6876 | asc_board_t *boardp; | 3546 | struct asc_board *boardp = shost_priv(shost); |
6877 | int leftlen; | 3547 | int leftlen; |
6878 | int totlen; | 3548 | int totlen; |
6879 | int len; | 3549 | int len; |
6880 | int chip_scsi_id; | 3550 | int chip_scsi_id; |
6881 | 3551 | ||
6882 | boardp = ASC_BOARDP(shost); | ||
6883 | |||
6884 | leftlen = cplen; | 3552 | leftlen = cplen; |
6885 | totlen = len = 0; | 3553 | totlen = len = 0; |
6886 | 3554 | ||
@@ -6912,10 +3580,7 @@ static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen) | |||
6912 | boardp->asc_n_io_port); | 3580 | boardp->asc_n_io_port); |
6913 | ASC_PRT_NEXT(); | 3581 | ASC_PRT_NEXT(); |
6914 | 3582 | ||
6915 | /* 'shost->n_io_port' may be truncated because it is only one byte. */ | 3583 | len = asc_prt_line(cp, leftlen, " io_port 0x%x\n", shost->io_port); |
6916 | len = asc_prt_line(cp, leftlen, | ||
6917 | " io_port 0x%x, n_io_port 0x%x\n", | ||
6918 | shost->io_port, shost->n_io_port); | ||
6919 | ASC_PRT_NEXT(); | 3584 | ASC_PRT_NEXT(); |
6920 | 3585 | ||
6921 | if (ASC_NARROW_BOARD(boardp)) { | 3586 | if (ASC_NARROW_BOARD(boardp)) { |
@@ -6940,7 +3605,7 @@ static int asc_prt_driver_conf(struct Scsi_Host *shost, char *cp, int cplen) | |||
6940 | */ | 3605 | */ |
6941 | static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen) | 3606 | static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen) |
6942 | { | 3607 | { |
6943 | asc_board_t *boardp; | 3608 | struct asc_board *boardp = shost_priv(shost); |
6944 | int chip_scsi_id; | 3609 | int chip_scsi_id; |
6945 | int leftlen; | 3610 | int leftlen; |
6946 | int totlen; | 3611 | int totlen; |
@@ -6950,7 +3615,6 @@ static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen) | |||
6950 | int i; | 3615 | int i; |
6951 | int renegotiate = 0; | 3616 | int renegotiate = 0; |
6952 | 3617 | ||
6953 | boardp = ASC_BOARDP(shost); | ||
6954 | v = &boardp->dvc_var.asc_dvc_var; | 3618 | v = &boardp->dvc_var.asc_dvc_var; |
6955 | c = &boardp->dvc_cfg.asc_dvc_cfg; | 3619 | c = &boardp->dvc_cfg.asc_dvc_cfg; |
6956 | chip_scsi_id = c->chip_scsi_id; | 3620 | chip_scsi_id = c->chip_scsi_id; |
@@ -6963,15 +3627,10 @@ static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen) | |||
6963 | shost->host_no); | 3627 | shost->host_no); |
6964 | ASC_PRT_NEXT(); | 3628 | ASC_PRT_NEXT(); |
6965 | 3629 | ||
6966 | len = asc_prt_line(cp, leftlen, | 3630 | len = asc_prt_line(cp, leftlen, " chip_version %u, mcode_date 0x%x, " |
6967 | " chip_version %u, lib_version 0x%x, lib_serial_no %u, mcode_date 0x%x\n", | 3631 | "mcode_version 0x%x, err_code %u\n", |
6968 | c->chip_version, c->lib_version, c->lib_serial_no, | 3632 | c->chip_version, c->mcode_date, c->mcode_version, |
6969 | c->mcode_date); | 3633 | v->err_code); |
6970 | ASC_PRT_NEXT(); | ||
6971 | |||
6972 | len = asc_prt_line(cp, leftlen, | ||
6973 | " mcode_version 0x%x, err_code %u\n", | ||
6974 | c->mcode_version, v->err_code); | ||
6975 | ASC_PRT_NEXT(); | 3634 | ASC_PRT_NEXT(); |
6976 | 3635 | ||
6977 | /* Current number of commands waiting for the host. */ | 3636 | /* Current number of commands waiting for the host. */ |
@@ -7128,7 +3787,7 @@ static int asc_prt_asc_board_info(struct Scsi_Host *shost, char *cp, int cplen) | |||
7128 | */ | 3787 | */ |
7129 | static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen) | 3788 | static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen) |
7130 | { | 3789 | { |
7131 | asc_board_t *boardp; | 3790 | struct asc_board *boardp = shost_priv(shost); |
7132 | int leftlen; | 3791 | int leftlen; |
7133 | int totlen; | 3792 | int totlen; |
7134 | int len; | 3793 | int len; |
@@ -7145,7 +3804,6 @@ static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen) | |||
7145 | ushort period = 0; | 3804 | ushort period = 0; |
7146 | int renegotiate = 0; | 3805 | int renegotiate = 0; |
7147 | 3806 | ||
7148 | boardp = ASC_BOARDP(shost); | ||
7149 | v = &boardp->dvc_var.adv_dvc_var; | 3807 | v = &boardp->dvc_var.adv_dvc_var; |
7150 | c = &boardp->dvc_cfg.adv_dvc_cfg; | 3808 | c = &boardp->dvc_cfg.adv_dvc_cfg; |
7151 | iop_base = v->iop_base; | 3809 | iop_base = v->iop_base; |
@@ -7167,10 +3825,9 @@ static int asc_prt_adv_board_info(struct Scsi_Host *shost, char *cp, int cplen) | |||
7167 | v->err_code); | 3825 | v->err_code); |
7168 | ASC_PRT_NEXT(); | 3826 | ASC_PRT_NEXT(); |
7169 | 3827 | ||
7170 | len = asc_prt_line(cp, leftlen, | 3828 | len = asc_prt_line(cp, leftlen, " chip_version %u, mcode_date 0x%x, " |
7171 | " chip_version %u, lib_version 0x%x, mcode_date 0x%x, mcode_version 0x%x\n", | 3829 | "mcode_version 0x%x\n", c->chip_version, |
7172 | c->chip_version, c->lib_version, c->mcode_date, | 3830 | c->mcode_date, c->mcode_version); |
7173 | c->mcode_version); | ||
7174 | ASC_PRT_NEXT(); | 3831 | ASC_PRT_NEXT(); |
7175 | 3832 | ||
7176 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | 3833 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); |
@@ -7376,12 +4033,12 @@ asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen, | |||
7376 | { | 4033 | { |
7377 | int cnt = 0; | 4034 | int cnt = 0; |
7378 | 4035 | ||
7379 | ASC_DBG3(2, "asc_proc_copy: offset %d, advoffset %d, cplen %d\n", | 4036 | ASC_DBG(2, "offset %d, advoffset %d, cplen %d\n", |
7380 | (unsigned)offset, (unsigned)advoffset, cplen); | 4037 | (unsigned)offset, (unsigned)advoffset, cplen); |
7381 | if (offset <= advoffset) { | 4038 | if (offset <= advoffset) { |
7382 | /* Read offset below current offset, copy everything. */ | 4039 | /* Read offset below current offset, copy everything. */ |
7383 | cnt = min(cplen, leftlen); | 4040 | cnt = min(cplen, leftlen); |
7384 | ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n", | 4041 | ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n", |
7385 | (ulong)curbuf, (ulong)cp, cnt); | 4042 | (ulong)curbuf, (ulong)cp, cnt); |
7386 | memcpy(curbuf, cp, cnt); | 4043 | memcpy(curbuf, cp, cnt); |
7387 | } else if (offset < advoffset + cplen) { | 4044 | } else if (offset < advoffset + cplen) { |
@@ -7389,1125 +4046,4537 @@ asc_proc_copy(off_t advoffset, off_t offset, char *curbuf, int leftlen, | |||
7389 | cnt = (advoffset + cplen) - offset; | 4046 | cnt = (advoffset + cplen) - offset; |
7390 | cp = (cp + cplen) - cnt; | 4047 | cp = (cp + cplen) - cnt; |
7391 | cnt = min(cnt, leftlen); | 4048 | cnt = min(cnt, leftlen); |
7392 | ASC_DBG3(2, "asc_proc_copy: curbuf 0x%lx, cp 0x%lx, cnt %d\n", | 4049 | ASC_DBG(2, "curbuf 0x%lx, cp 0x%lx, cnt %d\n", |
7393 | (ulong)curbuf, (ulong)cp, cnt); | 4050 | (ulong)curbuf, (ulong)cp, cnt); |
7394 | memcpy(curbuf, cp, cnt); | 4051 | memcpy(curbuf, cp, cnt); |
7395 | } | 4052 | } |
7396 | return cnt; | 4053 | return cnt; |
7397 | } | 4054 | } |
7398 | 4055 | ||
4056 | #ifdef ADVANSYS_STATS | ||
7399 | /* | 4057 | /* |
7400 | * asc_prt_line() | 4058 | * asc_prt_board_stats() |
7401 | * | 4059 | * |
7402 | * If 'cp' is NULL print to the console, otherwise print to a buffer. | 4060 | * Note: no single line should be greater than ASC_PRTLINE_SIZE, |
4061 | * cf. asc_prt_line(). | ||
7403 | * | 4062 | * |
7404 | * Return 0 if printing to the console, otherwise return the number of | 4063 | * Return the number of characters copied into 'cp'. No more than |
7405 | * bytes written to the buffer. | 4064 | * 'cplen' characters will be copied to 'cp'. |
4065 | */ | ||
4066 | static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen) | ||
4067 | { | ||
4068 | struct asc_board *boardp = shost_priv(shost); | ||
4069 | struct asc_stats *s = &boardp->asc_stats; | ||
4070 | |||
4071 | int leftlen = cplen; | ||
4072 | int len, totlen = 0; | ||
4073 | |||
4074 | len = asc_prt_line(cp, leftlen, | ||
4075 | "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", | ||
4076 | shost->host_no); | ||
4077 | ASC_PRT_NEXT(); | ||
4078 | |||
4079 | len = asc_prt_line(cp, leftlen, | ||
4080 | " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n", | ||
4081 | s->queuecommand, s->reset, s->biosparam, | ||
4082 | s->interrupt); | ||
4083 | ASC_PRT_NEXT(); | ||
4084 | |||
4085 | len = asc_prt_line(cp, leftlen, | ||
4086 | " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n", | ||
4087 | s->callback, s->done, s->build_error, | ||
4088 | s->adv_build_noreq, s->adv_build_nosg); | ||
4089 | ASC_PRT_NEXT(); | ||
4090 | |||
4091 | len = asc_prt_line(cp, leftlen, | ||
4092 | " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n", | ||
4093 | s->exe_noerror, s->exe_busy, s->exe_error, | ||
4094 | s->exe_unknown); | ||
4095 | ASC_PRT_NEXT(); | ||
4096 | |||
4097 | /* | ||
4098 | * Display data transfer statistics. | ||
4099 | */ | ||
4100 | if (s->xfer_cnt > 0) { | ||
4101 | len = asc_prt_line(cp, leftlen, " xfer_cnt %lu, xfer_elem %lu, ", | ||
4102 | s->xfer_cnt, s->xfer_elem); | ||
4103 | ASC_PRT_NEXT(); | ||
4104 | |||
4105 | len = asc_prt_line(cp, leftlen, "xfer_bytes %lu.%01lu kb\n", | ||
4106 | s->xfer_sect / 2, ASC_TENTHS(s->xfer_sect, 2)); | ||
4107 | ASC_PRT_NEXT(); | ||
4108 | |||
4109 | /* Scatter gather transfer statistics */ | ||
4110 | len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ", | ||
4111 | s->xfer_elem / s->xfer_cnt, | ||
4112 | ASC_TENTHS(s->xfer_elem, s->xfer_cnt)); | ||
4113 | ASC_PRT_NEXT(); | ||
4114 | |||
4115 | len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ", | ||
4116 | (s->xfer_sect / 2) / s->xfer_elem, | ||
4117 | ASC_TENTHS((s->xfer_sect / 2), s->xfer_elem)); | ||
4118 | ASC_PRT_NEXT(); | ||
4119 | |||
4120 | len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n", | ||
4121 | (s->xfer_sect / 2) / s->xfer_cnt, | ||
4122 | ASC_TENTHS((s->xfer_sect / 2), s->xfer_cnt)); | ||
4123 | ASC_PRT_NEXT(); | ||
4124 | } | ||
4125 | |||
4126 | return totlen; | ||
4127 | } | ||
4128 | #endif /* ADVANSYS_STATS */ | ||
4129 | |||
4130 | /* | ||
4131 | * advansys_proc_info() - /proc/scsi/advansys/{0,1,2,3,...} | ||
7406 | * | 4132 | * |
7407 | * Note: If any single line is greater than ASC_PRTLINE_SIZE bytes the stack | 4133 | * *buffer: I/O buffer |
7408 | * will be corrupted. 's[]' is defined to be ASC_PRTLINE_SIZE bytes. | 4134 | * **start: if inout == FALSE pointer into buffer where user read should start |
4135 | * offset: current offset into a /proc/scsi/advansys/[0...] file | ||
4136 | * length: length of buffer | ||
4137 | * hostno: Scsi_Host host_no | ||
4138 | * inout: TRUE - user is writing; FALSE - user is reading | ||
4139 | * | ||
4140 | * Return the number of bytes read from or written to a | ||
4141 | * /proc/scsi/advansys/[0...] file. | ||
4142 | * | ||
4143 | * Note: This function uses the per board buffer 'prtbuf' which is | ||
4144 | * allocated when the board is initialized in advansys_detect(). The | ||
4145 | * buffer is ASC_PRTBUF_SIZE bytes. The function asc_proc_copy() is | ||
4146 | * used to write to the buffer. The way asc_proc_copy() is written | ||
4147 | * if 'prtbuf' is too small it will not be overwritten. Instead the | ||
4148 | * user just won't get all the available statistics. | ||
7409 | */ | 4149 | */ |
7410 | static int asc_prt_line(char *buf, int buflen, char *fmt, ...) | 4150 | static int |
4151 | advansys_proc_info(struct Scsi_Host *shost, char *buffer, char **start, | ||
4152 | off_t offset, int length, int inout) | ||
7411 | { | 4153 | { |
7412 | va_list args; | 4154 | struct asc_board *boardp = shost_priv(shost); |
7413 | int ret; | 4155 | char *cp; |
7414 | char s[ASC_PRTLINE_SIZE]; | 4156 | int cplen; |
4157 | int cnt; | ||
4158 | int totcnt; | ||
4159 | int leftlen; | ||
4160 | char *curbuf; | ||
4161 | off_t advoffset; | ||
7415 | 4162 | ||
7416 | va_start(args, fmt); | 4163 | ASC_DBG(1, "begin\n"); |
7417 | ret = vsprintf(s, fmt, args); | 4164 | |
7418 | ASC_ASSERT(ret < ASC_PRTLINE_SIZE); | 4165 | /* |
7419 | if (buf == NULL) { | 4166 | * User write not supported. |
7420 | (void)printk(s); | 4167 | */ |
7421 | ret = 0; | 4168 | if (inout == TRUE) |
4169 | return -ENOSYS; | ||
4170 | |||
4171 | /* | ||
4172 | * User read of /proc/scsi/advansys/[0...] file. | ||
4173 | */ | ||
4174 | |||
4175 | /* Copy read data starting at the beginning of the buffer. */ | ||
4176 | *start = buffer; | ||
4177 | curbuf = buffer; | ||
4178 | advoffset = 0; | ||
4179 | totcnt = 0; | ||
4180 | leftlen = length; | ||
4181 | |||
4182 | /* | ||
4183 | * Get board configuration information. | ||
4184 | * | ||
4185 | * advansys_info() returns the board string from its own static buffer. | ||
4186 | */ | ||
4187 | cp = (char *)advansys_info(shost); | ||
4188 | strcat(cp, "\n"); | ||
4189 | cplen = strlen(cp); | ||
4190 | /* Copy board information. */ | ||
4191 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4192 | totcnt += cnt; | ||
4193 | leftlen -= cnt; | ||
4194 | if (leftlen == 0) { | ||
4195 | ASC_DBG(1, "totcnt %d\n", totcnt); | ||
4196 | return totcnt; | ||
4197 | } | ||
4198 | advoffset += cplen; | ||
4199 | curbuf += cnt; | ||
4200 | |||
4201 | /* | ||
4202 | * Display Wide Board BIOS Information. | ||
4203 | */ | ||
4204 | if (!ASC_NARROW_BOARD(boardp)) { | ||
4205 | cp = boardp->prtbuf; | ||
4206 | cplen = asc_prt_adv_bios(shost, cp, ASC_PRTBUF_SIZE); | ||
4207 | BUG_ON(cplen >= ASC_PRTBUF_SIZE); | ||
4208 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, | ||
4209 | cplen); | ||
4210 | totcnt += cnt; | ||
4211 | leftlen -= cnt; | ||
4212 | if (leftlen == 0) { | ||
4213 | ASC_DBG(1, "totcnt %d\n", totcnt); | ||
4214 | return totcnt; | ||
4215 | } | ||
4216 | advoffset += cplen; | ||
4217 | curbuf += cnt; | ||
4218 | } | ||
4219 | |||
4220 | /* | ||
4221 | * Display driver information for each device attached to the board. | ||
4222 | */ | ||
4223 | cp = boardp->prtbuf; | ||
4224 | cplen = asc_prt_board_devices(shost, cp, ASC_PRTBUF_SIZE); | ||
4225 | BUG_ON(cplen >= ASC_PRTBUF_SIZE); | ||
4226 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4227 | totcnt += cnt; | ||
4228 | leftlen -= cnt; | ||
4229 | if (leftlen == 0) { | ||
4230 | ASC_DBG(1, "totcnt %d\n", totcnt); | ||
4231 | return totcnt; | ||
4232 | } | ||
4233 | advoffset += cplen; | ||
4234 | curbuf += cnt; | ||
4235 | |||
4236 | /* | ||
4237 | * Display EEPROM configuration for the board. | ||
4238 | */ | ||
4239 | cp = boardp->prtbuf; | ||
4240 | if (ASC_NARROW_BOARD(boardp)) { | ||
4241 | cplen = asc_prt_asc_board_eeprom(shost, cp, ASC_PRTBUF_SIZE); | ||
7422 | } else { | 4242 | } else { |
7423 | ret = min(buflen, ret); | 4243 | cplen = asc_prt_adv_board_eeprom(shost, cp, ASC_PRTBUF_SIZE); |
7424 | memcpy(buf, s, ret); | ||
7425 | } | 4244 | } |
7426 | va_end(args); | 4245 | BUG_ON(cplen >= ASC_PRTBUF_SIZE); |
7427 | return ret; | 4246 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); |
4247 | totcnt += cnt; | ||
4248 | leftlen -= cnt; | ||
4249 | if (leftlen == 0) { | ||
4250 | ASC_DBG(1, "totcnt %d\n", totcnt); | ||
4251 | return totcnt; | ||
4252 | } | ||
4253 | advoffset += cplen; | ||
4254 | curbuf += cnt; | ||
4255 | |||
4256 | /* | ||
4257 | * Display driver configuration and information for the board. | ||
4258 | */ | ||
4259 | cp = boardp->prtbuf; | ||
4260 | cplen = asc_prt_driver_conf(shost, cp, ASC_PRTBUF_SIZE); | ||
4261 | BUG_ON(cplen >= ASC_PRTBUF_SIZE); | ||
4262 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4263 | totcnt += cnt; | ||
4264 | leftlen -= cnt; | ||
4265 | if (leftlen == 0) { | ||
4266 | ASC_DBG(1, "totcnt %d\n", totcnt); | ||
4267 | return totcnt; | ||
4268 | } | ||
4269 | advoffset += cplen; | ||
4270 | curbuf += cnt; | ||
4271 | |||
4272 | #ifdef ADVANSYS_STATS | ||
4273 | /* | ||
4274 | * Display driver statistics for the board. | ||
4275 | */ | ||
4276 | cp = boardp->prtbuf; | ||
4277 | cplen = asc_prt_board_stats(shost, cp, ASC_PRTBUF_SIZE); | ||
4278 | BUG_ON(cplen >= ASC_PRTBUF_SIZE); | ||
4279 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4280 | totcnt += cnt; | ||
4281 | leftlen -= cnt; | ||
4282 | if (leftlen == 0) { | ||
4283 | ASC_DBG(1, "totcnt %d\n", totcnt); | ||
4284 | return totcnt; | ||
4285 | } | ||
4286 | advoffset += cplen; | ||
4287 | curbuf += cnt; | ||
4288 | #endif /* ADVANSYS_STATS */ | ||
4289 | |||
4290 | /* | ||
4291 | * Display Asc Library dynamic configuration information | ||
4292 | * for the board. | ||
4293 | */ | ||
4294 | cp = boardp->prtbuf; | ||
4295 | if (ASC_NARROW_BOARD(boardp)) { | ||
4296 | cplen = asc_prt_asc_board_info(shost, cp, ASC_PRTBUF_SIZE); | ||
4297 | } else { | ||
4298 | cplen = asc_prt_adv_board_info(shost, cp, ASC_PRTBUF_SIZE); | ||
4299 | } | ||
4300 | BUG_ON(cplen >= ASC_PRTBUF_SIZE); | ||
4301 | cnt = asc_proc_copy(advoffset, offset, curbuf, leftlen, cp, cplen); | ||
4302 | totcnt += cnt; | ||
4303 | leftlen -= cnt; | ||
4304 | if (leftlen == 0) { | ||
4305 | ASC_DBG(1, "totcnt %d\n", totcnt); | ||
4306 | return totcnt; | ||
4307 | } | ||
4308 | advoffset += cplen; | ||
4309 | curbuf += cnt; | ||
4310 | |||
4311 | ASC_DBG(1, "totcnt %d\n", totcnt); | ||
4312 | |||
4313 | return totcnt; | ||
7428 | } | 4314 | } |
7429 | #endif /* CONFIG_PROC_FS */ | 4315 | #endif /* CONFIG_PROC_FS */ |
7430 | 4316 | ||
7431 | /* | 4317 | static void asc_scsi_done(struct scsi_cmnd *scp) |
7432 | * --- Functions Required by the Asc Library | 4318 | { |
7433 | */ | 4319 | scsi_dma_unmap(scp); |
4320 | ASC_STATS(scp->device->host, done); | ||
4321 | scp->scsi_done(scp); | ||
4322 | } | ||
7434 | 4323 | ||
7435 | /* | 4324 | static void AscSetBank(PortAddr iop_base, uchar bank) |
7436 | * Delay for 'n' milliseconds. Don't use the 'jiffies' | ||
7437 | * global variable which is incremented once every 5 ms | ||
7438 | * from a timer interrupt, because this function may be | ||
7439 | * called when interrupts are disabled. | ||
7440 | */ | ||
7441 | static void DvcSleepMilliSecond(ADV_DCNT n) | ||
7442 | { | 4325 | { |
7443 | ASC_DBG1(4, "DvcSleepMilliSecond: %lu\n", (ulong)n); | 4326 | uchar val; |
7444 | mdelay(n); | 4327 | |
4328 | val = AscGetChipControl(iop_base) & | ||
4329 | (~ | ||
4330 | (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | | ||
4331 | CC_CHIP_RESET)); | ||
4332 | if (bank == 1) { | ||
4333 | val |= CC_BANK_ONE; | ||
4334 | } else if (bank == 2) { | ||
4335 | val |= CC_DIAG | CC_BANK_ONE; | ||
4336 | } else { | ||
4337 | val &= ~CC_BANK_ONE; | ||
4338 | } | ||
4339 | AscSetChipControl(iop_base, val); | ||
7445 | } | 4340 | } |
7446 | 4341 | ||
7447 | /* | 4342 | static void AscSetChipIH(PortAddr iop_base, ushort ins_code) |
7448 | * Currently and inline noop but leave as a placeholder. | ||
7449 | * Leave DvcEnterCritical() as a noop placeholder. | ||
7450 | */ | ||
7451 | static inline ulong DvcEnterCritical(void) | ||
7452 | { | 4343 | { |
7453 | return 0; | 4344 | AscSetBank(iop_base, 1); |
4345 | AscWriteChipIH(iop_base, ins_code); | ||
4346 | AscSetBank(iop_base, 0); | ||
7454 | } | 4347 | } |
7455 | 4348 | ||
7456 | /* | 4349 | static int AscStartChip(PortAddr iop_base) |
7457 | * Critical sections are all protected by the board spinlock. | 4350 | { |
7458 | * Leave DvcLeaveCritical() as a noop placeholder. | 4351 | AscSetChipControl(iop_base, 0); |
7459 | */ | 4352 | if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) { |
7460 | static inline void DvcLeaveCritical(ulong flags) | 4353 | return (0); |
4354 | } | ||
4355 | return (1); | ||
4356 | } | ||
4357 | |||
4358 | static int AscStopChip(PortAddr iop_base) | ||
4359 | { | ||
4360 | uchar cc_val; | ||
4361 | |||
4362 | cc_val = | ||
4363 | AscGetChipControl(iop_base) & | ||
4364 | (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG)); | ||
4365 | AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT)); | ||
4366 | AscSetChipIH(iop_base, INS_HALT); | ||
4367 | AscSetChipIH(iop_base, INS_RFLAG_WTM); | ||
4368 | if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) { | ||
4369 | return (0); | ||
4370 | } | ||
4371 | return (1); | ||
4372 | } | ||
4373 | |||
4374 | static int AscIsChipHalted(PortAddr iop_base) | ||
4375 | { | ||
4376 | if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) { | ||
4377 | if ((AscGetChipControl(iop_base) & CC_HALT) != 0) { | ||
4378 | return (1); | ||
4379 | } | ||
4380 | } | ||
4381 | return (0); | ||
4382 | } | ||
4383 | |||
4384 | static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc) | ||
4385 | { | ||
4386 | PortAddr iop_base; | ||
4387 | int i = 10; | ||
4388 | |||
4389 | iop_base = asc_dvc->iop_base; | ||
4390 | while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) | ||
4391 | && (i-- > 0)) { | ||
4392 | mdelay(100); | ||
4393 | } | ||
4394 | AscStopChip(iop_base); | ||
4395 | AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT); | ||
4396 | udelay(60); | ||
4397 | AscSetChipIH(iop_base, INS_RFLAG_WTM); | ||
4398 | AscSetChipIH(iop_base, INS_HALT); | ||
4399 | AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT); | ||
4400 | AscSetChipControl(iop_base, CC_HALT); | ||
4401 | mdelay(200); | ||
4402 | AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT); | ||
4403 | AscSetChipStatus(iop_base, 0); | ||
4404 | return (AscIsChipHalted(iop_base)); | ||
4405 | } | ||
4406 | |||
4407 | static int AscFindSignature(PortAddr iop_base) | ||
4408 | { | ||
4409 | ushort sig_word; | ||
4410 | |||
4411 | ASC_DBG(1, "AscGetChipSignatureByte(0x%x) 0x%x\n", | ||
4412 | iop_base, AscGetChipSignatureByte(iop_base)); | ||
4413 | if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) { | ||
4414 | ASC_DBG(1, "AscGetChipSignatureWord(0x%x) 0x%x\n", | ||
4415 | iop_base, AscGetChipSignatureWord(iop_base)); | ||
4416 | sig_word = AscGetChipSignatureWord(iop_base); | ||
4417 | if ((sig_word == (ushort)ASC_1000_ID0W) || | ||
4418 | (sig_word == (ushort)ASC_1000_ID0W_FIX)) { | ||
4419 | return (1); | ||
4420 | } | ||
4421 | } | ||
4422 | return (0); | ||
4423 | } | ||
4424 | |||
4425 | static void AscEnableInterrupt(PortAddr iop_base) | ||
4426 | { | ||
4427 | ushort cfg; | ||
4428 | |||
4429 | cfg = AscGetChipCfgLsw(iop_base); | ||
4430 | AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON); | ||
4431 | } | ||
4432 | |||
4433 | static void AscDisableInterrupt(PortAddr iop_base) | ||
4434 | { | ||
4435 | ushort cfg; | ||
4436 | |||
4437 | cfg = AscGetChipCfgLsw(iop_base); | ||
4438 | AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON)); | ||
4439 | } | ||
4440 | |||
4441 | static uchar AscReadLramByte(PortAddr iop_base, ushort addr) | ||
4442 | { | ||
4443 | unsigned char byte_data; | ||
4444 | unsigned short word_data; | ||
4445 | |||
4446 | if (isodd_word(addr)) { | ||
4447 | AscSetChipLramAddr(iop_base, addr - 1); | ||
4448 | word_data = AscGetChipLramData(iop_base); | ||
4449 | byte_data = (word_data >> 8) & 0xFF; | ||
4450 | } else { | ||
4451 | AscSetChipLramAddr(iop_base, addr); | ||
4452 | word_data = AscGetChipLramData(iop_base); | ||
4453 | byte_data = word_data & 0xFF; | ||
4454 | } | ||
4455 | return byte_data; | ||
4456 | } | ||
4457 | |||
4458 | static ushort AscReadLramWord(PortAddr iop_base, ushort addr) | ||
4459 | { | ||
4460 | ushort word_data; | ||
4461 | |||
4462 | AscSetChipLramAddr(iop_base, addr); | ||
4463 | word_data = AscGetChipLramData(iop_base); | ||
4464 | return (word_data); | ||
4465 | } | ||
4466 | |||
4467 | #if CC_VERY_LONG_SG_LIST | ||
4468 | static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr) | ||
4469 | { | ||
4470 | ushort val_low, val_high; | ||
4471 | ASC_DCNT dword_data; | ||
4472 | |||
4473 | AscSetChipLramAddr(iop_base, addr); | ||
4474 | val_low = AscGetChipLramData(iop_base); | ||
4475 | val_high = AscGetChipLramData(iop_base); | ||
4476 | dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low; | ||
4477 | return (dword_data); | ||
4478 | } | ||
4479 | #endif /* CC_VERY_LONG_SG_LIST */ | ||
4480 | |||
4481 | static void | ||
4482 | AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words) | ||
4483 | { | ||
4484 | int i; | ||
4485 | |||
4486 | AscSetChipLramAddr(iop_base, s_addr); | ||
4487 | for (i = 0; i < words; i++) { | ||
4488 | AscSetChipLramData(iop_base, set_wval); | ||
4489 | } | ||
4490 | } | ||
4491 | |||
4492 | static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val) | ||
4493 | { | ||
4494 | AscSetChipLramAddr(iop_base, addr); | ||
4495 | AscSetChipLramData(iop_base, word_val); | ||
4496 | } | ||
4497 | |||
4498 | static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val) | ||
7461 | { | 4499 | { |
7462 | return; | 4500 | ushort word_data; |
4501 | |||
4502 | if (isodd_word(addr)) { | ||
4503 | addr--; | ||
4504 | word_data = AscReadLramWord(iop_base, addr); | ||
4505 | word_data &= 0x00FF; | ||
4506 | word_data |= (((ushort)byte_val << 8) & 0xFF00); | ||
4507 | } else { | ||
4508 | word_data = AscReadLramWord(iop_base, addr); | ||
4509 | word_data &= 0xFF00; | ||
4510 | word_data |= ((ushort)byte_val & 0x00FF); | ||
4511 | } | ||
4512 | AscWriteLramWord(iop_base, addr, word_data); | ||
7463 | } | 4513 | } |
7464 | 4514 | ||
7465 | /* | 4515 | /* |
7466 | * void | 4516 | * Copy 2 bytes to LRAM. |
7467 | * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words) | ||
7468 | * | ||
7469 | * Calling/Exit State: | ||
7470 | * none | ||
7471 | * | 4517 | * |
7472 | * Description: | 4518 | * The source data is assumed to be in little-endian order in memory |
7473 | * Output an ASC_SCSI_Q structure to the chip | 4519 | * and is maintained in little-endian order when written to LRAM. |
7474 | */ | 4520 | */ |
7475 | static void | 4521 | static void |
7476 | DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words) | 4522 | AscMemWordCopyPtrToLram(PortAddr iop_base, |
4523 | ushort s_addr, uchar *s_buffer, int words) | ||
7477 | { | 4524 | { |
7478 | int i; | 4525 | int i; |
7479 | 4526 | ||
7480 | ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words); | ||
7481 | AscSetChipLramAddr(iop_base, s_addr); | 4527 | AscSetChipLramAddr(iop_base, s_addr); |
7482 | for (i = 0; i < 2 * words; i += 2) { | 4528 | for (i = 0; i < 2 * words; i += 2) { |
7483 | if (i == 4 || i == 20) { | 4529 | /* |
7484 | continue; | 4530 | * On a little-endian system the second argument below |
7485 | } | 4531 | * produces a little-endian ushort which is written to |
4532 | * LRAM in little-endian order. On a big-endian system | ||
4533 | * the second argument produces a big-endian ushort which | ||
4534 | * is "transparently" byte-swapped by outpw() and written | ||
4535 | * in little-endian order to LRAM. | ||
4536 | */ | ||
7486 | outpw(iop_base + IOP_RAM_DATA, | 4537 | outpw(iop_base + IOP_RAM_DATA, |
7487 | ((ushort)outbuf[i + 1] << 8) | outbuf[i]); | 4538 | ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); |
7488 | } | 4539 | } |
7489 | } | 4540 | } |
7490 | 4541 | ||
7491 | /* | 4542 | /* |
7492 | * void | 4543 | * Copy 4 bytes to LRAM. |
7493 | * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words) | ||
7494 | * | 4544 | * |
7495 | * Calling/Exit State: | 4545 | * The source data is assumed to be in little-endian order in memory |
7496 | * none | 4546 | * and is maintained in little-endian order when writen to LRAM. |
4547 | */ | ||
4548 | static void | ||
4549 | AscMemDWordCopyPtrToLram(PortAddr iop_base, | ||
4550 | ushort s_addr, uchar *s_buffer, int dwords) | ||
4551 | { | ||
4552 | int i; | ||
4553 | |||
4554 | AscSetChipLramAddr(iop_base, s_addr); | ||
4555 | for (i = 0; i < 4 * dwords; i += 4) { | ||
4556 | outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */ | ||
4557 | outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */ | ||
4558 | } | ||
4559 | } | ||
4560 | |||
4561 | /* | ||
4562 | * Copy 2 bytes from LRAM. | ||
7497 | * | 4563 | * |
7498 | * Description: | 4564 | * The source data is assumed to be in little-endian order in LRAM |
7499 | * Input an ASC_QDONE_INFO structure from the chip | 4565 | * and is maintained in little-endian order when written to memory. |
7500 | */ | 4566 | */ |
7501 | static void | 4567 | static void |
7502 | DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words) | 4568 | AscMemWordCopyPtrFromLram(PortAddr iop_base, |
4569 | ushort s_addr, uchar *d_buffer, int words) | ||
7503 | { | 4570 | { |
7504 | int i; | 4571 | int i; |
7505 | ushort word; | 4572 | ushort word; |
7506 | 4573 | ||
7507 | AscSetChipLramAddr(iop_base, s_addr); | 4574 | AscSetChipLramAddr(iop_base, s_addr); |
7508 | for (i = 0; i < 2 * words; i += 2) { | 4575 | for (i = 0; i < 2 * words; i += 2) { |
7509 | if (i == 10) { | ||
7510 | continue; | ||
7511 | } | ||
7512 | word = inpw(iop_base + IOP_RAM_DATA); | 4576 | word = inpw(iop_base + IOP_RAM_DATA); |
7513 | inbuf[i] = word & 0xff; | 4577 | d_buffer[i] = word & 0xff; |
7514 | inbuf[i + 1] = (word >> 8) & 0xff; | 4578 | d_buffer[i + 1] = (word >> 8) & 0xff; |
7515 | } | 4579 | } |
7516 | ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words); | ||
7517 | } | 4580 | } |
7518 | 4581 | ||
7519 | /* | 4582 | static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words) |
7520 | * Read a PCI configuration byte. | ||
7521 | */ | ||
7522 | static uchar __init DvcReadPCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset) | ||
7523 | { | 4583 | { |
7524 | #ifdef CONFIG_PCI | 4584 | ASC_DCNT sum; |
7525 | uchar byte_data; | 4585 | int i; |
7526 | pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data); | 4586 | |
7527 | return byte_data; | 4587 | sum = 0L; |
7528 | #else /* !defined(CONFIG_PCI) */ | 4588 | for (i = 0; i < words; i++, s_addr += 2) { |
7529 | return 0; | 4589 | sum += AscReadLramWord(iop_base, s_addr); |
7530 | #endif /* !defined(CONFIG_PCI) */ | 4590 | } |
4591 | return (sum); | ||
7531 | } | 4592 | } |
7532 | 4593 | ||
7533 | /* | 4594 | static ushort AscInitLram(ASC_DVC_VAR *asc_dvc) |
7534 | * Write a PCI configuration byte. | ||
7535 | */ | ||
7536 | static void __init | ||
7537 | DvcWritePCIConfigByte(ASC_DVC_VAR *asc_dvc, ushort offset, uchar byte_data) | ||
7538 | { | 4595 | { |
7539 | #ifdef CONFIG_PCI | 4596 | uchar i; |
7540 | pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data); | 4597 | ushort s_addr; |
7541 | #endif /* CONFIG_PCI */ | 4598 | PortAddr iop_base; |
4599 | ushort warn_code; | ||
4600 | |||
4601 | iop_base = asc_dvc->iop_base; | ||
4602 | warn_code = 0; | ||
4603 | AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0, | ||
4604 | (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) * | ||
4605 | 64) >> 1)); | ||
4606 | i = ASC_MIN_ACTIVE_QNO; | ||
4607 | s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE; | ||
4608 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD), | ||
4609 | (uchar)(i + 1)); | ||
4610 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD), | ||
4611 | (uchar)(asc_dvc->max_total_qng)); | ||
4612 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO), | ||
4613 | (uchar)i); | ||
4614 | i++; | ||
4615 | s_addr += ASC_QBLK_SIZE; | ||
4616 | for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) { | ||
4617 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD), | ||
4618 | (uchar)(i + 1)); | ||
4619 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD), | ||
4620 | (uchar)(i - 1)); | ||
4621 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO), | ||
4622 | (uchar)i); | ||
4623 | } | ||
4624 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD), | ||
4625 | (uchar)ASC_QLINK_END); | ||
4626 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD), | ||
4627 | (uchar)(asc_dvc->max_total_qng - 1)); | ||
4628 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO), | ||
4629 | (uchar)asc_dvc->max_total_qng); | ||
4630 | i++; | ||
4631 | s_addr += ASC_QBLK_SIZE; | ||
4632 | for (; i <= (uchar)(asc_dvc->max_total_qng + 3); | ||
4633 | i++, s_addr += ASC_QBLK_SIZE) { | ||
4634 | AscWriteLramByte(iop_base, | ||
4635 | (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i); | ||
4636 | AscWriteLramByte(iop_base, | ||
4637 | (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i); | ||
4638 | AscWriteLramByte(iop_base, | ||
4639 | (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i); | ||
4640 | } | ||
4641 | return warn_code; | ||
7542 | } | 4642 | } |
7543 | 4643 | ||
7544 | /* | 4644 | static ASC_DCNT |
7545 | * Return the BIOS address of the adapter at the specified | 4645 | AscLoadMicroCode(PortAddr iop_base, |
7546 | * I/O port and with the specified bus type. | 4646 | ushort s_addr, uchar *mcode_buf, ushort mcode_size) |
7547 | */ | ||
7548 | static ushort __init AscGetChipBiosAddress(PortAddr iop_base, ushort bus_type) | ||
7549 | { | 4647 | { |
7550 | ushort cfg_lsw; | 4648 | ASC_DCNT chksum; |
7551 | ushort bios_addr; | 4649 | ushort mcode_word_size; |
4650 | ushort mcode_chksum; | ||
7552 | 4651 | ||
7553 | /* | 4652 | /* Write the microcode buffer starting at LRAM address 0. */ |
7554 | * The PCI BIOS is re-located by the motherboard BIOS. Because | 4653 | mcode_word_size = (ushort)(mcode_size >> 1); |
7555 | * of this the driver can not determine where a PCI BIOS is | 4654 | AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size); |
7556 | * loaded and executes. | 4655 | AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size); |
7557 | */ | 4656 | |
7558 | if (bus_type & ASC_IS_PCI) { | 4657 | chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size); |
7559 | return (0); | 4658 | ASC_DBG(1, "chksum 0x%lx\n", (ulong)chksum); |
4659 | mcode_chksum = (ushort)AscMemSumLramWord(iop_base, | ||
4660 | (ushort)ASC_CODE_SEC_BEG, | ||
4661 | (ushort)((mcode_size - | ||
4662 | s_addr - (ushort) | ||
4663 | ASC_CODE_SEC_BEG) / | ||
4664 | 2)); | ||
4665 | ASC_DBG(1, "mcode_chksum 0x%lx\n", (ulong)mcode_chksum); | ||
4666 | AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum); | ||
4667 | AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size); | ||
4668 | return chksum; | ||
4669 | } | ||
4670 | |||
4671 | /* Microcode buffer is kept after initialization for error recovery. */ | ||
4672 | static uchar _asc_mcode_buf[] = { | ||
4673 | 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
4674 | 0x00, 0x00, 0x00, 0x00, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, | ||
4675 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
4676 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
4677 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
4678 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, | ||
4679 | 0x01, 0x00, 0x00, 0x00, 0x00, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
4680 | 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
4681 | 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, | ||
4682 | 0x00, 0x00, 0x00, 0x00, 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, | ||
4683 | 0x00, 0x00, 0xE4, 0x88, 0x00, 0x00, 0x00, 0x00, 0x80, 0x73, 0x48, 0x04, | ||
4684 | 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, 0x03, 0x23, 0x36, 0x40, | ||
4685 | 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2, | ||
4686 | 0xC2, 0x00, 0x92, 0x80, 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, | ||
4687 | 0xDF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x4F, 0x00, 0xF5, 0x00, | ||
4688 | 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, 0x92, 0x80, 0x80, 0x62, | ||
4689 | 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8, | ||
4690 | 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, | ||
4691 | 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, 0xD2, 0xC1, 0x80, 0x73, 0xCD, 0x04, | ||
4692 | 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, 0xC6, 0x81, 0xC2, 0x88, | ||
4693 | 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00, | ||
4694 | 0x84, 0x97, 0x07, 0xA6, 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, | ||
4695 | 0x03, 0x03, 0x01, 0xDE, 0xC2, 0x88, 0xCE, 0x00, 0x69, 0x60, 0xCE, 0x00, | ||
4696 | 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, 0x80, 0x63, 0x07, 0xA6, | ||
4697 | 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6, | ||
4698 | 0x34, 0x01, 0x00, 0x33, 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, | ||
4699 | 0x04, 0xCA, 0x0D, 0x23, 0x68, 0x98, 0x4D, 0x04, 0x04, 0x85, 0x05, 0xD8, | ||
4700 | 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, 0xF8, 0x88, 0xFB, 0x23, | ||
4701 | 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01, | ||
4702 | 0x00, 0x33, 0x0A, 0x00, 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, | ||
4703 | 0x00, 0x33, 0x0B, 0x00, 0xC2, 0x88, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, | ||
4704 | 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, 0x06, 0xAB, 0x82, 0x01, | ||
4705 | 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3, | ||
4706 | 0x3C, 0x01, 0x00, 0x05, 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, | ||
4707 | 0x04, 0x23, 0xA0, 0x01, 0x15, 0x23, 0xA1, 0x01, 0xBE, 0x81, 0xFD, 0x23, | ||
4708 | 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, | ||
4709 | 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00, | ||
4710 | 0xC2, 0x88, 0x06, 0x23, 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, | ||
4711 | 0x00, 0xA2, 0xD4, 0x01, 0x57, 0x60, 0x00, 0xA0, 0xDA, 0x01, 0xE6, 0x84, | ||
4712 | 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, 0x4B, 0x00, 0x06, 0x61, | ||
4713 | 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC, | ||
4714 | 0x4F, 0x00, 0x84, 0x97, 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, | ||
4715 | 0x4F, 0x00, 0x62, 0x97, 0x48, 0x04, 0x84, 0x80, 0xF0, 0x97, 0x00, 0x46, | ||
4716 | 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, 0x81, 0x73, 0x06, 0x29, | ||
4717 | 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88, | ||
4718 | 0x04, 0x98, 0xF0, 0x80, 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, | ||
4719 | 0x7C, 0x95, 0x06, 0xA6, 0x34, 0x02, 0x03, 0xA6, 0x4C, 0x04, 0x46, 0x82, | ||
4720 | 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, 0x46, 0x82, 0xFE, 0x95, | ||
4721 | 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02, | ||
4722 | 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, | ||
4723 | 0xC2, 0x88, 0x7C, 0x95, 0x48, 0x82, 0x60, 0x96, 0x48, 0x82, 0x04, 0x23, | ||
4724 | 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, 0x04, 0x01, 0x0C, 0xDC, | ||
4725 | 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, | ||
4726 | 0x6F, 0x00, 0xA5, 0x01, 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, | ||
4727 | 0x24, 0x2B, 0x1C, 0x01, 0x02, 0xA6, 0xAA, 0x02, 0x07, 0xA6, 0x5A, 0x02, | ||
4728 | 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, 0x01, 0xA6, 0xB4, 0x02, | ||
4729 | 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E, | ||
4730 | 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, | ||
4731 | 0x0B, 0xDC, 0xE7, 0x23, 0x04, 0x61, 0x84, 0x01, 0x10, 0x31, 0x12, 0x35, | ||
4732 | 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0xEA, 0x82, | ||
4733 | 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8, | ||
4734 | 0x00, 0x33, 0x1F, 0x00, 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, | ||
4735 | 0x0E, 0x3D, 0x7E, 0x98, 0xB6, 0x2D, 0x01, 0xA6, 0x14, 0x03, 0x00, 0xA6, | ||
4736 | 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, 0x10, 0x03, 0x03, 0xA6, | ||
4737 | 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88, | ||
4738 | 0x7C, 0x95, 0xEE, 0x82, 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, | ||
4739 | 0x7E, 0x98, 0x64, 0xE4, 0x04, 0x01, 0x2D, 0xC8, 0x31, 0x05, 0x07, 0x01, | ||
4740 | 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, 0x05, 0x05, 0x86, 0x98, | ||
4741 | 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6, | ||
4742 | 0x3C, 0x04, 0x06, 0xA6, 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, | ||
4743 | 0x25, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x32, 0x83, 0x60, 0x96, 0x32, 0x83, | ||
4744 | 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, 0xEB, 0x04, 0x00, 0x33, | ||
4745 | 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05, | ||
4746 | 0xFF, 0xA2, 0x7A, 0x03, 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, | ||
4747 | 0x05, 0x05, 0x15, 0x01, 0x00, 0xA2, 0x9A, 0x03, 0xEC, 0x00, 0x6E, 0x00, | ||
4748 | 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, 0x01, 0xA6, 0x96, 0x03, | ||
4749 | 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6, | ||
4750 | 0xA4, 0x03, 0x00, 0xA6, 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, | ||
4751 | 0x01, 0xA6, 0xA4, 0x03, 0x07, 0xA6, 0xB2, 0x03, 0xD4, 0x83, 0x7C, 0x95, | ||
4752 | 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, 0xA8, 0x98, 0x80, 0x42, | ||
4753 | 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95, | ||
4754 | 0xC0, 0x83, 0x00, 0x33, 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, | ||
4755 | 0x80, 0x36, 0x04, 0x23, 0xA0, 0x01, 0x12, 0x23, 0xA1, 0x01, 0x10, 0x84, | ||
4756 | 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, | ||
4757 | 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04, | ||
4758 | 0x06, 0xA6, 0x0A, 0x04, 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, | ||
4759 | 0xF4, 0x83, 0x60, 0x96, 0xF4, 0x83, 0x20, 0x84, 0x07, 0xF0, 0x06, 0xA4, | ||
4760 | 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, 0x83, 0x03, 0x80, 0x63, | ||
4761 | 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6, | ||
4762 | 0x38, 0x04, 0x00, 0x33, 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, | ||
4763 | 0x60, 0x96, 0x20, 0x84, 0x1D, 0x01, 0x06, 0xCC, 0x00, 0x33, 0x00, 0x84, | ||
4764 | 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, 0xA2, 0x0D, 0x80, 0x63, | ||
4765 | 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03, | ||
4766 | 0x80, 0x63, 0xA3, 0x01, 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, | ||
4767 | 0x86, 0x04, 0x0A, 0xA0, 0x76, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1D, 0x00, | ||
4768 | 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, 0x00, 0x33, 0x1E, 0x00, | ||
4769 | 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04, | ||
4770 | 0x08, 0x23, 0x22, 0xA3, 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, | ||
4771 | 0x02, 0x23, 0x22, 0xA3, 0xC4, 0x04, 0x42, 0x23, 0xF8, 0x88, 0x4A, 0x00, | ||
4772 | 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, 0xF8, 0x88, 0x04, 0x98, | ||
4773 | 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, | ||
4774 | 0x81, 0x62, 0xE8, 0x81, 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, | ||
4775 | 0x04, 0x98, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x81, 0xC0, 0x20, 0x81, 0x62, | ||
4776 | 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, 0xF8, 0x88, 0x04, 0x23, | ||
4777 | 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, | ||
4778 | 0xF4, 0x04, 0x00, 0x33, 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, | ||
4779 | 0x02, 0x23, 0xA2, 0x01, 0x04, 0x23, 0xA0, 0x01, 0x04, 0x98, 0x26, 0x95, | ||
4780 | 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, 0x00, 0xA3, 0x22, 0x05, | ||
4781 | 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85, | ||
4782 | 0x46, 0x97, 0xCD, 0x04, 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, | ||
4783 | 0x03, 0xDA, 0x80, 0x23, 0x82, 0x01, 0x34, 0x85, 0x02, 0x23, 0xA0, 0x01, | ||
4784 | 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, 0x1D, 0x01, 0x04, 0xD6, | ||
4785 | 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, | ||
4786 | 0x49, 0x00, 0x81, 0x01, 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, | ||
4787 | 0xF7, 0x04, 0x03, 0x01, 0x49, 0x04, 0x80, 0x01, 0xC9, 0x00, 0x00, 0x05, | ||
4788 | 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, 0x01, 0x23, 0xEA, 0x00, | ||
4789 | 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, | ||
4790 | 0x07, 0xA4, 0xF8, 0x05, 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, | ||
4791 | 0x00, 0x33, 0x2D, 0x00, 0xC2, 0x88, 0x04, 0xA0, 0xB8, 0x05, 0x80, 0x63, | ||
4792 | 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0xA4, 0x05, | ||
4793 | 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00, | ||
4794 | 0x62, 0x97, 0x04, 0x85, 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, | ||
4795 | 0x08, 0xA0, 0xBE, 0x05, 0xF4, 0x85, 0x03, 0xA0, 0xC4, 0x05, 0xF4, 0x85, | ||
4796 | 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, 0xCC, 0x86, 0x07, 0xA0, | ||
4797 | 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05, | ||
4798 | 0x80, 0x67, 0x80, 0x63, 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, | ||
4799 | 0x68, 0x98, 0x48, 0x23, 0xF8, 0x88, 0x07, 0x23, 0x80, 0x00, 0x06, 0x87, | ||
4800 | 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, 0x4A, 0x00, | ||
4801 | 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23, | ||
4802 | 0x07, 0x41, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, | ||
4803 | 0x37, 0x00, 0xC2, 0x88, 0x1D, 0x01, 0x01, 0xD6, 0x20, 0x23, 0x63, 0x60, | ||
4804 | 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, 0x07, 0xA6, 0x7C, 0x05, | ||
4805 | 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00, | ||
4806 | 0x52, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, | ||
4807 | 0xC0, 0x23, 0x07, 0x41, 0x00, 0x63, 0x1D, 0x01, 0x04, 0xCC, 0x00, 0x33, | ||
4808 | 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, 0x07, 0x41, 0x00, 0x63, | ||
4809 | 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23, | ||
4810 | 0xDF, 0x00, 0x06, 0xA6, 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, | ||
4811 | 0x80, 0x63, 0x00, 0x33, 0x00, 0x40, 0xC0, 0x20, 0x81, 0x62, 0x00, 0x63, | ||
4812 | 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, 0x94, 0x06, | ||
4813 | 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B, | ||
4814 | 0x40, 0x0E, 0x80, 0x63, 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, | ||
4815 | 0x7C, 0x05, 0x40, 0x0E, 0x80, 0x63, 0x00, 0x43, 0x00, 0xA0, 0xA2, 0x06, | ||
4816 | 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x40, 0x0E, | ||
4817 | 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, | ||
4818 | 0x07, 0xA6, 0xD6, 0x06, 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, | ||
4819 | 0x80, 0x63, 0x89, 0x00, 0x0A, 0x2B, 0x07, 0xA6, 0xE8, 0x06, 0x00, 0x33, | ||
4820 | 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, 0xF4, 0x06, 0xC0, 0x0E, | ||
4821 | 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20, | ||
4822 | 0x81, 0x62, 0x04, 0x01, 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, | ||
4823 | 0x80, 0x63, 0x06, 0xA6, 0x8C, 0x06, 0x00, 0x33, 0x2C, 0x00, 0xC2, 0x88, | ||
4824 | 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, 0x06, 0xA6, | ||
4825 | 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88, | ||
4826 | 0x00, 0x00, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, | ||
4827 | 0x07, 0xA6, 0x7C, 0x05, 0xBF, 0x23, 0x04, 0x61, 0x84, 0x01, 0xE6, 0x84, | ||
4828 | 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, 0x00, 0x01, 0xF2, 0x00, | ||
4829 | 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, | ||
4830 | 0x80, 0x05, 0x81, 0x05, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, | ||
4831 | 0x01, 0x01, 0xF1, 0x00, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, 0x71, 0x00, | ||
4832 | 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, 0x70, 0x00, 0x80, 0x01, | ||
4833 | 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, | ||
4834 | 0xF1, 0x00, 0x70, 0x00, 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, | ||
4835 | 0x72, 0x00, 0x81, 0x01, 0x71, 0x04, 0x70, 0x00, 0x81, 0x01, 0x70, 0x04, | ||
4836 | 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, 0xA3, 0x01, 0xA2, 0x01, | ||
4837 | 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, | ||
4838 | 0xC4, 0x07, 0x00, 0x33, 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, | ||
4839 | 0x04, 0x01, 0x11, 0xC8, 0x48, 0x00, 0xB0, 0x01, 0xB1, 0x01, 0x08, 0x23, | ||
4840 | 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, 0x00, 0xA2, 0xE4, 0x07, | ||
4841 | 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, | ||
4842 | 0x05, 0x05, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, | ||
4843 | 0x00, 0x02, 0x80, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, 0x00, 0x63, | ||
4844 | 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x00, 0xA0, | ||
4845 | 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, | ||
4846 | 0x00, 0x63, 0xF3, 0x04, 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, | ||
4847 | 0xF4, 0x00, 0xCF, 0x40, 0x00, 0xA2, 0x44, 0x08, 0x74, 0x04, 0x02, 0x01, | ||
4848 | 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, 0x24, 0x08, 0x04, 0x98, | ||
4849 | 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, | ||
4850 | 0x5A, 0x88, 0x02, 0x01, 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, | ||
4851 | 0x4A, 0x88, 0x75, 0x00, 0x00, 0xA3, 0x64, 0x08, 0x00, 0x05, 0x4E, 0x88, | ||
4852 | 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, 0x76, 0x08, | ||
4853 | 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, | ||
4854 | 0x00, 0x63, 0x38, 0x2B, 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, | ||
4855 | 0x31, 0x05, 0x92, 0x98, 0x05, 0x05, 0xB2, 0x09, 0x00, 0x63, 0x00, 0x32, | ||
4856 | 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, 0x80, 0x32, 0x80, 0x36, | ||
4857 | 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, | ||
4858 | 0x40, 0x36, 0x40, 0x3A, 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, | ||
4859 | 0x00, 0xA0, 0xB4, 0x08, 0x5D, 0x00, 0xFE, 0xC3, 0x00, 0x63, 0x80, 0x73, | ||
4860 | 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, 0xFF, 0xFD, 0x80, 0x73, | ||
4861 | 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, | ||
4862 | 0xA1, 0x23, 0xA1, 0x01, 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, | ||
4863 | 0x68, 0x00, 0x00, 0xA2, 0x80, 0x00, 0x03, 0xC2, 0xF1, 0xC7, 0x41, 0x23, | ||
4864 | 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, 0xA0, 0x01, 0xE6, 0x84, | ||
4865 | }; | ||
4866 | |||
4867 | static unsigned short _asc_mcode_size = sizeof(_asc_mcode_buf); | ||
4868 | static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL; | ||
4869 | |||
4870 | /* Microcode buffer is kept after initialization for error recovery. */ | ||
4871 | static unsigned char _adv_asc3550_buf[] = { | ||
4872 | 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc, | ||
4873 | 0x01, 0x00, 0x48, 0xe4, 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, | ||
4874 | 0x00, 0xfa, 0xff, 0xff, 0x28, 0x0e, 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, | ||
4875 | 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, 0x01, 0xf6, | ||
4876 | 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00, | ||
4877 | 0x00, 0xec, 0x85, 0xf0, 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, | ||
4878 | 0x00, 0xe6, 0x1e, 0xf0, 0x86, 0xf0, 0xb4, 0x00, 0x98, 0x57, 0xd0, 0x01, | ||
4879 | 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, 0xaa, 0x18, 0x02, 0x80, | ||
4880 | 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40, | ||
4881 | 0x00, 0x57, 0x01, 0xea, 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, | ||
4882 | 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01, | ||
4883 | 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, 0x02, 0x4a, 0xb9, 0x54, | ||
4884 | 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00, | ||
4885 | 0x3e, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, | ||
4886 | 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x62, 0x0a, | ||
4887 | 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, 0x4c, 0x1c, 0xbb, 0x55, | ||
4888 | 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0, | ||
4889 | 0x03, 0xf7, 0x06, 0xf7, 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, | ||
4890 | 0x00, 0x01, 0xb0, 0x08, 0x30, 0x13, 0x64, 0x15, 0x32, 0x1c, 0x38, 0x1c, | ||
4891 | 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, 0x04, 0xea, 0x5d, 0xf0, | ||
4892 | 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, | ||
4893 | 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, | ||
4894 | 0x0a, 0x12, 0x04, 0x13, 0x40, 0x13, 0x30, 0x1c, 0x00, 0x4e, 0xbd, 0x56, | ||
4895 | 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xa7, 0xf0, | ||
4896 | 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, | ||
4897 | 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, | ||
4898 | 0xde, 0x03, 0x56, 0x0a, 0x14, 0x0e, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, | ||
4899 | 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, 0x10, 0x15, 0x14, 0x15, | ||
4900 | 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, | ||
4901 | 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, | ||
4902 | 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, 0x0c, 0xf0, | ||
4903 | 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, | ||
4904 | 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00, | ||
4905 | 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, | ||
4906 | 0x26, 0x01, 0x79, 0x01, 0x7a, 0x01, 0xc0, 0x01, 0xc2, 0x01, 0x7c, 0x02, | ||
4907 | 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, 0x69, 0x08, 0xba, 0x08, | ||
4908 | 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10, | ||
4909 | 0xf1, 0x10, 0x06, 0x12, 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, | ||
4910 | 0x42, 0x14, 0xd6, 0x14, 0x8a, 0x15, 0xc6, 0x17, 0xd2, 0x17, 0x6b, 0x18, | ||
4911 | 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0x48, 0x47, | ||
4912 | 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55, | ||
4913 | 0x14, 0x56, 0x77, 0x57, 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, | ||
4914 | 0x03, 0xa1, 0xfe, 0x9c, 0xf0, 0x29, 0x02, 0xfe, 0xb8, 0x0c, 0xff, 0x10, | ||
4915 | 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, 0xfe, 0x80, 0x01, 0xff, | ||
4916 | 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, | ||
4917 | 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, | ||
4918 | 0x00, 0x10, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08, | ||
4919 | 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x0f, | ||
4920 | 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, | ||
4921 | 0xfe, 0x04, 0xf7, 0xcf, 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, | ||
4922 | 0x04, 0xf7, 0xcf, 0x67, 0x0b, 0x3c, 0x2a, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, | ||
4923 | 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, | ||
4924 | 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b, | ||
4925 | 0x02, 0xfe, 0xd4, 0x0c, 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, | ||
4926 | 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x05, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12, | ||
4927 | 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, 0xf0, 0xfe, 0x86, 0x02, | ||
4928 | 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02, | ||
4929 | 0xfe, 0x46, 0xf0, 0xfe, 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, | ||
4930 | 0xfe, 0x43, 0xf0, 0xfe, 0x44, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x48, 0x02, | ||
4931 | 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, 0xa0, 0x17, 0x06, 0x18, | ||
4932 | 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe, | ||
4933 | 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, | ||
4934 | 0xfe, 0x06, 0xfc, 0xc7, 0x0a, 0x6b, 0x01, 0x9e, 0x02, 0x29, 0x14, 0x4d, | ||
4935 | 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xbd, | ||
4936 | 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, | ||
4937 | 0x58, 0x1c, 0x17, 0x06, 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, | ||
4938 | 0xfe, 0x02, 0x02, 0x21, 0xfe, 0x94, 0x02, 0xfe, 0x5a, 0x1c, 0xea, 0xfe, | ||
4939 | 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, 0x01, 0xfe, 0x54, 0x0f, | ||
4940 | 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe, | ||
4941 | 0x69, 0x10, 0x17, 0x06, 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, | ||
4942 | 0x12, 0x20, 0xfe, 0x05, 0xf6, 0xc7, 0x01, 0xfe, 0x52, 0x16, 0x09, 0x4a, | ||
4943 | 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, 0x02, 0x29, 0x0a, 0x40, | ||
4944 | 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41, | ||
4945 | 0x58, 0x0a, 0x99, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, | ||
4946 | 0x01, 0xe6, 0x02, 0x29, 0x2a, 0x46, 0xfe, 0x02, 0xe8, 0x27, 0xf8, 0xfe, | ||
4947 | 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, 0x01, 0xfe, 0x07, 0x4b, | ||
4948 | 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0, | ||
4949 | 0xfe, 0x56, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, | ||
4950 | 0x9c, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x64, 0x03, 0xeb, 0x0f, | ||
4951 | 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, 0x1c, 0xeb, 0x09, 0x04, | ||
4952 | 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40, | ||
4953 | 0x01, 0x0e, 0xac, 0x75, 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, | ||
4954 | 0xfe, 0x01, 0xf0, 0xd2, 0xfe, 0x82, 0xf0, 0xfe, 0x92, 0x03, 0xec, 0x11, | ||
4955 | 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, 0x32, 0x1f, 0xfe, 0xb4, | ||
4956 | 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe, | ||
4957 | 0x0a, 0xf0, 0xfe, 0x7a, 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, | ||
4958 | 0xf6, 0x04, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, 0xd1, | ||
4959 | 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, 0xf7, 0xfe, 0x48, 0x1c, | ||
4960 | 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3, | ||
4961 | 0x0a, 0xca, 0x01, 0x0e, 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, | ||
4962 | 0xfe, 0x10, 0x12, 0x14, 0x2c, 0x01, 0x33, 0x8f, 0xfe, 0x66, 0x02, 0x02, | ||
4963 | 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, 0xfe, 0x3c, 0x04, 0x1f, | ||
4964 | 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, | ||
4965 | 0x12, 0x2b, 0xff, 0x02, 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, | ||
4966 | 0x2b, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd5, 0xfe, 0x4c, 0x44, 0xfe, | ||
4967 | 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64, | ||
4968 | 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d, | ||
4969 | 0xfe, 0x2a, 0x13, 0x2f, 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, | ||
4970 | 0xfe, 0x4c, 0x54, 0x64, 0xd3, 0xfa, 0xef, 0x86, 0x09, 0x04, 0x1d, 0xfe, | ||
4971 | 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, 0x1d, 0xfe, 0x1c, 0x12, | ||
4972 | 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, | ||
4973 | 0x70, 0x0c, 0x02, 0x22, 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, | ||
4974 | 0xf9, 0x03, 0x14, 0x92, 0x01, 0x33, 0x02, 0x29, 0xfe, 0x42, 0x5b, 0x67, | ||
4975 | 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, | ||
4976 | 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a, | ||
4977 | 0xfe, 0x70, 0x12, 0x49, 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, | ||
4978 | 0x00, 0x28, 0x16, 0xfe, 0x80, 0x05, 0xfe, 0x31, 0xe4, 0x6a, 0x49, 0x04, | ||
4979 | 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x42, 0x12, | ||
4980 | 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05, | ||
4981 | 0x11, 0xfe, 0xe3, 0x00, 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, | ||
4982 | 0xfe, 0x49, 0xf0, 0xfe, 0x64, 0x05, 0x83, 0x24, 0xfe, 0x21, 0x00, 0xa1, | ||
4983 | 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, 0x09, 0x48, 0x01, 0x08, | ||
4984 | 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01, | ||
4985 | 0x86, 0x24, 0x06, 0x12, 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, | ||
4986 | 0xfe, 0x22, 0x12, 0x47, 0x01, 0xa7, 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, | ||
4987 | 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, 0x02, 0x22, 0x05, 0xfe, | ||
4988 | 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13, | ||
4989 | 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, | ||
4990 | 0xfe, 0x02, 0x12, 0x5f, 0x01, 0xfe, 0xaa, 0x14, 0x1f, 0xfe, 0xfe, 0x05, | ||
4991 | 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x50, 0xb4, 0x0c, | ||
4992 | 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a, | ||
4993 | 0x13, 0x01, 0xfe, 0x14, 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, | ||
4994 | 0xb7, 0x19, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, | ||
4995 | 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, 0x72, 0x06, 0x49, 0x04, | ||
4996 | 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68, | ||
4997 | 0x06, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, | ||
4998 | 0x0c, 0x3f, 0x17, 0x06, 0x01, 0xa7, 0xec, 0x72, 0x70, 0x01, 0x6e, 0x87, | ||
4999 | 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, 0xfe, | ||
5000 | 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07, | ||
5001 | 0x8d, 0x81, 0x02, 0x22, 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, | ||
5002 | 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, | ||
5003 | 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, 0x00, 0x02, 0xfe, 0x32, | ||
5004 | 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15, | ||
5005 | 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, | ||
5006 | 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x06, 0x01, 0x08, 0x15, 0x00, 0x02, | ||
5007 | 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, 0x9a, 0x81, 0x4b, 0x1d, | ||
5008 | 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca, | ||
5009 | 0x45, 0xfe, 0x32, 0x12, 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, | ||
5010 | 0x32, 0xfe, 0x0a, 0xf0, 0xfe, 0x32, 0x07, 0x8d, 0x81, 0x8c, 0xfe, 0x5c, | ||
5011 | 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, 0x06, 0x15, 0x19, 0x02, | ||
5012 | 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae, | ||
5013 | 0x90, 0x77, 0xfe, 0xca, 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, | ||
5014 | 0x35, 0x1e, 0x20, 0x07, 0x10, 0xfe, 0x0e, 0x12, 0x74, 0xfe, 0x80, 0x80, | ||
5015 | 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, 0x83, 0xe7, 0xc4, 0xa1, | ||
5016 | 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f, | ||
5017 | 0x40, 0x12, 0x58, 0x01, 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, | ||
5018 | 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x83, 0xfb, 0xfe, 0x8a, 0x90, 0x0c, 0x52, | ||
5019 | 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, | ||
5020 | 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a, | ||
5021 | 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, | ||
5022 | 0x55, 0x09, 0x04, 0x4f, 0x85, 0x01, 0xa8, 0xfe, 0x1f, 0x80, 0x12, 0x58, | ||
5023 | 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, 0x18, 0x57, 0xfb, 0xfe, | ||
5024 | 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, | ||
5025 | 0x0c, 0x39, 0x18, 0x3a, 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, | ||
5026 | 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x48, 0x08, 0xfe, 0x9e, 0xf0, | ||
5027 | 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0xfe, 0x80, | ||
5028 | 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0, | ||
5029 | 0xfe, 0x7a, 0x08, 0x8d, 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, | ||
5030 | 0x15, 0x19, 0xfe, 0xc9, 0x10, 0x61, 0x04, 0x06, 0xfe, 0x10, 0x12, 0x61, | ||
5031 | 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, 0x12, 0xfe, 0x2e, 0x1c, | ||
5032 | 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe, | ||
5033 | 0x52, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, | ||
5034 | 0xac, 0xf0, 0xfe, 0xbe, 0x08, 0xfe, 0x8a, 0x10, 0xaa, 0xfe, 0xf3, 0x10, | ||
5035 | 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, 0x24, 0x0a, 0xab, 0xfe, | ||
5036 | 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe, | ||
5037 | 0x1c, 0x12, 0xb5, 0xfe, 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, | ||
5038 | 0x16, 0x9d, 0x05, 0xcb, 0x1c, 0x06, 0x16, 0x9d, 0xb8, 0x6d, 0xb9, 0x6d, | ||
5039 | 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, 0x14, 0x92, 0x01, 0x33, | ||
5040 | 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a, | ||
5041 | 0xfe, 0x74, 0x18, 0x1c, 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, | ||
5042 | 0xfe, 0x44, 0x0d, 0x3b, 0x01, 0xe6, 0x1e, 0x27, 0x74, 0x67, 0x1a, 0x02, | ||
5043 | 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, 0x09, 0x04, 0x6a, 0xfe, | ||
5044 | 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc, | ||
5045 | 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, | ||
5046 | 0xfe, 0x86, 0x91, 0x63, 0x27, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x77, | ||
5047 | 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, 0x7c, 0xbe, 0x54, 0xbf, | ||
5048 | 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e, | ||
5049 | 0x79, 0x56, 0x68, 0x57, 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, | ||
5050 | 0xfa, 0x4e, 0x01, 0xa5, 0xa2, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, 0x79, 0x56, | ||
5051 | 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x79, 0x39, | ||
5052 | 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53, | ||
5053 | 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, | ||
5054 | 0x02, 0x6d, 0x09, 0x04, 0x19, 0x16, 0xd7, 0x09, 0x04, 0xfe, 0xf7, 0x00, | ||
5055 | 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, 0xfe, 0x10, 0x90, 0xfe, | ||
5056 | 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08, | ||
5057 | 0x11, 0x9b, 0x09, 0x04, 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, | ||
5058 | 0x77, 0xfe, 0xc6, 0x08, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x6d, | ||
5059 | 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, 0x0b, 0xfe, 0x1a, 0x12, | ||
5060 | 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9, | ||
5061 | 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, | ||
5062 | 0x6c, 0x19, 0xbe, 0x39, 0xfe, 0xed, 0x19, 0xbf, 0x3a, 0xfe, 0x0c, 0x51, | ||
5063 | 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, 0x34, 0xfe, 0x74, 0x10, | ||
5064 | 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a, | ||
5065 | 0x84, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, | ||
5066 | 0x02, 0x5a, 0xfe, 0xd1, 0xf0, 0xfe, 0xc4, 0x0a, 0x14, 0x7a, 0x01, 0x33, | ||
5067 | 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xca, | ||
5068 | 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe, | ||
5069 | 0x22, 0x00, 0x02, 0x5a, 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, | ||
5070 | 0x24, 0x00, 0x02, 0x5a, 0xfe, 0xd0, 0xf0, 0xfe, 0xec, 0x0a, 0x0f, 0x93, | ||
5071 | 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, 0x4c, 0xfe, 0x10, 0x10, | ||
5072 | 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00, | ||
5073 | 0x2a, 0x13, 0xfe, 0x4e, 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, | ||
5074 | 0xfe, 0x20, 0x0b, 0xb1, 0x16, 0x32, 0x2a, 0x73, 0xdd, 0xb8, 0x22, 0xb9, | ||
5075 | 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, 0x32, 0x8c, 0xfe, 0x48, | ||
5076 | 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe, | ||
5077 | 0xdb, 0x10, 0x11, 0xfe, 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, | ||
5078 | 0x7f, 0xfe, 0x89, 0xf0, 0x22, 0x30, 0x2e, 0xd8, 0xbc, 0x7d, 0xbd, 0x7f, | ||
5079 | 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, 0x45, 0x0f, 0xfe, 0x42, | ||
5080 | 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c, | ||
5081 | 0x09, 0x04, 0x0b, 0xfe, 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, | ||
5082 | 0x12, 0x4b, 0xfe, 0x28, 0x00, 0x21, 0xfe, 0xa6, 0x0c, 0x0a, 0x40, 0x01, | ||
5083 | 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, | ||
5084 | 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d, | ||
5085 | 0x01, 0x6f, 0x02, 0x29, 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, | ||
5086 | 0x0b, 0xfe, 0xb4, 0x10, 0x01, 0x86, 0x3e, 0x0b, 0xfe, 0xaa, 0x10, 0x01, | ||
5087 | 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, 0x3e, 0x0b, 0x0f, 0xfe, | ||
5088 | 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01, | ||
5089 | 0xe8, 0x59, 0x11, 0x2d, 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, | ||
5090 | 0xfe, 0x2a, 0x03, 0x09, 0x04, 0x0b, 0x84, 0x3e, 0x0b, 0x0f, 0x00, 0xfe, | ||
5091 | 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, 0x09, 0x04, 0x1b, 0xfe, | ||
5092 | 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe, | ||
5093 | 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, | ||
5094 | 0xfe, 0xa9, 0x10, 0x0f, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0b, 0x5f, | ||
5095 | 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x0f, 0xfe, 0x47, 0x00, | ||
5096 | 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa, | ||
5097 | 0xab, 0x70, 0x05, 0x6b, 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, | ||
5098 | 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x59, 0x01, 0xda, 0x02, 0x29, 0xea, | ||
5099 | 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, 0x00, 0x37, 0x97, 0x01, | ||
5100 | 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e, | ||
5101 | 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, | ||
5102 | 0x4b, 0x89, 0xfe, 0x75, 0x57, 0x05, 0x51, 0xfe, 0x98, 0x56, 0xfe, 0x38, | ||
5103 | 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, 0x46, 0x09, 0x04, 0x1d, | ||
5104 | 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a, | ||
5105 | 0x99, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, | ||
5106 | 0x2a, 0x03, 0x0a, 0x51, 0xfe, 0xee, 0x14, 0xee, 0x3e, 0x1d, 0xfe, 0xce, | ||
5107 | 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x29, 0x1e, | ||
5108 | 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12, | ||
5109 | 0xce, 0x1e, 0x2d, 0x47, 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, | ||
5110 | 0xec, 0x0d, 0x13, 0x06, 0x12, 0x4d, 0x01, 0xfe, 0xe2, 0x15, 0x05, 0xfe, | ||
5111 | 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, 0xf0, 0x0d, 0xfe, 0x02, | ||
5112 | 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05, | ||
5113 | 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, | ||
5114 | 0x0d, 0xfe, 0x18, 0x13, 0xaf, 0xfe, 0x02, 0xea, 0xce, 0x62, 0x7a, 0xfe, | ||
5115 | 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, 0x05, 0xfe, 0x38, 0x01, | ||
5116 | 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01, | ||
5117 | 0x0c, 0xfe, 0x62, 0x01, 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, | ||
5118 | 0x2d, 0x8a, 0x13, 0x06, 0x03, 0x23, 0x03, 0x1e, 0x4d, 0xfe, 0xf7, 0x12, | ||
5119 | 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, 0x71, 0x13, 0xfe, 0x24, | ||
5120 | 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03, | ||
5121 | 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, | ||
5122 | 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x23, | ||
5123 | 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, 0x75, 0x03, 0x09, 0x04, | ||
5124 | 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13, | ||
5125 | 0xfe, 0x1e, 0x80, 0xe1, 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, | ||
5126 | 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xa3, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, | ||
5127 | 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, 0x16, 0x2f, 0x07, 0x2d, | ||
5128 | 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01, | ||
5129 | 0xe8, 0x11, 0xfe, 0xe9, 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, | ||
5130 | 0xfe, 0x14, 0x16, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90, | ||
5131 | 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, 0x09, 0x04, 0x4f, 0xfe, | ||
5132 | 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80, | ||
5133 | 0x40, 0x12, 0x20, 0x63, 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, | ||
5134 | 0x20, 0x03, 0xfe, 0x08, 0x1c, 0x05, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, | ||
5135 | 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, 0xfe, 0xb0, 0x00, 0xfe, | ||
5136 | 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, | ||
5137 | 0x24, 0x69, 0x12, 0xc9, 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, | ||
5138 | 0x5f, 0x17, 0x1d, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x21, 0xfe, 0x08, | ||
5139 | 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, 0xfe, 0x90, 0x4d, 0xfe, | ||
5140 | 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c, | ||
5141 | 0x46, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, | ||
5142 | 0xfe, 0x32, 0x0f, 0xea, 0x70, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, | ||
5143 | 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, 0xfe, 0x07, 0xe6, 0x1d, | ||
5144 | 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46, | ||
5145 | 0xfa, 0xef, 0xfe, 0x42, 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, | ||
5146 | 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x36, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01, | ||
5147 | 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, | ||
5148 | 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e, | ||
5149 | 0x10, 0x07, 0x7e, 0x45, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, | ||
5150 | 0xfe, 0x44, 0x58, 0x74, 0xfe, 0x01, 0xec, 0x97, 0xfe, 0x9e, 0x40, 0xfe, | ||
5151 | 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, 0x27, 0x01, 0xda, 0xfe, | ||
5152 | 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b, | ||
5153 | 0xfe, 0x48, 0x12, 0x07, 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, | ||
5154 | 0x12, 0x07, 0xc2, 0x16, 0xfe, 0x3e, 0x11, 0x07, 0xfe, 0x23, 0x00, 0x16, | ||
5155 | 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, 0x11, 0x07, 0x19, 0xfe, | ||
5156 | 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b, | ||
5157 | 0x01, 0x08, 0x8c, 0x43, 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, | ||
5158 | 0xfe, 0x32, 0x0e, 0x11, 0x7e, 0x02, 0x29, 0x2b, 0x2f, 0x07, 0x9b, 0xfe, | ||
5159 | 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, 0xfc, 0x10, 0x09, 0x04, | ||
5160 | 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe, | ||
5161 | 0xc6, 0x10, 0x1e, 0x58, 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, | ||
5162 | 0xfe, 0x82, 0x0c, 0x0c, 0x54, 0x18, 0x55, 0x23, 0x0c, 0x7b, 0x0c, 0x7c, | ||
5163 | 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, 0xa5, 0xc0, 0x38, 0xc1, | ||
5164 | 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe, | ||
5165 | 0x05, 0xfa, 0x4e, 0xfe, 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, | ||
5166 | 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x56, 0x18, 0x57, 0x83, 0xc0, 0x38, 0xc1, | ||
5167 | 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x00, 0x56, 0xfe, 0xa1, | ||
5168 | 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e, | ||
5169 | 0x58, 0xfe, 0x1f, 0x40, 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, | ||
5170 | 0xae, 0x50, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x44, 0x50, 0xfe, 0xc6, 0x50, | ||
5171 | 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x05, 0x39, | ||
5172 | 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06, | ||
5173 | 0x12, 0xcd, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, | ||
5174 | 0x07, 0x06, 0x21, 0x44, 0x2f, 0x07, 0x9b, 0x21, 0x5b, 0x01, 0x6e, 0x1c, | ||
5175 | 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, 0x39, 0x68, 0x3a, 0xfe, | ||
5176 | 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c, | ||
5177 | 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, | ||
5178 | 0x41, 0x02, 0x5b, 0x2b, 0x01, 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, | ||
5179 | 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, 0x3b, 0x02, 0x44, 0x01, | ||
5180 | 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44, | ||
5181 | 0x01, 0x08, 0x1f, 0xa2, 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, | ||
5182 | 0x60, 0x05, 0xfe, 0x9c, 0x00, 0x28, 0x84, 0x49, 0x04, 0x19, 0x34, 0x9f, | ||
5183 | 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, 0x78, 0x3d, 0xfe, 0xda, | ||
5184 | 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1, | ||
5185 | 0x05, 0xc6, 0x28, 0x84, 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, | ||
5186 | 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, 0x05, 0x50, 0xb4, 0x0c, | ||
5187 | 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, 0xaa, 0x14, 0x02, | ||
5188 | 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06, | ||
5189 | 0x21, 0x44, 0x01, 0xfe, 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, | ||
5190 | 0xfe, 0xa4, 0x14, 0x87, 0xfe, 0x4a, 0xf4, 0x0b, 0x16, 0x44, 0xfe, 0x4a, | ||
5191 | 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, 0x85, 0x02, 0x5b, 0x05, | ||
5192 | 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, | ||
5193 | 0xd8, 0x14, 0x02, 0x5c, 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, | ||
5194 | 0xe0, 0x12, 0x72, 0xf1, 0x01, 0x08, 0x23, 0x72, 0x03, 0x8f, 0xfe, 0xdc, | ||
5195 | 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, 0x12, 0x5e, 0x2b, 0x01, | ||
5196 | 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, | ||
5197 | 0x1c, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, | ||
5198 | 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0x1c, 0x3d, 0xfe, 0x30, 0x56, | ||
5199 | 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, | ||
5200 | 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58, | ||
5201 | 0x03, 0x0a, 0x50, 0x01, 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, | ||
5202 | 0x10, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x19, 0x48, 0xfe, 0x00, | ||
5203 | 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x63, 0x27, | ||
5204 | 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08, | ||
5205 | 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, | ||
5206 | 0xfe, 0x14, 0x18, 0xfe, 0x42, 0x48, 0x5f, 0x60, 0x89, 0x01, 0x08, 0x1f, | ||
5207 | 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, | ||
5208 | 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe, | ||
5209 | 0xcc, 0x12, 0x49, 0x04, 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, | ||
5210 | 0x4b, 0xc3, 0x64, 0xfe, 0xe8, 0x13, 0x3b, 0x13, 0x06, 0x17, 0xc3, 0x78, | ||
5211 | 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xa1, 0xff, 0x02, 0x83, | ||
5212 | 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c, | ||
5213 | 0x13, 0x06, 0xfe, 0x56, 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, | ||
5214 | 0x8e, 0xe4, 0x0a, 0xfe, 0x64, 0x00, 0x17, 0x93, 0x13, 0x06, 0xfe, 0x28, | ||
5215 | 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, 0xc8, 0x00, 0x8e, 0xe4, | ||
5216 | 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90, | ||
5217 | 0x01, 0xba, 0xfe, 0x4e, 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, | ||
5218 | 0x94, 0xfe, 0x56, 0xf0, 0xfe, 0x60, 0x14, 0xfe, 0x04, 0xf4, 0x6c, 0xfe, | ||
5219 | 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, 0xfe, 0x22, 0x13, 0x1c, | ||
5220 | 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba, | ||
5221 | 0xfe, 0x9c, 0x14, 0xb7, 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, | ||
5222 | 0x4d, 0xe4, 0x19, 0xba, 0xfe, 0x9c, 0x14, 0xb7, 0x19, 0x83, 0x60, 0x23, | ||
5223 | 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, 0xfe, 0xb4, 0x56, 0xfe, | ||
5224 | 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26, | ||
5225 | 0xe5, 0x15, 0x0b, 0x01, 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, | ||
5226 | 0xe5, 0x72, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x03, 0x15, 0x06, 0x01, 0x08, | ||
5227 | 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x06, 0x01, 0x08, | ||
5228 | 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89, | ||
5229 | 0x4a, 0x01, 0x08, 0x03, 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, | ||
5230 | 0x13, 0xad, 0x12, 0xcc, 0xfe, 0x49, 0xf4, 0x00, 0x3b, 0x72, 0x9f, 0x5e, | ||
5231 | 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, 0x08, 0x2f, 0x07, 0xfe, | ||
5232 | 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd, | ||
5233 | 0x01, 0x43, 0x1e, 0xcd, 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, | ||
5234 | 0x0a, 0x42, 0x01, 0x0e, 0xed, 0x88, 0x07, 0x10, 0xa4, 0x0a, 0x80, 0x01, | ||
5235 | 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x80, 0x01, 0x0e, 0x88, | ||
5236 | 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3, | ||
5237 | 0x88, 0x03, 0x0a, 0x42, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, | ||
5238 | 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x80, 0x80, 0xf2, 0xfe, 0x49, 0xe4, 0x10, | ||
5239 | 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, 0x01, 0x82, 0x03, 0x17, | ||
5240 | 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, | ||
5241 | 0xfe, 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, | ||
5242 | 0xfe, 0xfc, 0x16, 0xe0, 0x91, 0x1d, 0x66, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, | ||
5243 | 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, 0xda, 0x10, 0x17, 0x10, | ||
5244 | 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58, | ||
5245 | 0x05, 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, | ||
5246 | 0xfe, 0x30, 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x66, 0xfe, 0x38, 0x00, 0xfe, | ||
5247 | 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, 0x40, 0x16, 0xfe, 0xb6, | ||
5248 | 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17, | ||
5249 | 0x10, 0x71, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, | ||
5250 | 0x1d, 0xf7, 0x38, 0x90, 0xfe, 0x62, 0x16, 0xfe, 0x94, 0x14, 0xfe, 0x10, | ||
5251 | 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, | ||
5252 | 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71, | ||
5253 | 0xfe, 0x30, 0xbc, 0xfe, 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, | ||
5254 | 0x79, 0xfe, 0x1c, 0xf7, 0xc5, 0x90, 0xfe, 0x9a, 0x16, 0xfe, 0x5c, 0x14, | ||
5255 | 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, 0x42, 0x10, 0xfe, 0x02, | ||
5256 | 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc, | ||
5257 | 0xfe, 0x1d, 0xf7, 0x4f, 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, | ||
5258 | 0x1c, 0x13, 0x91, 0x4f, 0x47, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, | ||
5259 | 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, 0xfe, 0xdd, 0x00, 0x63, | ||
5260 | 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14, | ||
5261 | 0x06, 0x37, 0x95, 0xa9, 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, | ||
5262 | 0x23, 0x03, 0xfe, 0x7e, 0x18, 0x1c, 0x1a, 0x5d, 0x13, 0x0d, 0x03, 0x71, | ||
5263 | 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x78, 0x2c, | ||
5264 | 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42, | ||
5265 | 0x13, 0x3c, 0x8a, 0x0a, 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, | ||
5266 | 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, | ||
5267 | 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x01, 0x6f, | ||
5268 | 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, | ||
5269 | 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, | ||
5270 | 0xe7, 0x0b, 0x0f, 0xfe, 0x15, 0x00, 0x59, 0x76, 0x27, 0x01, 0xda, 0x17, | ||
5271 | 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, 0x11, 0x2d, 0x01, 0x6f, | ||
5272 | 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68, | ||
5273 | 0xc8, 0xfe, 0x48, 0x55, 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, | ||
5274 | 0x12, 0x98, 0x03, 0x0a, 0x99, 0x01, 0x0e, 0xf0, 0x0a, 0x40, 0x01, 0x0e, | ||
5275 | 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, 0x75, 0x03, 0x0a, 0x42, | ||
5276 | 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01, | ||
5277 | 0x0e, 0x73, 0x75, 0x03, 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, | ||
5278 | 0x05, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0x5b, 0xfe, 0x4e, 0xe4, 0xc2, | ||
5279 | 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1b, | ||
5280 | 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05, | ||
5281 | 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, | ||
5282 | 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x2c, 0xfe, 0x4e, 0x45, 0xfe, 0x0c, 0x12, | ||
5283 | 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, 0x03, 0x07, 0x7a, 0xfe, | ||
5284 | 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10, | ||
5285 | 0x07, 0x1b, 0xfe, 0x5a, 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, | ||
5286 | 0x10, 0x07, 0x1a, 0x5d, 0x24, 0x2c, 0xdc, 0x07, 0x0b, 0x5d, 0x24, 0x93, | ||
5287 | 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, 0x9f, 0xad, 0x03, 0x14, | ||
5288 | 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9, | ||
5289 | 0x03, 0x25, 0xfe, 0xca, 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, | ||
5290 | 0x18, 0x03, 0xff, 0x1a, 0x00, 0x00, | ||
5291 | }; | ||
5292 | |||
5293 | static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */ | ||
5294 | static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */ | ||
5295 | |||
5296 | /* Microcode buffer is kept after initialization for error recovery. */ | ||
5297 | static unsigned char _adv_asc38C0800_buf[] = { | ||
5298 | 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4, | ||
5299 | 0x01, 0x00, 0x48, 0xe4, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, | ||
5300 | 0x00, 0xfa, 0xff, 0xff, 0x1c, 0x0f, 0x00, 0xf6, 0x9e, 0xe7, 0xff, 0x00, | ||
5301 | 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, 0x09, 0xe7, 0x55, 0xf0, | ||
5302 | 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0, | ||
5303 | 0x18, 0xf4, 0x08, 0x00, 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, | ||
5304 | 0x82, 0x0d, 0x00, 0xe6, 0x86, 0xf0, 0xb1, 0xf0, 0x98, 0x57, 0x01, 0xfc, | ||
5305 | 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x3c, 0x00, 0xbb, 0x00, | ||
5306 | 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13, | ||
5307 | 0xba, 0x13, 0x18, 0x40, 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, | ||
5308 | 0x3e, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x74, 0x01, 0x76, 0x01, 0xb9, 0x54, | ||
5309 | 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, 0xc0, 0x00, 0x01, 0x01, | ||
5310 | 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12, | ||
5311 | 0x08, 0x12, 0x02, 0x4a, 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, | ||
5312 | 0x30, 0xe4, 0x4b, 0xe4, 0x5d, 0xf0, 0x02, 0xfa, 0x20, 0x00, 0x32, 0x00, | ||
5313 | 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, | ||
5314 | 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d, | ||
5315 | 0x06, 0x13, 0x4c, 0x1c, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, | ||
5316 | 0x03, 0xf7, 0x0c, 0x00, 0x0f, 0x00, 0x47, 0x00, 0xbe, 0x00, 0x00, 0x01, | ||
5317 | 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, | ||
5318 | 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa, | ||
5319 | 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, | ||
5320 | 0x4e, 0x01, 0x4a, 0x0b, 0x42, 0x0c, 0x12, 0x0f, 0x0c, 0x10, 0x22, 0x11, | ||
5321 | 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, 0x00, 0x4e, 0x42, 0x54, | ||
5322 | 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, | ||
5323 | 0x59, 0xf0, 0xb8, 0xf0, 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, | ||
5324 | 0x05, 0xfc, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, 0xa4, 0x00, | ||
5325 | 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xe2, 0x03, | ||
5326 | 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13, | ||
5327 | 0x12, 0x13, 0x24, 0x14, 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, | ||
5328 | 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, | ||
5329 | 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x3a, 0x55, 0x83, 0x55, | ||
5330 | 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, | ||
5331 | 0x0c, 0xf0, 0x04, 0xf8, 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, | ||
5332 | 0x1e, 0x00, 0x9e, 0x00, 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, | ||
5333 | 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, 0xc4, 0x01, 0xc6, 0x01, | ||
5334 | 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08, | ||
5335 | 0x68, 0x08, 0x69, 0x08, 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, | ||
5336 | 0x12, 0x10, 0x1a, 0x10, 0xed, 0x10, 0xf1, 0x10, 0x2a, 0x11, 0x06, 0x12, | ||
5337 | 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x46, 0x14, | ||
5338 | 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18, | ||
5339 | 0xca, 0x18, 0xe6, 0x19, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, | ||
5340 | 0x0e, 0x47, 0xfe, 0x9c, 0xf0, 0x2b, 0x02, 0xfe, 0xac, 0x0d, 0xff, 0x10, | ||
5341 | 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, 0xfe, 0x84, 0x01, 0xff, | ||
5342 | 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, | ||
5343 | 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, | ||
5344 | 0x00, 0x11, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08, | ||
5345 | 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x11, | ||
5346 | 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, | ||
5347 | 0xfe, 0x04, 0xf7, 0xd6, 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, | ||
5348 | 0x04, 0xf7, 0xd6, 0x99, 0x0a, 0x42, 0x2c, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, | ||
5349 | 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, | ||
5350 | 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d, | ||
5351 | 0x02, 0xfe, 0xc8, 0x0d, 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, | ||
5352 | 0xfc, 0x10, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd3, 0x12, | ||
5353 | 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, 0xf0, 0xfe, 0x8a, 0x02, | ||
5354 | 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02, | ||
5355 | 0xfe, 0x46, 0xf0, 0xfe, 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, | ||
5356 | 0xfe, 0x43, 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x4c, 0x02, | ||
5357 | 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, 0xaa, 0x18, 0x06, 0x14, | ||
5358 | 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe, | ||
5359 | 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, | ||
5360 | 0xfe, 0x06, 0xfc, 0xce, 0x09, 0x70, 0x01, 0xa8, 0x02, 0x2b, 0x15, 0x59, | ||
5361 | 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xbd, | ||
5362 | 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, | ||
5363 | 0x58, 0x1c, 0x18, 0x06, 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, | ||
5364 | 0xfe, 0x06, 0x02, 0x23, 0xfe, 0x98, 0x02, 0xfe, 0x5a, 0x1c, 0xf8, 0xfe, | ||
5365 | 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, | ||
5366 | 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe, | ||
5367 | 0x69, 0x10, 0x18, 0x06, 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, | ||
5368 | 0x13, 0x20, 0xfe, 0x05, 0xf6, 0xce, 0x01, 0xfe, 0x4a, 0x17, 0x08, 0x54, | ||
5369 | 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, | ||
5370 | 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10, | ||
5371 | 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, | ||
5372 | 0x10, 0x03, 0x01, 0xfe, 0x82, 0x16, 0x02, 0x2b, 0x2c, 0x4f, 0xfe, 0x02, | ||
5373 | 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, | ||
5374 | 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7, | ||
5375 | 0xfe, 0x40, 0x1c, 0x1c, 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, | ||
5376 | 0xa0, 0xf0, 0xfe, 0x48, 0x03, 0xfe, 0x11, 0xf0, 0xa7, 0xfe, 0xef, 0x10, | ||
5377 | 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, 0xfe, 0x11, 0x00, 0x02, | ||
5378 | 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13, | ||
5379 | 0x21, 0x22, 0xa3, 0xb7, 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, | ||
5380 | 0x01, 0xfe, 0xb4, 0x16, 0x12, 0xd1, 0x1c, 0xd9, 0xfe, 0x01, 0xf0, 0xd9, | ||
5381 | 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, 0xfe, 0xe4, 0x00, 0x27, | ||
5382 | 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe, | ||
5383 | 0x06, 0xf0, 0xfe, 0xc8, 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, | ||
5384 | 0x06, 0x02, 0x24, 0x03, 0x70, 0x28, 0x17, 0xfe, 0xfa, 0x04, 0x15, 0x6d, | ||
5385 | 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, 0xf9, 0x2c, 0x99, 0x19, | ||
5386 | 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, | ||
5387 | 0x74, 0x01, 0xaf, 0x8c, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, | ||
5388 | 0x09, 0xd1, 0x01, 0x0e, 0x8d, 0x51, 0x64, 0x79, 0x2a, 0x03, 0x70, 0x28, | ||
5389 | 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, | ||
5390 | 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d, | ||
5391 | 0xfe, 0x3c, 0x04, 0x3b, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, | ||
5392 | 0x12, 0x2d, 0xff, 0x02, 0x00, 0x10, 0x01, 0x0b, 0x1d, 0xfe, 0xe4, 0x04, | ||
5393 | 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, 0xfe, 0x4c, 0x44, 0xfe, | ||
5394 | 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, | ||
5395 | 0xda, 0x4f, 0x79, 0x2a, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, | ||
5396 | 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x2a, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x52, | ||
5397 | 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, 0xda, 0xfe, | ||
5398 | 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe, | ||
5399 | 0x08, 0x13, 0x32, 0x07, 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, | ||
5400 | 0x1c, 0x12, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, | ||
5401 | 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x2d, 0x12, 0xfe, 0xe6, | ||
5402 | 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36, | ||
5403 | 0x02, 0x2b, 0xfe, 0x42, 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, | ||
5404 | 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x87, 0x80, 0xfe, 0x31, 0xe4, 0x5b, 0x08, | ||
5405 | 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x19, 0xfe, 0x7c, | ||
5406 | 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28, | ||
5407 | 0x17, 0xfe, 0x90, 0x05, 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, | ||
5408 | 0x56, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x28, 0xfe, 0x4e, 0x12, 0x67, 0xff, | ||
5409 | 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, 0x34, 0xfe, 0x89, 0x48, | ||
5410 | 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05, | ||
5411 | 0x12, 0xfe, 0xe3, 0x00, 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, | ||
5412 | 0xfe, 0x49, 0xf0, 0xfe, 0x70, 0x05, 0x88, 0x25, 0xfe, 0x21, 0x00, 0xab, | ||
5413 | 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, 0x09, 0x48, 0xff, 0x02, | ||
5414 | 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2, | ||
5415 | 0x08, 0x53, 0x05, 0xcb, 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, | ||
5416 | 0xfe, 0x27, 0x01, 0x08, 0x05, 0x1b, 0xfe, 0x22, 0x12, 0x41, 0x01, 0xb2, | ||
5417 | 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, | ||
5418 | 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb, | ||
5419 | 0x03, 0x5c, 0x28, 0xfe, 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, | ||
5420 | 0x06, 0x09, 0x06, 0x53, 0x05, 0x1f, 0xfe, 0x02, 0x12, 0x50, 0x01, 0xfe, | ||
5421 | 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, | ||
5422 | 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62, | ||
5423 | 0x12, 0x03, 0x45, 0x28, 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, | ||
5424 | 0xfe, 0x76, 0x19, 0xfe, 0x43, 0x48, 0xc4, 0xcc, 0x0f, 0x71, 0xff, 0x02, | ||
5425 | 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, 0x6e, 0x41, 0x01, 0xb2, | ||
5426 | 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01, | ||
5427 | 0xfe, 0xcc, 0x15, 0x1d, 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, | ||
5428 | 0xfe, 0xe5, 0x00, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x18, 0x06, 0x01, 0xb2, | ||
5429 | 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, 0xe2, 0x00, 0x27, 0xdb, | ||
5430 | 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07, | ||
5431 | 0xfe, 0x06, 0xf0, 0xfe, 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, | ||
5432 | 0x0a, 0xfe, 0x2e, 0x12, 0x16, 0x19, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, | ||
5433 | 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0xfe, 0x99, 0xa4, 0x01, | ||
5434 | 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38, | ||
5435 | 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, | ||
5436 | 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, | ||
5437 | 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, 0xe2, 0x6c, 0x58, 0xbe, | ||
5438 | 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b, | ||
5439 | 0xfe, 0x09, 0x6f, 0xba, 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, | ||
5440 | 0x8b, 0x6c, 0x7f, 0x27, 0xfe, 0x54, 0x07, 0x1c, 0x34, 0xfe, 0x0a, 0xf0, | ||
5441 | 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, 0x07, 0x02, 0x24, 0x01, | ||
5442 | 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe, | ||
5443 | 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, | ||
5444 | 0x61, 0x08, 0x54, 0x5a, 0x37, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x0e, 0x12, | ||
5445 | 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, 0xfe, 0x06, 0x10, 0xfe, | ||
5446 | 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b, | ||
5447 | 0x37, 0x01, 0xb3, 0xb8, 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, | ||
5448 | 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0x88, | ||
5449 | 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x0c, | ||
5450 | 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d, | ||
5451 | 0x14, 0x3e, 0xfe, 0x4a, 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, | ||
5452 | 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x05, 0x5b, | ||
5453 | 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, 0xfe, 0x44, 0x90, 0xfe, | ||
5454 | 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, | ||
5455 | 0x0c, 0x5e, 0x14, 0x5f, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, | ||
5456 | 0x14, 0x3e, 0x0c, 0x2e, 0x14, 0x3c, 0x21, 0x0c, 0x49, 0x0c, 0x63, 0x08, | ||
5457 | 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, 0xdd, 0xfe, 0x9e, | ||
5458 | 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe, | ||
5459 | 0x9a, 0x08, 0xc6, 0xfe, 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, | ||
5460 | 0xf0, 0xfe, 0x94, 0x08, 0x95, 0x86, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xc9, | ||
5461 | 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, 0x06, 0xfe, 0x10, 0x12, | ||
5462 | 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e, | ||
5463 | 0x1c, 0x02, 0xfe, 0x18, 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, | ||
5464 | 0xfe, 0x7a, 0x12, 0xfe, 0x2c, 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0xd2, 0x09, | ||
5465 | 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, 0xde, 0x09, 0xfe, 0xb7, | ||
5466 | 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18, | ||
5467 | 0xfe, 0xf1, 0x18, 0xfe, 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, | ||
5468 | 0xfe, 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x1c, 0x85, 0xfe, | ||
5469 | 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, 0xfe, 0xf0, 0x08, 0xb5, | ||
5470 | 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18, | ||
5471 | 0x0b, 0xb6, 0xfe, 0xbf, 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, | ||
5472 | 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xc2, 0xfe, 0xd2, 0xf0, 0x85, 0xfe, 0x76, | ||
5473 | 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, 0x06, 0x17, 0x85, 0xc5, | ||
5474 | 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15, | ||
5475 | 0x9d, 0x01, 0x36, 0x10, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, | ||
5476 | 0x80, 0x02, 0x65, 0xfe, 0x98, 0x80, 0xfe, 0x19, 0xe4, 0x0a, 0xfe, 0x1a, | ||
5477 | 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, 0xfe, 0x44, 0x54, 0xbe, | ||
5478 | 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08, | ||
5479 | 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, | ||
5480 | 0x14, 0x40, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x6c, 0x18, 0xfe, 0xed, 0x18, | ||
5481 | 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, 0x3b, 0x40, 0x03, 0x49, | ||
5482 | 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18, | ||
5483 | 0x8f, 0xfe, 0xe3, 0x54, 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, | ||
5484 | 0xfe, 0x37, 0xf0, 0xfe, 0xda, 0x09, 0xfe, 0x8b, 0xf0, 0xfe, 0x60, 0x09, | ||
5485 | 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, 0x0a, 0x3a, 0x49, 0x3b, | ||
5486 | 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00, | ||
5487 | 0xad, 0xfe, 0x01, 0x59, 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, | ||
5488 | 0xfe, 0x24, 0x0a, 0x3a, 0x49, 0x8f, 0xfe, 0xe3, 0x54, 0x57, 0x49, 0x7d, | ||
5489 | 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, 0x4a, 0x3a, 0x49, 0x3b, | ||
5490 | 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63, | ||
5491 | 0x02, 0x4a, 0x08, 0x05, 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, | ||
5492 | 0x66, 0x13, 0x22, 0x62, 0xb7, 0xfe, 0x03, 0xa1, 0xfe, 0x83, 0x80, 0xfe, | ||
5493 | 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x6a, | ||
5494 | 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29, | ||
5495 | 0x61, 0x0c, 0x7f, 0x14, 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, | ||
5496 | 0x6a, 0x2a, 0x13, 0x62, 0x9b, 0x2e, 0x9c, 0x3c, 0x3a, 0x3f, 0x3b, 0x40, | ||
5497 | 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0x01, 0xef, | ||
5498 | 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40, | ||
5499 | 0xe4, 0x08, 0x05, 0x1f, 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, | ||
5500 | 0xfe, 0xf7, 0x00, 0x37, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x10, 0x58, 0xfe, | ||
5501 | 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, 0xf4, 0x09, 0x08, 0x05, | ||
5502 | 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19, | ||
5503 | 0x81, 0x50, 0xfe, 0x10, 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, | ||
5504 | 0x07, 0xa6, 0x17, 0xfe, 0x08, 0x09, 0x12, 0xa6, 0x08, 0x05, 0x0a, 0xfe, | ||
5505 | 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, 0x08, 0x09, 0xfe, 0x0c, | ||
5506 | 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7, | ||
5507 | 0x08, 0x05, 0x0a, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, | ||
5508 | 0xf4, 0xc2, 0xfe, 0xd1, 0xf0, 0xe2, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, | ||
5509 | 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0x57, 0x3d, 0xfe, 0xed, | ||
5510 | 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe, | ||
5511 | 0x00, 0xff, 0x35, 0xfe, 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, | ||
5512 | 0x0b, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x8a, 0x03, 0xd2, 0x1e, 0x06, 0xfe, | ||
5513 | 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, 0xfe, 0xd1, 0xf0, 0xfe, | ||
5514 | 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42, | ||
5515 | 0x10, 0xfe, 0xce, 0xf0, 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, | ||
5516 | 0xf0, 0xfe, 0xca, 0x0b, 0x10, 0xfe, 0x22, 0x00, 0x02, 0x65, 0xfe, 0xcb, | ||
5517 | 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, 0x02, 0x65, 0xfe, 0xd0, | ||
5518 | 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea, | ||
5519 | 0x0b, 0x10, 0x58, 0xfe, 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, | ||
5520 | 0x1f, 0x4d, 0x10, 0xfe, 0x12, 0x00, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, 0x27, | ||
5521 | 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, 0x0c, 0xbc, 0x17, 0x34, | ||
5522 | 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20, | ||
5523 | 0x0c, 0x1c, 0x34, 0x94, 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, | ||
5524 | 0xdc, 0x02, 0x24, 0x01, 0x4b, 0xfe, 0xdb, 0x10, 0x12, 0xfe, 0xe8, 0x00, | ||
5525 | 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, 0x89, 0xf0, 0x24, 0x33, | ||
5526 | 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24, | ||
5527 | 0x33, 0x31, 0xdf, 0xbc, 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, | ||
5528 | 0x06, 0xfe, 0x81, 0x49, 0x17, 0xfe, 0x2c, 0x0d, 0x08, 0x05, 0x0a, 0xfe, | ||
5529 | 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, 0x12, 0x55, 0xfe, 0x28, | ||
5530 | 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, | ||
5531 | 0x44, 0xfe, 0x28, 0x00, 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, | ||
5532 | 0xa4, 0x01, 0xfe, 0x26, 0x0f, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x02, 0x2b, | ||
5533 | 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, 0x0a, 0xfe, 0xb4, 0x10, | ||
5534 | 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82, | ||
5535 | 0xfe, 0x34, 0x46, 0xac, 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, | ||
5536 | 0x10, 0x08, 0x54, 0x0a, 0x37, 0x01, 0xf5, 0x01, 0xf6, 0x64, 0x12, 0x2f, | ||
5537 | 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, 0xfe, 0x2e, 0x03, 0x08, | ||
5538 | 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05, | ||
5539 | 0x1a, 0xfe, 0x58, 0x12, 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, | ||
5540 | 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x50, 0x0d, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, | ||
5541 | 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, 0xfe, 0xa9, 0x10, 0x10, | ||
5542 | 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10, | ||
5543 | 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, | ||
5544 | 0x00, 0xaa, 0x10, 0xfe, 0x24, 0x00, 0x8c, 0xb5, 0xb6, 0x74, 0x03, 0x70, | ||
5545 | 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, 0xfe, 0x9d, 0x41, 0xfe, | ||
5546 | 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0, | ||
5547 | 0xb4, 0x15, 0xfe, 0x31, 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, | ||
5548 | 0xd7, 0x42, 0xfe, 0x06, 0xec, 0xd0, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, | ||
5549 | 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, 0x4b, 0x91, 0xfe, 0x75, | ||
5550 | 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01, | ||
5551 | 0x0e, 0xfe, 0x44, 0x48, 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, | ||
5552 | 0x46, 0x01, 0x0e, 0x41, 0xfe, 0x41, 0x58, 0x09, 0xa4, 0x01, 0x0e, 0xfe, | ||
5553 | 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, 0x2e, 0x03, 0x09, 0x5d, | ||
5554 | 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, | ||
5555 | 0xce, 0x47, 0xfe, 0xad, 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, | ||
5556 | 0x9e, 0x12, 0x21, 0x13, 0x59, 0x13, 0x9f, 0x13, 0xd5, 0x22, 0x2f, 0x41, | ||
5557 | 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, 0xe0, 0x0e, 0x0f, 0x06, | ||
5558 | 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe, | ||
5559 | 0x3a, 0x01, 0x56, 0xfe, 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, | ||
5560 | 0x66, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, | ||
5561 | 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, | ||
5562 | 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13, | ||
5563 | 0x15, 0x1a, 0x39, 0xa0, 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, | ||
5564 | 0x1e, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x03, 0xfe, 0x3a, 0x01, | ||
5565 | 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, 0x06, 0x13, 0x2f, 0x12, | ||
5566 | 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12, | ||
5567 | 0x22, 0x9f, 0xb7, 0x13, 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, | ||
5568 | 0x1c, 0x15, 0x19, 0x39, 0xa0, 0xb4, 0xfe, 0xd9, 0x10, 0xc3, 0xfe, 0x03, | ||
5569 | 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xc3, 0xfe, 0x03, 0xdc, | ||
5570 | 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21, | ||
5571 | 0xfe, 0x00, 0xcc, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, | ||
5572 | 0x58, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13, | ||
5573 | 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, 0xfe, 0x0c, 0x90, 0xfe, | ||
5574 | 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, | ||
5575 | 0x0a, 0xfe, 0x3c, 0x50, 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, | ||
5576 | 0xad, 0x01, 0xfe, 0xb4, 0x16, 0x08, 0x05, 0x1b, 0x4e, 0x01, 0xf5, 0x01, | ||
5577 | 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, 0xfe, 0x2c, 0x13, 0x01, | ||
5578 | 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90, | ||
5579 | 0x0c, 0xfe, 0x64, 0x01, 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, | ||
5580 | 0x12, 0x12, 0xfe, 0x03, 0x80, 0x8d, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80, | ||
5581 | 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, 0x22, 0x20, 0xfb, 0x79, | ||
5582 | 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, | ||
5583 | 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, | ||
5584 | 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, | ||
5585 | 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, 0x45, 0x0f, 0x46, 0x52, | ||
5586 | 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc, | ||
5587 | 0x0f, 0x44, 0x11, 0x0f, 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, | ||
5588 | 0x91, 0x54, 0x23, 0xe4, 0x25, 0x11, 0x13, 0x20, 0x7c, 0x6f, 0x4f, 0x22, | ||
5589 | 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, | ||
5590 | 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, | ||
5591 | 0x18, 0x1c, 0x04, 0x42, 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, | ||
5592 | 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x04, 0x01, 0xb0, 0x7c, 0x6f, 0x4f, | ||
5593 | 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0x32, 0x07, 0x2f, | ||
5594 | 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe, | ||
5595 | 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, | ||
5596 | 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, | ||
5597 | 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, 0x82, 0x4e, 0xfe, 0x14, | ||
5598 | 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d, | ||
5599 | 0xfe, 0x01, 0xec, 0xa2, 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, | ||
5600 | 0x9c, 0xe7, 0x1a, 0x79, 0x2a, 0x01, 0xe3, 0xfe, 0xdd, 0x10, 0x2c, 0xc7, | ||
5601 | 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, 0xfe, 0x48, 0x12, 0x07, | ||
5602 | 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17, | ||
5603 | 0xfe, 0x32, 0x12, 0x07, 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, | ||
5604 | 0xfe, 0x9c, 0x12, 0x07, 0x1f, 0xfe, 0x12, 0x12, 0x07, 0x00, 0x17, 0x24, | ||
5605 | 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, 0x94, 0x4b, 0x04, 0x2d, | ||
5606 | 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d, | ||
5607 | 0x32, 0x07, 0xa6, 0xfe, 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, | ||
5608 | 0xf0, 0x11, 0x08, 0x05, 0x5a, 0xfe, 0x72, 0x12, 0x9b, 0x2e, 0x9c, 0x3c, | ||
5609 | 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, 0xfe, 0x26, 0x13, 0x03, | ||
5610 | 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21, | ||
5611 | 0x0c, 0x7f, 0x0c, 0x80, 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, | ||
5612 | 0xef, 0x9b, 0x2e, 0x9c, 0x3c, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, | ||
5613 | 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, 0x91, 0x10, 0x03, 0x3f, | ||
5614 | 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40, | ||
5615 | 0x88, 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, | ||
5616 | 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x0c, 0x5e, 0x14, 0x5f, 0x08, 0x05, 0x5a, | ||
5617 | 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, 0x03, 0x60, 0x29, 0x61, | ||
5618 | 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44, | ||
5619 | 0x50, 0xfe, 0xc6, 0x50, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, | ||
5620 | 0x8a, 0x50, 0x03, 0x3d, 0x29, 0x3e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, | ||
5621 | 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1d, | ||
5622 | 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23, | ||
5623 | 0x72, 0x01, 0xaf, 0x1e, 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, | ||
5624 | 0x3d, 0x3b, 0x3e, 0xfe, 0x0a, 0x55, 0x35, 0xfe, 0x8b, 0x55, 0x57, 0x3d, | ||
5625 | 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x02, 0x72, 0xfe, 0x19, | ||
5626 | 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34, | ||
5627 | 0x1d, 0xe8, 0x33, 0x31, 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, | ||
5628 | 0x4d, 0x02, 0x4c, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0xe8, 0x33, 0x31, 0xdf, | ||
5629 | 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, 0x33, 0x31, 0xfe, 0xe8, | ||
5630 | 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53, | ||
5631 | 0x05, 0x1f, 0x35, 0xa9, 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, | ||
5632 | 0x7c, 0x43, 0xfe, 0xda, 0x14, 0x01, 0xaf, 0x8c, 0xfe, 0x4b, 0x45, 0xee, | ||
5633 | 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, 0x03, 0x45, 0x28, 0x35, | ||
5634 | 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, | ||
5635 | 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, | ||
5636 | 0xfe, 0x9e, 0x15, 0x02, 0x89, 0x01, 0x0b, 0x1c, 0x34, 0x1d, 0x4c, 0x33, | ||
5637 | 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, 0xfe, 0x42, 0x58, 0xf1, | ||
5638 | 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a, | ||
5639 | 0xf4, 0x06, 0xea, 0x32, 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, | ||
5640 | 0x0c, 0x45, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0xcc, 0x15, | ||
5641 | 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, 0x26, 0xfe, 0xd4, 0x13, | ||
5642 | 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0, | ||
5643 | 0x13, 0x1c, 0xfe, 0xd0, 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, | ||
5644 | 0x0b, 0xfe, 0xd5, 0x10, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, | ||
5645 | 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x04, 0x0f, | ||
5646 | 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56, | ||
5647 | 0xfe, 0x00, 0x5c, 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, | ||
5648 | 0x04, 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0xfe, 0x0b, 0x58, | ||
5649 | 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, 0x87, 0x04, 0xfe, 0x03, | ||
5650 | 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52, | ||
5651 | 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, | ||
5652 | 0x6a, 0x2a, 0x0c, 0x5e, 0x14, 0x5f, 0x57, 0x3f, 0x7d, 0x40, 0x04, 0xdd, | ||
5653 | 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x8d, 0x04, 0x01, | ||
5654 | 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d, | ||
5655 | 0xfe, 0x96, 0x15, 0x33, 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, | ||
5656 | 0x33, 0x31, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0xcd, 0x28, 0xfe, | ||
5657 | 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, 0x21, 0x69, 0x1a, 0xee, | ||
5658 | 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c, | ||
5659 | 0x30, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, | ||
5660 | 0x55, 0x69, 0x19, 0xae, 0x98, 0xfe, 0x30, 0x00, 0x96, 0xf2, 0x18, 0x6d, | ||
5661 | 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, 0x98, 0xfe, 0x64, 0x00, | ||
5662 | 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28, | ||
5663 | 0x10, 0x69, 0x06, 0xfe, 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, | ||
5664 | 0x09, 0xfe, 0xc8, 0x00, 0x18, 0x59, 0x0f, 0x06, 0x88, 0x98, 0xfe, 0x90, | ||
5665 | 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, 0x43, 0xf4, 0x9f, 0xfe, | ||
5666 | 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4, | ||
5667 | 0x9e, 0xfe, 0xf3, 0x10, 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, | ||
5668 | 0x43, 0xec, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x6e, 0x7a, 0xfe, 0x90, | ||
5669 | 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, | ||
5670 | 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d, | ||
5671 | 0xf4, 0x00, 0xe9, 0x91, 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, | ||
5672 | 0x04, 0x51, 0x0f, 0x0a, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xf3, 0x16, | ||
5673 | 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, 0x0b, 0x26, 0xf3, 0x76, | ||
5674 | 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, | ||
5675 | 0x16, 0x19, 0x01, 0x0b, 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, | ||
5676 | 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x26, 0xb1, 0x76, 0xfe, 0x89, 0x4a, 0x01, | ||
5677 | 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, 0xfe, 0x48, 0x13, 0xb8, | ||
5678 | 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01, | ||
5679 | 0xec, 0xfe, 0x27, 0x01, 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, | ||
5680 | 0xfe, 0x2e, 0x16, 0x32, 0x07, 0xfe, 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1d, | ||
5681 | 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, 0x22, 0xd4, 0x07, 0x06, | ||
5682 | 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e, | ||
5683 | 0x07, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, | ||
5684 | 0x04, 0x09, 0x84, 0x01, 0x0e, 0x8e, 0xfe, 0x80, 0xe7, 0x11, 0x07, 0x11, | ||
5685 | 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, 0x09, 0x48, 0x01, 0x0e, | ||
5686 | 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80, | ||
5687 | 0x80, 0xfe, 0x80, 0x4c, 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, | ||
5688 | 0x0e, 0xfe, 0x80, 0x4c, 0x09, 0x5d, 0x01, 0x87, 0x04, 0x18, 0x11, 0x75, | ||
5689 | 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, | ||
5690 | 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4, | ||
5691 | 0x17, 0xad, 0x9a, 0x1b, 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, | ||
5692 | 0xb9, 0x23, 0xfe, 0xde, 0x16, 0xfe, 0xda, 0x10, 0x18, 0x11, 0x75, 0x03, | ||
5693 | 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, 0x18, 0x58, 0x03, 0xfe, | ||
5694 | 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30, | ||
5695 | 0xf4, 0x06, 0xfe, 0x3c, 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, | ||
5696 | 0xfe, 0x1c, 0xf7, 0x1f, 0x97, 0xfe, 0x38, 0x17, 0xfe, 0xb6, 0x14, 0x35, | ||
5697 | 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, 0x10, 0x18, 0x11, 0x75, | ||
5698 | 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, | ||
5699 | 0x2e, 0x97, 0xfe, 0x5a, 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, | ||
5700 | 0x1a, 0xfe, 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x04, 0xb9, 0x23, 0xfe, | ||
5701 | 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, 0xfe, 0x30, 0xbc, 0xfe, | ||
5702 | 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, | ||
5703 | 0xcb, 0x97, 0xfe, 0x92, 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, | ||
5704 | 0xfe, 0x7e, 0x17, 0xfe, 0x42, 0x10, 0xfe, 0x02, 0xf6, 0x11, 0x75, 0xfe, | ||
5705 | 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, 0x03, 0xa1, 0xfe, 0x1d, | ||
5706 | 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, | ||
5707 | 0x9a, 0x5b, 0x41, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, | ||
5708 | 0x11, 0xfe, 0x81, 0xe7, 0x11, 0x12, 0xfe, 0xdd, 0x00, 0x6a, 0x2a, 0x04, | ||
5709 | 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, 0x17, 0x15, 0x06, 0x39, | ||
5710 | 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04, | ||
5711 | 0xfe, 0x7e, 0x18, 0x1e, 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, | ||
5712 | 0x1e, 0x06, 0xfe, 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x7c, 0x6f, 0x4f, 0x32, | ||
5713 | 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, 0x13, 0x42, 0x92, 0x09, | ||
5714 | 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, | ||
5715 | 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, | ||
5716 | 0xac, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, 0x01, 0x73, 0xfe, 0x16, | ||
5717 | 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, 0xfe, 0x14, | ||
5718 | 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c, | ||
5719 | 0xe7, 0x0a, 0x10, 0xfe, 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, | ||
5720 | 0x06, 0x04, 0x42, 0x92, 0x08, 0x54, 0x1b, 0x37, 0x12, 0x2f, 0x01, 0x73, | ||
5721 | 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x3a, 0xce, 0x3b, | ||
5722 | 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77, | ||
5723 | 0x13, 0xa3, 0x04, 0x09, 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, | ||
5724 | 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x17, 0xfe, 0xe8, 0x18, 0x77, 0x78, 0x04, | ||
5725 | 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, 0x5d, 0x01, 0xa8, 0x09, | ||
5726 | 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe, | ||
5727 | 0x1c, 0x19, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, | ||
5728 | 0xfe, 0x4e, 0xe4, 0xc9, 0x6b, 0xfe, 0x2e, 0x19, 0x03, 0xfe, 0x92, 0x00, | ||
5729 | 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x6b, | ||
5730 | 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe, | ||
5731 | 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, | ||
5732 | 0x45, 0xea, 0xba, 0xff, 0x04, 0x68, 0x54, 0xe7, 0x1e, 0x6e, 0xfe, 0x08, | ||
5733 | 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, 0x1a, 0xf4, 0xfe, 0x00, | ||
5734 | 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19, | ||
5735 | 0x04, 0x07, 0x7e, 0xfe, 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, | ||
5736 | 0x00, 0xfe, 0x34, 0x10, 0x07, 0x1a, 0xfe, 0x5a, 0xf0, 0xfe, 0x92, 0x19, | ||
5737 | 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, 0x25, 0x6d, 0xe5, 0x07, | ||
5738 | 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59, | ||
5739 | 0xa9, 0xb8, 0x04, 0x15, 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, | ||
5740 | 0x81, 0x03, 0x83, 0xfe, 0x40, 0x5c, 0x04, 0x1c, 0xf7, 0xfe, 0x14, 0xf0, | ||
5741 | 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, 0xf7, 0xfe, 0x82, 0xf0, | ||
5742 | 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00, | ||
5743 | }; | ||
5744 | |||
5745 | static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */ | ||
5746 | static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */ | ||
5747 | |||
5748 | /* Microcode buffer is kept after initialization for error recovery. */ | ||
5749 | static unsigned char _adv_asc38C1600_buf[] = { | ||
5750 | 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0, | ||
5751 | 0x18, 0xe4, 0x01, 0x00, 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, | ||
5752 | 0x2e, 0x1e, 0x02, 0x00, 0x07, 0x17, 0xc0, 0x5f, 0x00, 0xfa, 0xff, 0xff, | ||
5753 | 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, 0x85, 0xf0, 0x86, 0xf0, | ||
5754 | 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00, | ||
5755 | 0x98, 0x57, 0x01, 0xe6, 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, | ||
5756 | 0x08, 0x00, 0xf0, 0x1d, 0x38, 0x54, 0x32, 0xf0, 0x10, 0x00, 0xc2, 0x0e, | ||
5757 | 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, 0x00, 0xe6, 0xb1, 0xf0, | ||
5758 | 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01, | ||
5759 | 0x06, 0x13, 0x0c, 0x1c, 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, | ||
5760 | 0xbc, 0x0e, 0xa2, 0x12, 0xb9, 0x54, 0x00, 0x80, 0x62, 0x0a, 0x5a, 0x12, | ||
5761 | 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, 0x03, 0xe6, 0x01, 0xea, | ||
5762 | 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, | ||
5763 | 0x04, 0x13, 0xbb, 0x55, 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, | ||
5764 | 0x40, 0x00, 0xb6, 0x00, 0xbb, 0x00, 0xc0, 0x00, 0x00, 0x01, 0x01, 0x01, | ||
5765 | 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, 0x4c, 0x1c, 0x4e, 0x1c, | ||
5766 | 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00, | ||
5767 | 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, | ||
5768 | 0x74, 0x01, 0x76, 0x01, 0x78, 0x01, 0x7c, 0x01, 0xc6, 0x0e, 0x0c, 0x10, | ||
5769 | 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, 0x6e, 0x1e, 0x02, 0x48, | ||
5770 | 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7, | ||
5771 | 0x03, 0xfc, 0x06, 0x00, 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, | ||
5772 | 0x18, 0x1a, 0x70, 0x1a, 0x30, 0x1c, 0x38, 0x1c, 0x10, 0x44, 0x00, 0x4c, | ||
5773 | 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, 0x5d, 0xf0, 0xa7, 0xf0, | ||
5774 | 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00, | ||
5775 | 0x33, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, | ||
5776 | 0x20, 0x01, 0x4e, 0x01, 0x79, 0x01, 0x3c, 0x09, 0x68, 0x0d, 0x02, 0x10, | ||
5777 | 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, 0x40, 0x16, 0x50, 0x16, | ||
5778 | 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc, | ||
5779 | 0x05, 0xf0, 0x09, 0xf0, 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, | ||
5780 | 0x0a, 0x00, 0x9b, 0x00, 0x9c, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, | ||
5781 | 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, 0xe9, 0x09, 0x5c, 0x0c, | ||
5782 | 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, | ||
5783 | 0x42, 0x1d, 0x08, 0x44, 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, | ||
5784 | 0x89, 0x48, 0x68, 0x54, 0x83, 0x55, 0x83, 0x59, 0x31, 0xe4, 0x02, 0xe6, | ||
5785 | 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, | ||
5786 | 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, | ||
5787 | 0xa8, 0x00, 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, | ||
5788 | 0x26, 0x01, 0x60, 0x01, 0x7a, 0x01, 0x82, 0x01, 0xc8, 0x01, 0xca, 0x01, | ||
5789 | 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, 0x68, 0x08, 0x10, 0x0d, | ||
5790 | 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10, | ||
5791 | 0xf3, 0x10, 0x06, 0x12, 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, | ||
5792 | 0x10, 0x13, 0xfe, 0x9c, 0xf0, 0x35, 0x05, 0xfe, 0xec, 0x0e, 0xff, 0x10, | ||
5793 | 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, 0xfe, 0x88, 0x01, 0xff, | ||
5794 | 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, | ||
5795 | 0x00, 0xfe, 0x57, 0x24, 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, | ||
5796 | 0x00, 0x1a, 0xff, 0x09, 0x00, 0x00, 0xff, 0x08, 0x01, 0x01, 0xff, 0x08, | ||
5797 | 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, 0xff, 0xff, 0xff, 0x13, | ||
5798 | 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, | ||
5799 | 0xfe, 0x04, 0xf7, 0xe8, 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, | ||
5800 | 0x04, 0xf7, 0xe8, 0x7d, 0x0d, 0x51, 0x37, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, | ||
5801 | 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, | ||
5802 | 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d, | ||
5803 | 0x05, 0xfe, 0x08, 0x0f, 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, | ||
5804 | 0xfe, 0x0e, 0x03, 0xfe, 0x28, 0x1c, 0x03, 0xfe, 0xa6, 0x00, 0xfe, 0xd1, | ||
5805 | 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, 0x48, 0xf0, 0xfe, 0x90, | ||
5806 | 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8, | ||
5807 | 0x02, 0xfe, 0x46, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, | ||
5808 | 0x02, 0xfe, 0x43, 0xf0, 0xfe, 0x4e, 0x02, 0xfe, 0x44, 0xf0, 0xfe, 0x52, | ||
5809 | 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, 0x0d, 0xa2, 0x1c, 0x07, | ||
5810 | 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02, | ||
5811 | 0x1c, 0xf5, 0xfe, 0x1e, 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, | ||
5812 | 0x10, 0xfe, 0x06, 0xfc, 0xde, 0x0a, 0x81, 0x01, 0xa3, 0x05, 0x35, 0x1f, | ||
5813 | 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, 0x81, 0x01, 0x5c, 0xfe, | ||
5814 | 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, | ||
5815 | 0xfe, 0x58, 0x1c, 0x1c, 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, | ||
5816 | 0xf0, 0xfe, 0x0c, 0x02, 0x2b, 0xfe, 0x9e, 0x02, 0xfe, 0x5a, 0x1c, 0xfe, | ||
5817 | 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, 0x00, 0x47, 0xb8, 0x01, | ||
5818 | 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09, | ||
5819 | 0x1a, 0x31, 0xfe, 0x69, 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, | ||
5820 | 0x2c, 0x60, 0x01, 0xfe, 0x1e, 0x1e, 0x20, 0x2c, 0xfe, 0x05, 0xf6, 0xde, | ||
5821 | 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, 0x44, 0x15, 0x56, 0x51, | ||
5822 | 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57, | ||
5823 | 0x01, 0x18, 0x09, 0x00, 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, | ||
5824 | 0x58, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0xc8, 0x54, 0x7b, 0xfe, 0x1c, 0x03, | ||
5825 | 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, 0xfe, 0x02, 0xe8, 0x30, | ||
5826 | 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0, | ||
5827 | 0xfe, 0xe4, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, | ||
5828 | 0x1c, 0x2a, 0xeb, 0xfe, 0x26, 0xf0, 0xfe, 0x66, 0x03, 0xfe, 0xa0, 0xf0, | ||
5829 | 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, 0xef, 0x10, 0xfe, 0x9f, | ||
5830 | 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05, | ||
5831 | 0x70, 0x37, 0xfe, 0x48, 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, | ||
5832 | 0xfe, 0x18, 0x13, 0x26, 0x21, 0xb9, 0xc7, 0x20, 0xb9, 0x0a, 0x57, 0x01, | ||
5833 | 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, 0xe1, 0x2a, 0xeb, 0xfe, | ||
5834 | 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32, | ||
5835 | 0x15, 0xfe, 0xe4, 0x00, 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, | ||
5836 | 0xc6, 0x03, 0x01, 0x41, 0xfe, 0x06, 0xf0, 0xfe, 0xd6, 0x03, 0xaf, 0xa0, | ||
5837 | 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, 0x03, 0x81, 0x1e, 0x1b, | ||
5838 | 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05, | ||
5839 | 0xea, 0xfe, 0x46, 0x1c, 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, | ||
5840 | 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, 0x75, 0x01, 0xa6, 0x86, 0x0a, | ||
5841 | 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, 0xe1, 0x01, 0x18, 0x77, | ||
5842 | 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42, | ||
5843 | 0x8f, 0xfe, 0x70, 0x02, 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, | ||
5844 | 0x2f, 0xfe, 0x4e, 0x04, 0x16, 0xfe, 0x4a, 0x04, 0x7e, 0xfe, 0xa0, 0x00, | ||
5845 | 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, 0x02, 0x00, 0x10, 0x01, | ||
5846 | 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25, | ||
5847 | 0xee, 0xfe, 0x4c, 0x44, 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, | ||
5848 | 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x60, 0x8d, 0x30, 0x01, 0xfe, 0x4e, | ||
5849 | 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xfe, | ||
5850 | 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10, | ||
5851 | 0x13, 0x34, 0xfe, 0x4c, 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, | ||
5852 | 0x48, 0x47, 0xfe, 0x54, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xa5, 0x01, 0x43, | ||
5853 | 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, 0x28, 0xf9, 0x1f, 0x7f, | ||
5854 | 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f, | ||
5855 | 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, | ||
5856 | 0x1c, 0x90, 0x04, 0xfe, 0x9c, 0x93, 0x3a, 0x0b, 0x0e, 0x8b, 0x02, 0x1f, | ||
5857 | 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, 0x7d, 0x1d, 0xfe, 0x46, | ||
5858 | 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04, | ||
5859 | 0xfe, 0x87, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, | ||
5860 | 0x06, 0x0d, 0xfe, 0x98, 0x13, 0x0f, 0xfe, 0x20, 0x80, 0x04, 0xfe, 0xa0, | ||
5861 | 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, 0x12, 0x01, 0x38, 0x06, | ||
5862 | 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda, | ||
5863 | 0x05, 0xd0, 0x54, 0x01, 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, | ||
5864 | 0xa0, 0x00, 0x1e, 0xfe, 0x50, 0x12, 0x5e, 0xff, 0x02, 0x00, 0x10, 0x2f, | ||
5865 | 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, | ||
5866 | 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01, | ||
5867 | 0x38, 0xfe, 0x4a, 0xf0, 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, | ||
5868 | 0x05, 0x71, 0x2e, 0xfe, 0x21, 0x00, 0xf1, 0x2e, 0xfe, 0x22, 0x00, 0xa2, | ||
5869 | 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, 0x10, 0x2f, 0xfe, 0xd0, | ||
5870 | 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe, | ||
5871 | 0x1c, 0x00, 0x4d, 0x01, 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, | ||
5872 | 0x01, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x24, 0x12, 0x3e, 0x01, 0x84, 0x1f, | ||
5873 | 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, | ||
5874 | 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13, | ||
5875 | 0x03, 0xb6, 0x1e, 0xfe, 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, | ||
5876 | 0x3e, 0x01, 0x84, 0x17, 0xfe, 0x72, 0x06, 0x0a, 0x07, 0x01, 0x38, 0x06, | ||
5877 | 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, 0x19, 0x16, 0xfe, 0x68, | ||
5878 | 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66, | ||
5879 | 0x03, 0x9a, 0x1e, 0xfe, 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, | ||
5880 | 0x01, 0xc6, 0x09, 0x12, 0x48, 0xfe, 0x92, 0x06, 0x2e, 0x12, 0x01, 0xfe, | ||
5881 | 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, 0x58, 0xff, 0x02, 0x00, | ||
5882 | 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17, | ||
5883 | 0xfe, 0xea, 0x06, 0x01, 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, | ||
5884 | 0xfe, 0x84, 0x19, 0x16, 0xfe, 0xe0, 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, | ||
5885 | 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, 0x01, 0x84, 0xfe, 0xae, | ||
5886 | 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a, | ||
5887 | 0x1e, 0xfe, 0x1a, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, | ||
5888 | 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0xf0, 0x45, 0x0a, 0x95, | ||
5889 | 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, 0x36, 0xfe, 0x02, 0xf6, | ||
5890 | 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e, | ||
5891 | 0xd0, 0x0d, 0x17, 0xfe, 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, | ||
5892 | 0x90, 0x07, 0x26, 0x20, 0x9e, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x21, | ||
5893 | 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, 0x57, 0x10, 0xe6, 0x05, | ||
5894 | 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84, | ||
5895 | 0xfe, 0x9c, 0x32, 0x5f, 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, | ||
5896 | 0x2f, 0xed, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, 0xce, 0x07, 0xae, 0xfe, | ||
5897 | 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, 0xaf, 0xa0, 0x05, 0x29, | ||
5898 | 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14, | ||
5899 | 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, | ||
5900 | 0x99, 0xa4, 0x01, 0x08, 0x14, 0x00, 0x05, 0xfe, 0xc6, 0x09, 0x01, 0x76, | ||
5901 | 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x30, 0x13, | ||
5902 | 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, | ||
5903 | 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, | ||
5904 | 0x05, 0xef, 0x7c, 0x4a, 0x78, 0x4f, 0x0f, 0xfe, 0x9a, 0x81, 0x04, 0xfe, | ||
5905 | 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, 0x28, 0x48, 0xfe, 0x6c, | ||
5906 | 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32, | ||
5907 | 0x12, 0x53, 0x63, 0x4e, 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, | ||
5908 | 0xfe, 0x0a, 0xf0, 0xfe, 0x6c, 0x08, 0xaf, 0xa0, 0xae, 0xfe, 0x96, 0x08, | ||
5909 | 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, 0x05, 0xed, 0xfe, 0x9c, | ||
5910 | 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe, | ||
5911 | 0x1e, 0xfe, 0x99, 0x58, 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, | ||
5912 | 0x16, 0x09, 0x10, 0x6a, 0x22, 0x6b, 0x01, 0x0c, 0x61, 0x54, 0x44, 0x21, | ||
5913 | 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, 0x1e, 0x47, 0x2c, 0x7a, | ||
5914 | 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40, | ||
5915 | 0x01, 0x0c, 0x61, 0x65, 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, | ||
5916 | 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, | ||
5917 | 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, 0x01, 0xfe, 0xce, 0x1e, | ||
5918 | 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e, | ||
5919 | 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, | ||
5920 | 0x22, 0x4c, 0xfe, 0x8a, 0x10, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x50, 0x12, | ||
5921 | 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, 0x10, 0x6a, 0x22, 0x6b, | ||
5922 | 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04, | ||
5923 | 0xfe, 0x9f, 0x83, 0x33, 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, | ||
5924 | 0x04, 0xfe, 0xc4, 0x93, 0x3a, 0x0b, 0xfe, 0xc6, 0x90, 0x04, 0xfe, 0xc6, | ||
5925 | 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, 0x01, 0xfe, 0xce, 0x1e, | ||
5926 | 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90, | ||
5927 | 0x04, 0xfe, 0xc0, 0x93, 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, | ||
5928 | 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x4b, 0x22, 0x4c, 0x10, 0x64, 0x22, 0x34, | ||
5929 | 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, | ||
5930 | 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b, | ||
5931 | 0x3c, 0x37, 0x88, 0xf5, 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, | ||
5932 | 0xd2, 0xfe, 0x1e, 0x0a, 0xd3, 0xfe, 0x42, 0x0a, 0xae, 0xfe, 0x12, 0x0a, | ||
5933 | 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, 0x05, 0x29, 0x01, 0x41, | ||
5934 | 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07, | ||
5935 | 0xfe, 0x14, 0x12, 0x01, 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, | ||
5936 | 0xfe, 0x74, 0x12, 0xfe, 0x2e, 0x1c, 0x05, 0xfe, 0x1a, 0x0c, 0x01, 0x76, | ||
5937 | 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, 0xfe, 0x2c, 0x1c, 0xfe, | ||
5938 | 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe, | ||
5939 | 0x92, 0x10, 0xc4, 0xf6, 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, | ||
5940 | 0x1a, 0x0c, 0xc5, 0xfe, 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0xbf, 0xfe, 0x6b, | ||
5941 | 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, 0xac, 0xfe, 0xd2, 0xf0, | ||
5942 | 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07, | ||
5943 | 0x1b, 0xbf, 0xd4, 0x5b, 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, | ||
5944 | 0xfe, 0xa9, 0x10, 0x75, 0x5e, 0x32, 0x1f, 0x7f, 0x01, 0x42, 0x19, 0xfe, | ||
5945 | 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, 0x05, 0x70, 0xfe, 0x74, | ||
5946 | 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78, | ||
5947 | 0x0f, 0x4d, 0x01, 0xfe, 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, | ||
5948 | 0x5b, 0x01, 0x0c, 0x06, 0x0d, 0x2b, 0xfe, 0xe2, 0x0b, 0x01, 0x0c, 0x06, | ||
5949 | 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, 0xfe, 0x88, 0x13, 0x21, | ||
5950 | 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe, | ||
5951 | 0x83, 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, | ||
5952 | 0x13, 0x0f, 0xfe, 0x04, 0x91, 0x04, 0xfe, 0x84, 0x93, 0xfe, 0xca, 0x57, | ||
5953 | 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, 0xfe, 0xcb, 0x57, 0x0b, | ||
5954 | 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03, | ||
5955 | 0x6a, 0x3b, 0x6b, 0x10, 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, | ||
5956 | 0xc2, 0xc8, 0x7a, 0x30, 0x20, 0x6e, 0xdb, 0x64, 0xdc, 0x34, 0x91, 0x6c, | ||
5957 | 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xfe, 0x04, 0xfa, 0x64, | ||
5958 | 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97, | ||
5959 | 0x10, 0x98, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, | ||
5960 | 0x24, 0x1b, 0x40, 0x91, 0x4b, 0x7e, 0x4c, 0x01, 0x0c, 0x06, 0xfe, 0xf7, | ||
5961 | 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, | ||
5962 | 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24, | ||
5963 | 0x1b, 0x40, 0x01, 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, | ||
5964 | 0x8e, 0x1e, 0x4f, 0x0f, 0xfe, 0x10, 0x90, 0x04, 0xfe, 0x90, 0x93, 0x3a, | ||
5965 | 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, 0x79, 0x0b, 0x0e, 0xfe, | ||
5966 | 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb, | ||
5967 | 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, | ||
5968 | 0xfe, 0x6e, 0x0a, 0xfe, 0x0c, 0x58, 0xfe, 0x8d, 0x58, 0x05, 0x5b, 0x26, | ||
5969 | 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, 0x83, 0x33, 0x0b, 0x0e, | ||
5970 | 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, | ||
5971 | 0x19, 0xfe, 0x19, 0x41, 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, | ||
5972 | 0x1f, 0x92, 0x01, 0x42, 0x19, 0xfe, 0x44, 0x00, 0xfe, 0x90, 0x10, 0xfe, | ||
5973 | 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, 0x4c, 0xfe, 0x0c, 0x51, | ||
5974 | 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe, | ||
5975 | 0x76, 0x10, 0xac, 0xfe, 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, | ||
5976 | 0x23, 0x1d, 0x5d, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0x08, 0x13, 0x19, 0xfe, | ||
5977 | 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, 0xcc, 0x0c, 0x1f, 0x92, | ||
5978 | 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2, | ||
5979 | 0x0c, 0xfe, 0x3e, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, | ||
5980 | 0x22, 0x00, 0x05, 0x70, 0xfe, 0xcb, 0xf0, 0xfe, 0xea, 0x0c, 0x19, 0xfe, | ||
5981 | 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, 0xf4, 0x0c, 0x19, 0x94, | ||
5982 | 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3, | ||
5983 | 0xfe, 0xcc, 0xf0, 0xef, 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, | ||
5984 | 0x00, 0x37, 0x13, 0xfe, 0x4e, 0x11, 0x2f, 0xfe, 0x16, 0x0d, 0xfe, 0x9e, | ||
5985 | 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, 0x3c, 0x37, 0x88, 0xf5, | ||
5986 | 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32, | ||
5987 | 0x2f, 0xfe, 0x3e, 0x0d, 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, | ||
5988 | 0xd4, 0x9f, 0xd5, 0x9f, 0xd2, 0x9f, 0xd3, 0x9f, 0x05, 0x29, 0x01, 0x41, | ||
5989 | 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, 0xc5, 0x75, 0xd7, 0x99, | ||
5990 | 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8, | ||
5991 | 0x9c, 0x2f, 0xfe, 0x8c, 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, | ||
5992 | 0x48, 0xa4, 0x19, 0xfe, 0x42, 0x00, 0x05, 0x70, 0x90, 0x07, 0xfe, 0x81, | ||
5993 | 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x44, 0x13, | ||
5994 | 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b, | ||
5995 | 0xfe, 0xda, 0x0e, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, | ||
5996 | 0x28, 0x00, 0xfe, 0xfa, 0x10, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, | ||
5997 | 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, 0x15, 0x56, 0x01, 0x85, | ||
5998 | 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe, | ||
5999 | 0xcc, 0x10, 0x01, 0xa7, 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, | ||
6000 | 0xfe, 0x19, 0x82, 0x04, 0xfe, 0x99, 0x83, 0xfe, 0xcc, 0x47, 0x0b, 0x0e, | ||
6001 | 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, 0x43, 0x00, 0xfe, 0xa2, | ||
6002 | 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, | ||
6003 | 0x00, 0x1d, 0x40, 0x15, 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, | ||
6004 | 0xfe, 0x9e, 0x1e, 0x05, 0xfe, 0x3a, 0x03, 0x01, 0x0c, 0x06, 0x0d, 0x5d, | ||
6005 | 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, 0x76, 0x06, 0x12, 0xfe, | ||
6006 | 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c, | ||
6007 | 0xfe, 0x9d, 0xf0, 0xfe, 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, | ||
6008 | 0xfe, 0x94, 0x0e, 0x01, 0x0c, 0x61, 0x12, 0x44, 0xfe, 0x9f, 0x10, 0x19, | ||
6009 | 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, 0xfe, 0x2e, 0x10, 0x19, | ||
6010 | 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19, | ||
6011 | 0xfe, 0x41, 0x00, 0xa2, 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, | ||
6012 | 0x03, 0x81, 0x1e, 0x2b, 0xea, 0x4f, 0xfe, 0x04, 0xe6, 0x12, 0xfe, 0x9d, | ||
6013 | 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, 0x35, 0xfe, 0x12, 0x1c, | ||
6014 | 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01, | ||
6015 | 0xfe, 0xd4, 0x11, 0x05, 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, | ||
6016 | 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0x06, 0xea, 0xe0, | ||
6017 | 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, 0x67, 0xfe, 0x98, 0x56, | ||
6018 | 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01, | ||
6019 | 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, | ||
6020 | 0x41, 0x58, 0x0a, 0xba, 0xfe, 0xfa, 0x14, 0xfe, 0x49, 0x54, 0xb0, 0xfe, | ||
6021 | 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, 0xfe, 0xe0, 0x14, 0xfe, | ||
6022 | 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47, | ||
6023 | 0xfe, 0xad, 0x13, 0x05, 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, | ||
6024 | 0x26, 0x20, 0x96, 0x20, 0xe7, 0xfe, 0x08, 0x1c, 0xfe, 0x7c, 0x19, 0xfe, | ||
6025 | 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, 0x48, 0x55, 0xa5, 0x3b, | ||
6026 | 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe, | ||
6027 | 0xf0, 0x1a, 0x03, 0xfe, 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, | ||
6028 | 0x1e, 0x10, 0xfe, 0x02, 0xec, 0xe7, 0x53, 0x00, 0x36, 0xfe, 0x04, 0xec, | ||
6029 | 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x62, 0x1b, | ||
6030 | 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02, | ||
6031 | 0xea, 0xe7, 0x53, 0x92, 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, | ||
6032 | 0xfe, 0x2a, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x23, 0xfe, 0xf0, 0xff, 0x10, | ||
6033 | 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, 0x01, 0x01, 0xfe, 0x1e, | ||
6034 | 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02, | ||
6035 | 0x26, 0x02, 0x21, 0x96, 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, | ||
6036 | 0x1f, 0x1d, 0x47, 0xb5, 0xc3, 0xfe, 0xe1, 0x10, 0xcf, 0xfe, 0x03, 0xdc, | ||
6037 | 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, 0xfe, 0x03, 0xdc, 0xfe, | ||
6038 | 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe, | ||
6039 | 0x00, 0xcc, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, | ||
6040 | 0x4a, 0xfe, 0x4e, 0x13, 0x0f, 0xfe, 0x1c, 0x80, 0x04, 0xfe, 0x9c, 0x83, | ||
6041 | 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, 0x0f, 0xfe, 0x1e, 0x80, | ||
6042 | 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe, | ||
6043 | 0x1d, 0x80, 0x04, 0xfe, 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, | ||
6044 | 0x13, 0x01, 0xfe, 0xee, 0x1e, 0xac, 0xfe, 0x14, 0x13, 0x01, 0xfe, 0xfe, | ||
6045 | 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, | ||
6046 | 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09, | ||
6047 | 0x56, 0xfb, 0x01, 0xfe, 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, | ||
6048 | 0xfe, 0xf4, 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x15, 0xfe, 0xe9, 0x00, 0x01, | ||
6049 | 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, 0x22, 0x1b, 0xfe, 0x1e, | ||
6050 | 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe, | ||
6051 | 0x96, 0x90, 0x04, 0xfe, 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, | ||
6052 | 0x01, 0x22, 0xfe, 0x66, 0x01, 0x01, 0x0c, 0x06, 0x65, 0xf9, 0x0f, 0xfe, | ||
6053 | 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x0e, 0x77, 0xfe, 0x01, | ||
6054 | 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40, | ||
6055 | 0x21, 0x2c, 0xfe, 0x00, 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, | ||
6056 | 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, 0x03, 0xfe, 0xae, 0x00, 0xfe, 0x07, | ||
6057 | 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, 0xb2, 0x00, | ||
6058 | 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10, | ||
6059 | 0x66, 0x10, 0x55, 0x10, 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, | ||
6060 | 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, 0x88, 0x11, 0x46, 0x1a, 0x13, | ||
6061 | 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x2b, 0xfe, | ||
6062 | 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe, | ||
6063 | 0x00, 0x40, 0x8d, 0x2c, 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, | ||
6064 | 0xfe, 0xb2, 0x11, 0xfe, 0x12, 0x1c, 0x75, 0xfe, 0x14, 0x1c, 0xfe, 0x10, | ||
6065 | 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, 0x14, 0xfe, 0x0e, 0x47, | ||
6066 | 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01, | ||
6067 | 0xa7, 0x90, 0x34, 0x60, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, | ||
6068 | 0x13, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x34, 0x13, 0x0a, 0x5a, 0x01, | ||
6069 | 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, | ||
6070 | 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89, | ||
6071 | 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, | ||
6072 | 0xf2, 0x09, 0x9b, 0xa4, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xec, | ||
6073 | 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, 0xec, 0xb8, 0xfe, 0x9e, | ||
6074 | 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01, | ||
6075 | 0xf4, 0xfe, 0xdd, 0x10, 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, | ||
6076 | 0x09, 0x12, 0xfe, 0x48, 0x12, 0x09, 0x0d, 0xfe, 0x56, 0x12, 0x09, 0x1d, | ||
6077 | 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, 0x13, 0x09, 0xfe, 0x23, | ||
6078 | 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09, | ||
6079 | 0x24, 0xfe, 0x12, 0x12, 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, | ||
6080 | 0xa1, 0x32, 0x01, 0x08, 0xae, 0x41, 0x02, 0x32, 0xfe, 0x62, 0x08, 0x0a, | ||
6081 | 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, 0x35, 0x32, 0x01, 0x43, | ||
6082 | 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80, | ||
6083 | 0x13, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, | ||
6084 | 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, 0xb0, 0xfe, 0x4a, 0x13, 0x21, 0x6e, | ||
6085 | 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, 0xfe, 0xb6, 0x0e, 0x10, | ||
6086 | 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49, | ||
6087 | 0x88, 0x20, 0x6e, 0x01, 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, | ||
6088 | 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x64, 0xfe, 0x05, 0xfa, | ||
6089 | 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x40, 0x56, 0xfe, | ||
6090 | 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe, | ||
6091 | 0x44, 0x55, 0xfe, 0xe5, 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, | ||
6092 | 0xfe, 0xa1, 0x56, 0x10, 0x68, 0x22, 0x69, 0x01, 0x0c, 0x06, 0x54, 0xf9, | ||
6093 | 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, 0x6b, 0xfe, 0x2c, 0x50, | ||
6094 | 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6, | ||
6095 | 0x50, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, | ||
6096 | 0x4b, 0x3b, 0x4c, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x05, 0x73, 0x2e, | ||
6097 | 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, 0x16, 0x3d, 0x27, 0x25, | ||
6098 | 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01, | ||
6099 | 0xa6, 0x23, 0x3f, 0x1b, 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, | ||
6100 | 0x91, 0x4b, 0x7e, 0x4c, 0xfe, 0x0a, 0x55, 0x31, 0xfe, 0x8b, 0x55, 0xd9, | ||
6101 | 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0x05, 0x72, 0x01, | ||
6102 | 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08, | ||
6103 | 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, | ||
6104 | 0x83, 0x2d, 0x7f, 0x1b, 0xfe, 0x66, 0x15, 0x05, 0x3d, 0x01, 0x08, 0x2a, | ||
6105 | 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, 0x2b, 0x3d, 0x01, 0x08, | ||
6106 | 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03, | ||
6107 | 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, | ||
6108 | 0x2d, 0x00, 0xa4, 0x46, 0x07, 0x90, 0x3f, 0x01, 0xfe, 0xf8, 0x15, 0x01, | ||
6109 | 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, 0x01, 0x43, 0x09, 0x82, | ||
6110 | 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e, | ||
6111 | 0x05, 0x72, 0xfe, 0xc0, 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, | ||
6112 | 0x8a, 0x10, 0x66, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, 0xfe, 0x56, | ||
6113 | 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, 0x27, 0x25, 0xbd, | ||
6114 | 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe, | ||
6115 | 0xe8, 0x14, 0x01, 0xa6, 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, | ||
6116 | 0x4a, 0xf4, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, | ||
6117 | 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, | ||
6118 | 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, | ||
6119 | 0x27, 0x25, 0xbd, 0x09, 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, | ||
6120 | 0xfe, 0xaa, 0x14, 0xfe, 0xb6, 0x14, 0x86, 0xa8, 0xb2, 0x0d, 0x1b, 0x3d, | ||
6121 | 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, 0x82, 0x4e, 0x05, 0x72, | ||
6122 | 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, | ||
6123 | 0xfe, 0xc0, 0x19, 0x05, 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, | ||
6124 | 0xfe, 0xe2, 0x15, 0x5f, 0xcc, 0x01, 0x08, 0x26, 0x5f, 0x02, 0x8f, 0xfe, | ||
6125 | 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, 0xcc, 0x15, 0x5e, 0x32, | ||
6126 | 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, | ||
6127 | 0xad, 0x23, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, | ||
6128 | 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0x23, 0x3f, 0xfe, 0x30, | ||
6129 | 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, | ||
6130 | 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e, | ||
6131 | 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, | ||
6132 | 0x02, 0x0a, 0x66, 0x01, 0x5c, 0x0a, 0x55, 0x01, 0x5c, 0x0a, 0x6f, 0x01, | ||
6133 | 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, 0xff, 0x03, 0x00, 0x54, | ||
6134 | 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07, | ||
6135 | 0x7c, 0x3a, 0x0b, 0x0e, 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, | ||
6136 | 0x19, 0xfe, 0xfb, 0x19, 0xfe, 0x1a, 0xf7, 0x00, 0xfe, 0x1b, 0xf7, 0x00, | ||
6137 | 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, 0xda, 0x6d, 0x02, 0xfe, | ||
6138 | 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77, | ||
6139 | 0x02, 0x01, 0xc6, 0xfe, 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, | ||
6140 | 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xbe, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, | ||
6141 | 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x03, 0x9a, 0x1e, 0xfe, | ||
6142 | 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12, | ||
6143 | 0x48, 0xfe, 0x08, 0x17, 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, | ||
6144 | 0xb4, 0x7b, 0xfe, 0x26, 0x17, 0x4d, 0x13, 0x07, 0x1c, 0xb4, 0x90, 0x04, | ||
6145 | 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, 0xff, 0x02, 0x83, 0x55, | ||
6146 | 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80, | ||
6147 | 0x17, 0x1c, 0x63, 0x13, 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, | ||
6148 | 0x13, 0xd6, 0xfe, 0x64, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0x64, | ||
6149 | 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, 0x53, 0x07, 0xfe, 0x60, | ||
6150 | 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8, | ||
6151 | 0x00, 0x1c, 0x95, 0x13, 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, | ||
6152 | 0x8c, 0x17, 0x45, 0xf3, 0xfe, 0x43, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, | ||
6153 | 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, 0xf4, 0x94, 0xf6, 0x8b, | ||
6154 | 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe, | ||
6155 | 0xda, 0x17, 0x62, 0x49, 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, | ||
6156 | 0xda, 0x17, 0x62, 0x80, 0x71, 0x50, 0x26, 0xfe, 0x4d, 0xf4, 0x00, 0xf7, | ||
6157 | 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x02, 0x50, 0x13, | ||
6158 | 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27, | ||
6159 | 0x25, 0xbe, 0xfe, 0x03, 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, | ||
6160 | 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, | ||
6161 | 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, 0x01, 0x08, 0x16, 0xa9, | ||
6162 | 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01, | ||
6163 | 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, | ||
6164 | 0x03, 0xb6, 0x1e, 0x83, 0x01, 0x38, 0x06, 0x24, 0x31, 0xa2, 0x78, 0xf2, | ||
6165 | 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, 0x78, 0x03, 0x9a, 0x1e, | ||
6166 | 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10, | ||
6167 | 0xfe, 0x40, 0x5a, 0x23, 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, | ||
6168 | 0x62, 0x49, 0x71, 0x8c, 0x80, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x80, 0xfe, | ||
6169 | 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe, | ||
6170 | 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe, | ||
6171 | 0x43, 0x48, 0x2d, 0x93, 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, | ||
6172 | 0x40, 0x10, 0x2d, 0xb4, 0x36, 0xfe, 0x34, 0xf4, 0x04, 0xfe, 0x34, 0x10, | ||
6173 | 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, 0x28, 0x10, 0xfe, 0xc0, | ||
6174 | 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa, | ||
6175 | 0x18, 0x45, 0xfe, 0x1c, 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, | ||
6176 | 0x56, 0xf0, 0xfe, 0x0c, 0x19, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x40, 0xf4, | ||
6177 | 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, 0x21, 0xfe, 0x7f, 0x01, | ||
6178 | 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe, | ||
6179 | 0x7e, 0x01, 0xfe, 0xc8, 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, | ||
6180 | 0xfe, 0x48, 0x45, 0xfa, 0x21, 0xfe, 0x81, 0x01, 0xfe, 0xc8, 0x44, 0x4e, | ||
6181 | 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, 0x13, 0x0d, 0x02, 0x14, | ||
6182 | 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17, | ||
6183 | 0xfe, 0x82, 0x19, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, | ||
6184 | 0xfe, 0x89, 0x49, 0x01, 0x08, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1, | ||
6185 | 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, 0x01, 0x08, 0x17, 0xc1, | ||
6186 | 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01, | ||
6187 | 0x08, 0x02, 0x50, 0x02, 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, | ||
6188 | 0x01, 0x08, 0x17, 0x74, 0x14, 0x12, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x89, | ||
6189 | 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, 0x08, 0x17, 0x74, 0xfe, | ||
6190 | 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17, | ||
6191 | 0x74, 0x5f, 0xcc, 0x01, 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, | ||
6192 | 0x13, 0xc8, 0x20, 0xe4, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x5f, 0xa1, 0x5e, | ||
6193 | 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, 0x02, 0x00, 0x10, 0x2f, | ||
6194 | 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13, | ||
6195 | 0x16, 0xfe, 0x64, 0x1a, 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, | ||
6196 | 0x07, 0x5d, 0x01, 0x0c, 0x61, 0x07, 0x44, 0x02, 0x0a, 0x5a, 0x01, 0x18, | ||
6197 | 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, | ||
6198 | 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa, | ||
6199 | 0xfe, 0x80, 0xe7, 0x1a, 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, | ||
6200 | 0xb2, 0x16, 0xaa, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0xaa, 0x0a, 0x67, 0x01, | ||
6201 | 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, 0x7e, 0x1e, 0xfe, 0x80, | ||
6202 | 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18, | ||
6203 | 0xfe, 0x80, 0x4c, 0x0a, 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, | ||
6204 | 0xe5, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x24, 0x1c, 0xfe, 0x1d, | ||
6205 | 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, 0x2a, 0x1c, 0xfa, 0xb3, | ||
6206 | 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe, | ||
6207 | 0xf4, 0x1a, 0xfe, 0xfa, 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, | ||
6208 | 0xfe, 0x00, 0xf4, 0x24, 0xfe, 0x18, 0x58, 0x03, 0xfe, 0x66, 0x01, 0xfe, | ||
6209 | 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, 0xfe, 0x30, 0xf4, 0x07, | ||
6210 | 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, | ||
6211 | 0xf7, 0x24, 0xb1, 0xfe, 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, | ||
6212 | 0x2b, 0xfe, 0x26, 0x1b, 0xfe, 0xba, 0x10, 0x1c, 0x1a, 0x87, 0xfe, 0x83, | ||
6213 | 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x54, 0xb1, | ||
6214 | 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe, | ||
6215 | 0xaf, 0x19, 0xfe, 0x98, 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, | ||
6216 | 0xfe, 0x8a, 0x10, 0x1c, 0x1a, 0x87, 0x8b, 0x0f, 0xfe, 0x30, 0x90, 0x04, | ||
6217 | 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, 0xfe, 0x32, 0x90, 0x04, | ||
6218 | 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a, | ||
6219 | 0x7c, 0x12, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, | ||
6220 | 0x1b, 0xfe, 0x5e, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x96, 0x1b, 0x5c, | ||
6221 | 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, 0x6a, 0xfe, 0x19, 0xfe, | ||
6222 | 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee, | ||
6223 | 0x1b, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, | ||
6224 | 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x1a, 0xfe, 0x81, 0xe7, 0x1a, | ||
6225 | 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, 0x30, 0xfe, 0x12, 0x45, | ||
6226 | 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe, | ||
6227 | 0x39, 0xf0, 0x75, 0x26, 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, | ||
6228 | 0x11, 0x02, 0x87, 0x03, 0xe3, 0x23, 0x07, 0xfe, 0xef, 0x12, 0xfe, 0xe1, | ||
6229 | 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, 0x56, 0xfe, 0x3c, 0x13, | ||
6230 | 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a, | ||
6231 | 0x01, 0x18, 0xcb, 0xfe, 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, | ||
6232 | 0x01, 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, | ||
6233 | 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x4c, 0x01, | ||
6234 | 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24, | ||
6235 | 0x12, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, | ||
6236 | 0x02, 0xfe, 0x9c, 0xe7, 0x0d, 0x19, 0xfe, 0x15, 0x00, 0x40, 0x8d, 0x30, | ||
6237 | 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, 0x83, 0xfe, 0x18, 0x80, | ||
6238 | 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38, | ||
6239 | 0x90, 0xfe, 0xba, 0x90, 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, | ||
6240 | 0xfe, 0xc9, 0x55, 0x02, 0x21, 0xb9, 0x88, 0x20, 0xb9, 0x02, 0x0a, 0xba, | ||
6241 | 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, 0x18, 0xfe, 0x49, 0x44, | ||
6242 | 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09, | ||
6243 | 0x1a, 0xa4, 0x0a, 0x67, 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, | ||
6244 | 0x02, 0xfe, 0x4e, 0xe4, 0x1d, 0x7b, 0xfe, 0x52, 0x1d, 0x03, 0xfe, 0x90, | ||
6245 | 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xdd, 0x7b, | ||
6246 | 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10, | ||
6247 | 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, | ||
6248 | 0x94, 0x00, 0xd1, 0x24, 0xfe, 0x08, 0x10, 0x03, 0xfe, 0x96, 0x00, 0xd1, | ||
6249 | 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, 0x68, 0x54, 0xfe, 0xf1, | ||
6250 | 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, | ||
6251 | 0xfe, 0x1a, 0xf4, 0xfe, 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, | ||
6252 | 0x1d, 0x13, 0x1d, 0x02, 0x09, 0x92, 0xfe, 0x5a, 0xf0, 0xfe, 0xba, 0x1d, | ||
6253 | 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, 0x5a, 0xf0, 0xfe, 0xc8, | ||
6254 | 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe, | ||
6255 | 0x1a, 0x10, 0x09, 0x0d, 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, | ||
6256 | 0x95, 0xa1, 0xc8, 0x02, 0x1f, 0x93, 0x01, 0x42, 0xfe, 0x04, 0xfe, 0x99, | ||
6257 | 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, 0xfe, 0x14, 0xf0, 0x08, | ||
6258 | 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e, | ||
6259 | 0xfe, 0x82, 0xf0, 0xfe, 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, | ||
6260 | 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x18, 0x80, 0x04, 0xfe, 0x98, | ||
6261 | 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, 0x80, 0x04, 0xfe, 0x82, | ||
6262 | 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86, | ||
6263 | 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, | ||
6264 | 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x04, 0x80, 0x04, 0xfe, 0x84, | ||
6265 | 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, 0x80, 0x04, 0xfe, 0x80, | ||
6266 | 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04, | ||
6267 | 0xfe, 0x99, 0x83, 0xfe, 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, | ||
6268 | 0x83, 0x04, 0xfe, 0x86, 0x83, 0xfe, 0xce, 0x47, 0x0b, 0x0e, 0x02, 0x0f, | ||
6269 | 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, | ||
6270 | 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, | ||
6271 | 0xfe, 0x08, 0x90, 0x04, 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, | ||
6272 | 0xfe, 0x8a, 0x90, 0x04, 0xfe, 0x8a, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, | ||
6273 | 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, | ||
6274 | 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, | ||
6275 | 0xfe, 0x3c, 0x90, 0x04, 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, | ||
6276 | 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, 0x77, 0x0e, | ||
6277 | 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00, | ||
6278 | }; | ||
6279 | |||
6280 | static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */ | ||
6281 | static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */ | ||
6282 | |||
6283 | static void AscInitQLinkVar(ASC_DVC_VAR *asc_dvc) | ||
6284 | { | ||
6285 | PortAddr iop_base; | ||
6286 | int i; | ||
6287 | ushort lram_addr; | ||
6288 | |||
6289 | iop_base = asc_dvc->iop_base; | ||
6290 | AscPutRiscVarFreeQHead(iop_base, 1); | ||
6291 | AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng); | ||
6292 | AscPutVarFreeQHead(iop_base, 1); | ||
6293 | AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng); | ||
6294 | AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B, | ||
6295 | (uchar)((int)asc_dvc->max_total_qng + 1)); | ||
6296 | AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B, | ||
6297 | (uchar)((int)asc_dvc->max_total_qng + 2)); | ||
6298 | AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B, | ||
6299 | asc_dvc->max_total_qng); | ||
6300 | AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0); | ||
6301 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); | ||
6302 | AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0); | ||
6303 | AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0); | ||
6304 | AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0); | ||
6305 | AscPutQDoneInProgress(iop_base, 0); | ||
6306 | lram_addr = ASC_QADR_BEG; | ||
6307 | for (i = 0; i < 32; i++, lram_addr += 2) { | ||
6308 | AscWriteLramWord(iop_base, lram_addr, 0); | ||
7560 | } | 6309 | } |
7561 | #ifdef CONFIG_ISA | 6310 | } |
7562 | if ((bus_type & ASC_IS_EISA) != 0) { | ||
7563 | cfg_lsw = AscGetEisaChipCfg(iop_base); | ||
7564 | cfg_lsw &= 0x000F; | ||
7565 | bios_addr = (ushort)(ASC_BIOS_MIN_ADDR + | ||
7566 | (cfg_lsw * ASC_BIOS_BANK_SIZE)); | ||
7567 | return (bios_addr); | ||
7568 | } /* if */ | ||
7569 | #endif /* CONFIG_ISA */ | ||
7570 | 6311 | ||
7571 | cfg_lsw = AscGetChipCfgLsw(iop_base); | 6312 | static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc) |
6313 | { | ||
6314 | int i; | ||
6315 | ushort warn_code; | ||
6316 | PortAddr iop_base; | ||
6317 | ASC_PADDR phy_addr; | ||
6318 | ASC_DCNT phy_size; | ||
6319 | struct asc_board *board = asc_dvc_to_board(asc_dvc); | ||
7572 | 6320 | ||
7573 | /* | 6321 | iop_base = asc_dvc->iop_base; |
7574 | * ISA PnP uses the top bit as the 32K BIOS flag | 6322 | warn_code = 0; |
7575 | */ | 6323 | for (i = 0; i <= ASC_MAX_TID; i++) { |
7576 | if (bus_type == ASC_IS_ISAPNP) { | 6324 | AscPutMCodeInitSDTRAtID(iop_base, i, |
7577 | cfg_lsw &= 0x7FFF; | 6325 | asc_dvc->cfg->sdtr_period_offset[i]); |
7578 | } | 6326 | } |
7579 | /* if */ | 6327 | |
7580 | bios_addr = (ushort)(((cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE) + | 6328 | AscInitQLinkVar(asc_dvc); |
7581 | ASC_BIOS_MIN_ADDR); | 6329 | AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B, |
7582 | return (bios_addr); | 6330 | asc_dvc->cfg->disc_enable); |
6331 | AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B, | ||
6332 | ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id)); | ||
6333 | |||
6334 | /* Ensure overrun buffer is aligned on an 8 byte boundary. */ | ||
6335 | BUG_ON((unsigned long)asc_dvc->overrun_buf & 7); | ||
6336 | asc_dvc->overrun_dma = dma_map_single(board->dev, asc_dvc->overrun_buf, | ||
6337 | ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); | ||
6338 | phy_addr = cpu_to_le32(asc_dvc->overrun_dma); | ||
6339 | AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D, | ||
6340 | (uchar *)&phy_addr, 1); | ||
6341 | phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE); | ||
6342 | AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D, | ||
6343 | (uchar *)&phy_size, 1); | ||
6344 | |||
6345 | asc_dvc->cfg->mcode_date = | ||
6346 | AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W); | ||
6347 | asc_dvc->cfg->mcode_version = | ||
6348 | AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W); | ||
6349 | |||
6350 | AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR); | ||
6351 | if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) { | ||
6352 | asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR; | ||
6353 | return warn_code; | ||
6354 | } | ||
6355 | if (AscStartChip(iop_base) != 1) { | ||
6356 | asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP; | ||
6357 | return warn_code; | ||
6358 | } | ||
6359 | |||
6360 | return warn_code; | ||
7583 | } | 6361 | } |
7584 | 6362 | ||
7585 | /* | 6363 | static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc) |
7586 | * --- Functions Required by the Adv Library | 6364 | { |
7587 | */ | 6365 | ushort warn_code; |
6366 | PortAddr iop_base; | ||
6367 | |||
6368 | iop_base = asc_dvc->iop_base; | ||
6369 | warn_code = 0; | ||
6370 | if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) && | ||
6371 | !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) { | ||
6372 | AscResetChipAndScsiBus(asc_dvc); | ||
6373 | mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */ | ||
6374 | } | ||
6375 | asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC; | ||
6376 | if (asc_dvc->err_code != 0) | ||
6377 | return UW_ERR; | ||
6378 | if (!AscFindSignature(asc_dvc->iop_base)) { | ||
6379 | asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; | ||
6380 | return warn_code; | ||
6381 | } | ||
6382 | AscDisableInterrupt(iop_base); | ||
6383 | warn_code |= AscInitLram(asc_dvc); | ||
6384 | if (asc_dvc->err_code != 0) | ||
6385 | return UW_ERR; | ||
6386 | ASC_DBG(1, "_asc_mcode_chksum 0x%lx\n", (ulong)_asc_mcode_chksum); | ||
6387 | if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf, | ||
6388 | _asc_mcode_size) != _asc_mcode_chksum) { | ||
6389 | asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; | ||
6390 | return warn_code; | ||
6391 | } | ||
6392 | warn_code |= AscInitMicroCodeVar(asc_dvc); | ||
6393 | asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC; | ||
6394 | AscEnableInterrupt(iop_base); | ||
6395 | return warn_code; | ||
6396 | } | ||
7588 | 6397 | ||
7589 | /* | 6398 | /* |
7590 | * DvcGetPhyAddr() | 6399 | * Load the Microcode |
6400 | * | ||
6401 | * Write the microcode image to RISC memory starting at address 0. | ||
6402 | * | ||
6403 | * The microcode is stored compressed in the following format: | ||
7591 | * | 6404 | * |
7592 | * Return the physical address of 'vaddr' and set '*lenp' to the | 6405 | * 254 word (508 byte) table indexed by byte code followed |
7593 | * number of physically contiguous bytes that follow 'vaddr'. | 6406 | * by the following byte codes: |
7594 | * 'flag' indicates the type of structure whose physical address | ||
7595 | * is being translated. | ||
7596 | * | 6407 | * |
7597 | * Note: Because Linux currently doesn't page the kernel and all | 6408 | * 1-Byte Code: |
7598 | * kernel buffers are physically contiguous, leave '*lenp' unchanged. | 6409 | * 00: Emit word 0 in table. |
6410 | * 01: Emit word 1 in table. | ||
6411 | * . | ||
6412 | * FD: Emit word 253 in table. | ||
6413 | * | ||
6414 | * Multi-Byte Code: | ||
6415 | * FE WW WW: (3 byte code) Word to emit is the next word WW WW. | ||
6416 | * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. | ||
6417 | * | ||
6418 | * Returns 0 or an error if the checksum doesn't match | ||
7599 | */ | 6419 | */ |
7600 | ADV_PADDR | 6420 | static int AdvLoadMicrocode(AdvPortAddr iop_base, unsigned char *buf, int size, |
7601 | DvcGetPhyAddr(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq, | 6421 | int memsize, int chksum) |
7602 | uchar *vaddr, ADV_SDCNT *lenp, int flag) | ||
7603 | { | 6422 | { |
7604 | ADV_PADDR paddr; | 6423 | int i, j, end, len = 0; |
6424 | ADV_DCNT sum; | ||
6425 | |||
6426 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); | ||
7605 | 6427 | ||
7606 | paddr = virt_to_bus(vaddr); | 6428 | for (i = 253 * 2; i < size; i++) { |
6429 | if (buf[i] == 0xff) { | ||
6430 | unsigned short word = (buf[i + 3] << 8) | buf[i + 2]; | ||
6431 | for (j = 0; j < buf[i + 1]; j++) { | ||
6432 | AdvWriteWordAutoIncLram(iop_base, word); | ||
6433 | len += 2; | ||
6434 | } | ||
6435 | i += 3; | ||
6436 | } else if (buf[i] == 0xfe) { | ||
6437 | unsigned short word = (buf[i + 2] << 8) | buf[i + 1]; | ||
6438 | AdvWriteWordAutoIncLram(iop_base, word); | ||
6439 | i += 2; | ||
6440 | len += 2; | ||
6441 | } else { | ||
6442 | unsigned char off = buf[i] * 2; | ||
6443 | unsigned short word = (buf[off + 1] << 8) | buf[off]; | ||
6444 | AdvWriteWordAutoIncLram(iop_base, word); | ||
6445 | len += 2; | ||
6446 | } | ||
6447 | } | ||
7607 | 6448 | ||
7608 | ASC_DBG4(4, | 6449 | end = len; |
7609 | "DvcGetPhyAddr: vaddr 0x%lx, lenp 0x%lx *lenp %lu, paddr 0x%lx\n", | ||
7610 | (ulong)vaddr, (ulong)lenp, (ulong)*((ulong *)lenp), | ||
7611 | (ulong)paddr); | ||
7612 | 6450 | ||
7613 | return paddr; | 6451 | while (len < memsize) { |
6452 | AdvWriteWordAutoIncLram(iop_base, 0); | ||
6453 | len += 2; | ||
6454 | } | ||
6455 | |||
6456 | /* Verify the microcode checksum. */ | ||
6457 | sum = 0; | ||
6458 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); | ||
6459 | |||
6460 | for (len = 0; len < end; len += 2) { | ||
6461 | sum += AdvReadWordAutoIncLram(iop_base); | ||
6462 | } | ||
6463 | |||
6464 | if (sum != chksum) | ||
6465 | return ASC_IERR_MCODE_CHKSUM; | ||
6466 | |||
6467 | return 0; | ||
7614 | } | 6468 | } |
7615 | 6469 | ||
7616 | /* | 6470 | static void AdvBuildCarrierFreelist(struct adv_dvc_var *asc_dvc) |
7617 | * Read a PCI configuration byte. | ||
7618 | */ | ||
7619 | static uchar __init DvcAdvReadPCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset) | ||
7620 | { | 6471 | { |
7621 | #ifdef CONFIG_PCI | 6472 | ADV_CARR_T *carrp; |
7622 | uchar byte_data; | 6473 | ADV_SDCNT buf_size; |
7623 | pci_read_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, &byte_data); | 6474 | ADV_PADDR carr_paddr; |
7624 | return byte_data; | 6475 | |
7625 | #else /* CONFIG_PCI */ | 6476 | carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf); |
7626 | return 0; | 6477 | asc_dvc->carr_freelist = NULL; |
7627 | #endif /* CONFIG_PCI */ | 6478 | if (carrp == asc_dvc->carrier_buf) { |
6479 | buf_size = ADV_CARRIER_BUFSIZE; | ||
6480 | } else { | ||
6481 | buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T); | ||
6482 | } | ||
6483 | |||
6484 | do { | ||
6485 | /* Get physical address of the carrier 'carrp'. */ | ||
6486 | carr_paddr = cpu_to_le32(virt_to_bus(carrp)); | ||
6487 | |||
6488 | buf_size -= sizeof(ADV_CARR_T); | ||
6489 | |||
6490 | carrp->carr_pa = carr_paddr; | ||
6491 | carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp)); | ||
6492 | |||
6493 | /* | ||
6494 | * Insert the carrier at the beginning of the freelist. | ||
6495 | */ | ||
6496 | carrp->next_vpa = | ||
6497 | cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); | ||
6498 | asc_dvc->carr_freelist = carrp; | ||
6499 | |||
6500 | carrp++; | ||
6501 | } while (buf_size > 0); | ||
7628 | } | 6502 | } |
7629 | 6503 | ||
7630 | /* | 6504 | /* |
7631 | * Write a PCI configuration byte. | 6505 | * Send an idle command to the chip and wait for completion. |
6506 | * | ||
6507 | * Command completion is polled for once per microsecond. | ||
6508 | * | ||
6509 | * The function can be called from anywhere including an interrupt handler. | ||
6510 | * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical() | ||
6511 | * functions to prevent reentrancy. | ||
6512 | * | ||
6513 | * Return Values: | ||
6514 | * ADV_TRUE - command completed successfully | ||
6515 | * ADV_FALSE - command failed | ||
6516 | * ADV_ERROR - command timed out | ||
7632 | */ | 6517 | */ |
7633 | static void __init | 6518 | static int |
7634 | DvcAdvWritePCIConfigByte(ADV_DVC_VAR *asc_dvc, ushort offset, uchar byte_data) | 6519 | AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc, |
6520 | ushort idle_cmd, ADV_DCNT idle_cmd_parameter) | ||
7635 | { | 6521 | { |
7636 | #ifdef CONFIG_PCI | 6522 | int result; |
7637 | pci_write_config_byte(to_pci_dev(asc_dvc->cfg->dev), offset, byte_data); | 6523 | ADV_DCNT i, j; |
7638 | #else /* CONFIG_PCI */ | 6524 | AdvPortAddr iop_base; |
7639 | return; | 6525 | |
7640 | #endif /* CONFIG_PCI */ | 6526 | iop_base = asc_dvc->iop_base; |
6527 | |||
6528 | /* | ||
6529 | * Clear the idle command status which is set by the microcode | ||
6530 | * to a non-zero value to indicate when the command is completed. | ||
6531 | * The non-zero result is one of the IDLE_CMD_STATUS_* values | ||
6532 | */ | ||
6533 | AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0); | ||
6534 | |||
6535 | /* | ||
6536 | * Write the idle command value after the idle command parameter | ||
6537 | * has been written to avoid a race condition. If the order is not | ||
6538 | * followed, the microcode may process the idle command before the | ||
6539 | * parameters have been written to LRAM. | ||
6540 | */ | ||
6541 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER, | ||
6542 | cpu_to_le32(idle_cmd_parameter)); | ||
6543 | AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd); | ||
6544 | |||
6545 | /* | ||
6546 | * Tickle the RISC to tell it to process the idle command. | ||
6547 | */ | ||
6548 | AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B); | ||
6549 | if (asc_dvc->chip_type == ADV_CHIP_ASC3550) { | ||
6550 | /* | ||
6551 | * Clear the tickle value. In the ASC-3550 the RISC flag | ||
6552 | * command 'clr_tickle_b' does not work unless the host | ||
6553 | * value is cleared. | ||
6554 | */ | ||
6555 | AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP); | ||
6556 | } | ||
6557 | |||
6558 | /* Wait for up to 100 millisecond for the idle command to timeout. */ | ||
6559 | for (i = 0; i < SCSI_WAIT_100_MSEC; i++) { | ||
6560 | /* Poll once each microsecond for command completion. */ | ||
6561 | for (j = 0; j < SCSI_US_PER_MSEC; j++) { | ||
6562 | AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, | ||
6563 | result); | ||
6564 | if (result != 0) | ||
6565 | return result; | ||
6566 | udelay(1); | ||
6567 | } | ||
6568 | } | ||
6569 | |||
6570 | BUG(); /* The idle command should never timeout. */ | ||
6571 | return ADV_ERROR; | ||
7641 | } | 6572 | } |
7642 | 6573 | ||
7643 | /* | 6574 | /* |
7644 | * --- Tracing and Debugging Functions | 6575 | * Reset SCSI Bus and purge all outstanding requests. |
6576 | * | ||
6577 | * Return Value: | ||
6578 | * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset. | ||
6579 | * ADV_FALSE(0) - Microcode command failed. | ||
6580 | * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC | ||
6581 | * may be hung which requires driver recovery. | ||
7645 | */ | 6582 | */ |
6583 | static int AdvResetSB(ADV_DVC_VAR *asc_dvc) | ||
6584 | { | ||
6585 | int status; | ||
6586 | |||
6587 | /* | ||
6588 | * Send the SCSI Bus Reset idle start idle command which asserts | ||
6589 | * the SCSI Bus Reset signal. | ||
6590 | */ | ||
6591 | status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L); | ||
6592 | if (status != ADV_TRUE) { | ||
6593 | return status; | ||
6594 | } | ||
6595 | |||
6596 | /* | ||
6597 | * Delay for the specified SCSI Bus Reset hold time. | ||
6598 | * | ||
6599 | * The hold time delay is done on the host because the RISC has no | ||
6600 | * microsecond accurate timer. | ||
6601 | */ | ||
6602 | udelay(ASC_SCSI_RESET_HOLD_TIME_US); | ||
6603 | |||
6604 | /* | ||
6605 | * Send the SCSI Bus Reset end idle command which de-asserts | ||
6606 | * the SCSI Bus Reset signal and purges any pending requests. | ||
6607 | */ | ||
6608 | status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L); | ||
6609 | if (status != ADV_TRUE) { | ||
6610 | return status; | ||
6611 | } | ||
6612 | |||
6613 | mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */ | ||
6614 | |||
6615 | return status; | ||
6616 | } | ||
7646 | 6617 | ||
7647 | #ifdef ADVANSYS_STATS | ||
7648 | #ifdef CONFIG_PROC_FS | ||
7649 | /* | 6618 | /* |
7650 | * asc_prt_board_stats() | 6619 | * Initialize the ASC-3550. |
7651 | * | 6620 | * |
7652 | * Note: no single line should be greater than ASC_PRTLINE_SIZE, | 6621 | * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. |
7653 | * cf. asc_prt_line(). | ||
7654 | * | 6622 | * |
7655 | * Return the number of characters copied into 'cp'. No more than | 6623 | * For a non-fatal error return a warning code. If there are no warnings |
7656 | * 'cplen' characters will be copied to 'cp'. | 6624 | * then 0 is returned. |
6625 | * | ||
6626 | * Needed after initialization for error recovery. | ||
7657 | */ | 6627 | */ |
7658 | static int asc_prt_board_stats(struct Scsi_Host *shost, char *cp, int cplen) | 6628 | static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) |
7659 | { | 6629 | { |
7660 | int leftlen; | 6630 | AdvPortAddr iop_base; |
7661 | int totlen; | 6631 | ushort warn_code; |
7662 | int len; | 6632 | int begin_addr; |
7663 | struct asc_stats *s; | 6633 | int end_addr; |
7664 | asc_board_t *boardp; | 6634 | ushort code_sum; |
6635 | int word; | ||
6636 | int i; | ||
6637 | ushort scsi_cfg1; | ||
6638 | uchar tid; | ||
6639 | ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */ | ||
6640 | ushort wdtr_able = 0, sdtr_able, tagqng_able; | ||
6641 | uchar max_cmd[ADV_MAX_TID + 1]; | ||
7665 | 6642 | ||
7666 | leftlen = cplen; | 6643 | /* If there is already an error, don't continue. */ |
7667 | totlen = len = 0; | 6644 | if (asc_dvc->err_code != 0) |
6645 | return ADV_ERROR; | ||
7668 | 6646 | ||
7669 | boardp = ASC_BOARDP(shost); | 6647 | /* |
7670 | s = &boardp->asc_stats; | 6648 | * The caller must set 'chip_type' to ADV_CHIP_ASC3550. |
6649 | */ | ||
6650 | if (asc_dvc->chip_type != ADV_CHIP_ASC3550) { | ||
6651 | asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE; | ||
6652 | return ADV_ERROR; | ||
6653 | } | ||
7671 | 6654 | ||
7672 | len = asc_prt_line(cp, leftlen, | 6655 | warn_code = 0; |
7673 | "\nLinux Driver Statistics for AdvanSys SCSI Host %d:\n", | 6656 | iop_base = asc_dvc->iop_base; |
7674 | shost->host_no); | ||
7675 | ASC_PRT_NEXT(); | ||
7676 | 6657 | ||
7677 | len = asc_prt_line(cp, leftlen, | 6658 | /* |
7678 | " queuecommand %lu, reset %lu, biosparam %lu, interrupt %lu\n", | 6659 | * Save the RISC memory BIOS region before writing the microcode. |
7679 | s->queuecommand, s->reset, s->biosparam, | 6660 | * The BIOS may already be loaded and using its RISC LRAM region |
7680 | s->interrupt); | 6661 | * so its region must be saved and restored. |
7681 | ASC_PRT_NEXT(); | 6662 | * |
6663 | * Note: This code makes the assumption, which is currently true, | ||
6664 | * that a chip reset does not clear RISC LRAM. | ||
6665 | */ | ||
6666 | for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { | ||
6667 | AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), | ||
6668 | bios_mem[i]); | ||
6669 | } | ||
7682 | 6670 | ||
7683 | len = asc_prt_line(cp, leftlen, | 6671 | /* |
7684 | " callback %lu, done %lu, build_error %lu, build_noreq %lu, build_nosg %lu\n", | 6672 | * Save current per TID negotiated values. |
7685 | s->callback, s->done, s->build_error, | 6673 | */ |
7686 | s->adv_build_noreq, s->adv_build_nosg); | 6674 | if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) { |
7687 | ASC_PRT_NEXT(); | 6675 | ushort bios_version, major, minor; |
7688 | 6676 | ||
7689 | len = asc_prt_line(cp, leftlen, | 6677 | bios_version = |
7690 | " exe_noerror %lu, exe_busy %lu, exe_error %lu, exe_unknown %lu\n", | 6678 | bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2]; |
7691 | s->exe_noerror, s->exe_busy, s->exe_error, | 6679 | major = (bios_version >> 12) & 0xF; |
7692 | s->exe_unknown); | 6680 | minor = (bios_version >> 8) & 0xF; |
7693 | ASC_PRT_NEXT(); | 6681 | if (major < 3 || (major == 3 && minor == 1)) { |
6682 | /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */ | ||
6683 | AdvReadWordLram(iop_base, 0x120, wdtr_able); | ||
6684 | } else { | ||
6685 | AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
6686 | } | ||
6687 | } | ||
6688 | AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
6689 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | ||
6690 | for (tid = 0; tid <= ADV_MAX_TID; tid++) { | ||
6691 | AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
6692 | max_cmd[tid]); | ||
6693 | } | ||
6694 | |||
6695 | asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc3550_buf, | ||
6696 | _adv_asc3550_size, ADV_3550_MEMSIZE, | ||
6697 | _adv_asc3550_chksum); | ||
6698 | if (asc_dvc->err_code) | ||
6699 | return ADV_ERROR; | ||
7694 | 6700 | ||
7695 | /* | 6701 | /* |
7696 | * Display data transfer statistics. | 6702 | * Restore the RISC memory BIOS region. |
7697 | */ | 6703 | */ |
7698 | if (s->cont_cnt > 0) { | 6704 | for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { |
7699 | len = asc_prt_line(cp, leftlen, " cont_cnt %lu, ", s->cont_cnt); | 6705 | AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), |
7700 | ASC_PRT_NEXT(); | 6706 | bios_mem[i]); |
6707 | } | ||
7701 | 6708 | ||
7702 | len = asc_prt_line(cp, leftlen, "cont_xfer %lu.%01lu kb ", | 6709 | /* |
7703 | s->cont_xfer / 2, | 6710 | * Calculate and write the microcode code checksum to the microcode |
7704 | ASC_TENTHS(s->cont_xfer, 2)); | 6711 | * code checksum location ASC_MC_CODE_CHK_SUM (0x2C). |
7705 | ASC_PRT_NEXT(); | 6712 | */ |
6713 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr); | ||
6714 | AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr); | ||
6715 | code_sum = 0; | ||
6716 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr); | ||
6717 | for (word = begin_addr; word < end_addr; word += 2) { | ||
6718 | code_sum += AdvReadWordAutoIncLram(iop_base); | ||
6719 | } | ||
6720 | AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum); | ||
7706 | 6721 | ||
7707 | /* Contiguous transfer average size */ | 6722 | /* |
7708 | len = asc_prt_line(cp, leftlen, "avg_xfer %lu.%01lu kb\n", | 6723 | * Read and save microcode version and date. |
7709 | (s->cont_xfer / 2) / s->cont_cnt, | 6724 | */ |
7710 | ASC_TENTHS((s->cont_xfer / 2), s->cont_cnt)); | 6725 | AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, |
7711 | ASC_PRT_NEXT(); | 6726 | asc_dvc->cfg->mcode_date); |
6727 | AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, | ||
6728 | asc_dvc->cfg->mcode_version); | ||
6729 | |||
6730 | /* | ||
6731 | * Set the chip type to indicate the ASC3550. | ||
6732 | */ | ||
6733 | AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550); | ||
6734 | |||
6735 | /* | ||
6736 | * If the PCI Configuration Command Register "Parity Error Response | ||
6737 | * Control" Bit was clear (0), then set the microcode variable | ||
6738 | * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode | ||
6739 | * to ignore DMA parity errors. | ||
6740 | */ | ||
6741 | if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) { | ||
6742 | AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
6743 | word |= CONTROL_FLAG_IGNORE_PERR; | ||
6744 | AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
7712 | } | 6745 | } |
7713 | 6746 | ||
7714 | if (s->sg_cnt > 0) { | 6747 | /* |
6748 | * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO | ||
6749 | * threshold of 128 bytes. This register is only accessible to the host. | ||
6750 | */ | ||
6751 | AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0, | ||
6752 | START_CTL_EMFU | READ_CMD_MRM); | ||
7715 | 6753 | ||
7716 | len = asc_prt_line(cp, leftlen, " sg_cnt %lu, sg_elem %lu, ", | 6754 | /* |
7717 | s->sg_cnt, s->sg_elem); | 6755 | * Microcode operating variables for WDTR, SDTR, and command tag |
7718 | ASC_PRT_NEXT(); | 6756 | * queuing will be set in slave_configure() based on what a |
6757 | * device reports it is capable of in Inquiry byte 7. | ||
6758 | * | ||
6759 | * If SCSI Bus Resets have been disabled, then directly set | ||
6760 | * SDTR and WDTR from the EEPROM configuration. This will allow | ||
6761 | * the BIOS and warm boot to work without a SCSI bus hang on | ||
6762 | * the Inquiry caused by host and target mismatched DTR values. | ||
6763 | * Without the SCSI Bus Reset, before an Inquiry a device can't | ||
6764 | * be assumed to be in Asynchronous, Narrow mode. | ||
6765 | */ | ||
6766 | if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) { | ||
6767 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, | ||
6768 | asc_dvc->wdtr_able); | ||
6769 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, | ||
6770 | asc_dvc->sdtr_able); | ||
6771 | } | ||
7719 | 6772 | ||
7720 | len = asc_prt_line(cp, leftlen, "sg_xfer %lu.%01lu kb\n", | 6773 | /* |
7721 | s->sg_xfer / 2, ASC_TENTHS(s->sg_xfer, 2)); | 6774 | * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2, |
7722 | ASC_PRT_NEXT(); | 6775 | * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID |
6776 | * bitmask. These values determine the maximum SDTR speed negotiated | ||
6777 | * with a device. | ||
6778 | * | ||
6779 | * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, | ||
6780 | * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them | ||
6781 | * without determining here whether the device supports SDTR. | ||
6782 | * | ||
6783 | * 4-bit speed SDTR speed name | ||
6784 | * =========== =============== | ||
6785 | * 0000b (0x0) SDTR disabled | ||
6786 | * 0001b (0x1) 5 Mhz | ||
6787 | * 0010b (0x2) 10 Mhz | ||
6788 | * 0011b (0x3) 20 Mhz (Ultra) | ||
6789 | * 0100b (0x4) 40 Mhz (LVD/Ultra2) | ||
6790 | * 0101b (0x5) 80 Mhz (LVD2/Ultra3) | ||
6791 | * 0110b (0x6) Undefined | ||
6792 | * . | ||
6793 | * 1111b (0xF) Undefined | ||
6794 | */ | ||
6795 | word = 0; | ||
6796 | for (tid = 0; tid <= ADV_MAX_TID; tid++) { | ||
6797 | if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) { | ||
6798 | /* Set Ultra speed for TID 'tid'. */ | ||
6799 | word |= (0x3 << (4 * (tid % 4))); | ||
6800 | } else { | ||
6801 | /* Set Fast speed for TID 'tid'. */ | ||
6802 | word |= (0x2 << (4 * (tid % 4))); | ||
6803 | } | ||
6804 | if (tid == 3) { /* Check if done with sdtr_speed1. */ | ||
6805 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word); | ||
6806 | word = 0; | ||
6807 | } else if (tid == 7) { /* Check if done with sdtr_speed2. */ | ||
6808 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word); | ||
6809 | word = 0; | ||
6810 | } else if (tid == 11) { /* Check if done with sdtr_speed3. */ | ||
6811 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word); | ||
6812 | word = 0; | ||
6813 | } else if (tid == 15) { /* Check if done with sdtr_speed4. */ | ||
6814 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word); | ||
6815 | /* End of loop. */ | ||
6816 | } | ||
6817 | } | ||
7723 | 6818 | ||
7724 | /* Scatter gather transfer statistics */ | 6819 | /* |
7725 | len = asc_prt_line(cp, leftlen, " avg_num_elem %lu.%01lu, ", | 6820 | * Set microcode operating variable for the disconnect per TID bitmask. |
7726 | s->sg_elem / s->sg_cnt, | 6821 | */ |
7727 | ASC_TENTHS(s->sg_elem, s->sg_cnt)); | 6822 | AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, |
7728 | ASC_PRT_NEXT(); | 6823 | asc_dvc->cfg->disc_enable); |
7729 | 6824 | ||
7730 | len = asc_prt_line(cp, leftlen, "avg_elem_size %lu.%01lu kb, ", | 6825 | /* |
7731 | (s->sg_xfer / 2) / s->sg_elem, | 6826 | * Set SCSI_CFG0 Microcode Default Value. |
7732 | ASC_TENTHS((s->sg_xfer / 2), s->sg_elem)); | 6827 | * |
7733 | ASC_PRT_NEXT(); | 6828 | * The microcode will set the SCSI_CFG0 register using this value |
6829 | * after it is started below. | ||
6830 | */ | ||
6831 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0, | ||
6832 | PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN | | ||
6833 | asc_dvc->chip_scsi_id); | ||
7734 | 6834 | ||
7735 | len = asc_prt_line(cp, leftlen, "avg_xfer_size %lu.%01lu kb\n", | 6835 | /* |
7736 | (s->sg_xfer / 2) / s->sg_cnt, | 6836 | * Determine SCSI_CFG1 Microcode Default Value. |
7737 | ASC_TENTHS((s->sg_xfer / 2), s->sg_cnt)); | 6837 | * |
7738 | ASC_PRT_NEXT(); | 6838 | * The microcode will set the SCSI_CFG1 register using this value |
6839 | * after it is started below. | ||
6840 | */ | ||
6841 | |||
6842 | /* Read current SCSI_CFG1 Register value. */ | ||
6843 | scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); | ||
6844 | |||
6845 | /* | ||
6846 | * If all three connectors are in use, return an error. | ||
6847 | */ | ||
6848 | if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 || | ||
6849 | (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) { | ||
6850 | asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION; | ||
6851 | return ADV_ERROR; | ||
7739 | } | 6852 | } |
7740 | 6853 | ||
7741 | /* | 6854 | /* |
7742 | * Display request queuing statistics. | 6855 | * If the internal narrow cable is reversed all of the SCSI_CTRL |
6856 | * register signals will be set. Check for and return an error if | ||
6857 | * this condition is found. | ||
7743 | */ | 6858 | */ |
7744 | len = asc_prt_line(cp, leftlen, | 6859 | if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) { |
7745 | " Active and Waiting Request Queues (Time Unit: %d HZ):\n", | 6860 | asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE; |
7746 | HZ); | 6861 | return ADV_ERROR; |
7747 | ASC_PRT_NEXT(); | 6862 | } |
7748 | 6863 | ||
7749 | return totlen; | 6864 | /* |
6865 | * If this is a differential board and a single-ended device | ||
6866 | * is attached to one of the connectors, return an error. | ||
6867 | */ | ||
6868 | if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) { | ||
6869 | asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE; | ||
6870 | return ADV_ERROR; | ||
6871 | } | ||
6872 | |||
6873 | /* | ||
6874 | * If automatic termination control is enabled, then set the | ||
6875 | * termination value based on a table listed in a_condor.h. | ||
6876 | * | ||
6877 | * If manual termination was specified with an EEPROM setting | ||
6878 | * then 'termination' was set-up in AdvInitFrom3550EEPROM() and | ||
6879 | * is ready to be 'ored' into SCSI_CFG1. | ||
6880 | */ | ||
6881 | if (asc_dvc->cfg->termination == 0) { | ||
6882 | /* | ||
6883 | * The software always controls termination by setting TERM_CTL_SEL. | ||
6884 | * If TERM_CTL_SEL were set to 0, the hardware would set termination. | ||
6885 | */ | ||
6886 | asc_dvc->cfg->termination |= TERM_CTL_SEL; | ||
6887 | |||
6888 | switch (scsi_cfg1 & CABLE_DETECT) { | ||
6889 | /* TERM_CTL_H: on, TERM_CTL_L: on */ | ||
6890 | case 0x3: | ||
6891 | case 0x7: | ||
6892 | case 0xB: | ||
6893 | case 0xD: | ||
6894 | case 0xE: | ||
6895 | case 0xF: | ||
6896 | asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L); | ||
6897 | break; | ||
6898 | |||
6899 | /* TERM_CTL_H: on, TERM_CTL_L: off */ | ||
6900 | case 0x1: | ||
6901 | case 0x5: | ||
6902 | case 0x9: | ||
6903 | case 0xA: | ||
6904 | case 0xC: | ||
6905 | asc_dvc->cfg->termination |= TERM_CTL_H; | ||
6906 | break; | ||
6907 | |||
6908 | /* TERM_CTL_H: off, TERM_CTL_L: off */ | ||
6909 | case 0x2: | ||
6910 | case 0x6: | ||
6911 | break; | ||
6912 | } | ||
6913 | } | ||
6914 | |||
6915 | /* | ||
6916 | * Clear any set TERM_CTL_H and TERM_CTL_L bits. | ||
6917 | */ | ||
6918 | scsi_cfg1 &= ~TERM_CTL; | ||
6919 | |||
6920 | /* | ||
6921 | * Invert the TERM_CTL_H and TERM_CTL_L bits and then | ||
6922 | * set 'scsi_cfg1'. The TERM_POL bit does not need to be | ||
6923 | * referenced, because the hardware internally inverts | ||
6924 | * the Termination High and Low bits if TERM_POL is set. | ||
6925 | */ | ||
6926 | scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL)); | ||
6927 | |||
6928 | /* | ||
6929 | * Set SCSI_CFG1 Microcode Default Value | ||
6930 | * | ||
6931 | * Set filter value and possibly modified termination control | ||
6932 | * bits in the Microcode SCSI_CFG1 Register Value. | ||
6933 | * | ||
6934 | * The microcode will set the SCSI_CFG1 register using this value | ||
6935 | * after it is started below. | ||
6936 | */ | ||
6937 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, | ||
6938 | FLTR_DISABLE | scsi_cfg1); | ||
6939 | |||
6940 | /* | ||
6941 | * Set MEM_CFG Microcode Default Value | ||
6942 | * | ||
6943 | * The microcode will set the MEM_CFG register using this value | ||
6944 | * after it is started below. | ||
6945 | * | ||
6946 | * MEM_CFG may be accessed as a word or byte, but only bits 0-7 | ||
6947 | * are defined. | ||
6948 | * | ||
6949 | * ASC-3550 has 8KB internal memory. | ||
6950 | */ | ||
6951 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, | ||
6952 | BIOS_EN | RAM_SZ_8KB); | ||
6953 | |||
6954 | /* | ||
6955 | * Set SEL_MASK Microcode Default Value | ||
6956 | * | ||
6957 | * The microcode will set the SEL_MASK register using this value | ||
6958 | * after it is started below. | ||
6959 | */ | ||
6960 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, | ||
6961 | ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); | ||
6962 | |||
6963 | AdvBuildCarrierFreelist(asc_dvc); | ||
6964 | |||
6965 | /* | ||
6966 | * Set-up the Host->RISC Initiator Command Queue (ICQ). | ||
6967 | */ | ||
6968 | |||
6969 | if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) { | ||
6970 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; | ||
6971 | return ADV_ERROR; | ||
6972 | } | ||
6973 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
6974 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa)); | ||
6975 | |||
6976 | /* | ||
6977 | * The first command issued will be placed in the stopper carrier. | ||
6978 | */ | ||
6979 | asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
6980 | |||
6981 | /* | ||
6982 | * Set RISC ICQ physical address start value. | ||
6983 | */ | ||
6984 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa); | ||
6985 | |||
6986 | /* | ||
6987 | * Set-up the RISC->Host Initiator Response Queue (IRQ). | ||
6988 | */ | ||
6989 | if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) { | ||
6990 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; | ||
6991 | return ADV_ERROR; | ||
6992 | } | ||
6993 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
6994 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa)); | ||
6995 | |||
6996 | /* | ||
6997 | * The first command completed by the RISC will be placed in | ||
6998 | * the stopper. | ||
6999 | * | ||
7000 | * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is | ||
7001 | * completed the RISC will set the ASC_RQ_STOPPER bit. | ||
7002 | */ | ||
7003 | asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
7004 | |||
7005 | /* | ||
7006 | * Set RISC IRQ physical address start value. | ||
7007 | */ | ||
7008 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa); | ||
7009 | asc_dvc->carr_pending_cnt = 0; | ||
7010 | |||
7011 | AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES, | ||
7012 | (ADV_INTR_ENABLE_HOST_INTR | | ||
7013 | ADV_INTR_ENABLE_GLOBAL_INTR)); | ||
7014 | |||
7015 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word); | ||
7016 | AdvWriteWordRegister(iop_base, IOPW_PC, word); | ||
7017 | |||
7018 | /* finally, finally, gentlemen, start your engine */ | ||
7019 | AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN); | ||
7020 | |||
7021 | /* | ||
7022 | * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus | ||
7023 | * Resets should be performed. The RISC has to be running | ||
7024 | * to issue a SCSI Bus Reset. | ||
7025 | */ | ||
7026 | if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) { | ||
7027 | /* | ||
7028 | * If the BIOS Signature is present in memory, restore the | ||
7029 | * BIOS Handshake Configuration Table and do not perform | ||
7030 | * a SCSI Bus Reset. | ||
7031 | */ | ||
7032 | if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == | ||
7033 | 0x55AA) { | ||
7034 | /* | ||
7035 | * Restore per TID negotiated values. | ||
7036 | */ | ||
7037 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
7038 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
7039 | AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, | ||
7040 | tagqng_able); | ||
7041 | for (tid = 0; tid <= ADV_MAX_TID; tid++) { | ||
7042 | AdvWriteByteLram(iop_base, | ||
7043 | ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
7044 | max_cmd[tid]); | ||
7045 | } | ||
7046 | } else { | ||
7047 | if (AdvResetSB(asc_dvc) != ADV_TRUE) { | ||
7048 | warn_code = ASC_WARN_BUSRESET_ERROR; | ||
7049 | } | ||
7050 | } | ||
7051 | } | ||
7052 | |||
7053 | return warn_code; | ||
7750 | } | 7054 | } |
7751 | 7055 | ||
7752 | /* | 7056 | /* |
7753 | * asc_prt_target_stats() | 7057 | * Initialize the ASC-38C0800. |
7754 | * | 7058 | * |
7755 | * Note: no single line should be greater than ASC_PRTLINE_SIZE, | 7059 | * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. |
7756 | * cf. asc_prt_line(). | ||
7757 | * | 7060 | * |
7758 | * This is separated from asc_prt_board_stats because a full set | 7061 | * For a non-fatal error return a warning code. If there are no warnings |
7759 | * of targets will overflow ASC_PRTBUF_SIZE. | 7062 | * then 0 is returned. |
7760 | * | 7063 | * |
7761 | * Return the number of characters copied into 'cp'. No more than | 7064 | * Needed after initialization for error recovery. |
7762 | * 'cplen' characters will be copied to 'cp'. | ||
7763 | */ | 7065 | */ |
7764 | static int | 7066 | static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) |
7765 | asc_prt_target_stats(struct Scsi_Host *shost, int tgt_id, char *cp, int cplen) | ||
7766 | { | 7067 | { |
7767 | int leftlen; | 7068 | AdvPortAddr iop_base; |
7768 | int totlen; | 7069 | ushort warn_code; |
7769 | int len; | 7070 | int begin_addr; |
7770 | struct asc_stats *s; | 7071 | int end_addr; |
7771 | ushort chip_scsi_id; | 7072 | ushort code_sum; |
7772 | asc_board_t *boardp; | 7073 | int word; |
7773 | asc_queue_t *active; | 7074 | int i; |
7774 | asc_queue_t *waiting; | 7075 | ushort scsi_cfg1; |
7076 | uchar byte; | ||
7077 | uchar tid; | ||
7078 | ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */ | ||
7079 | ushort wdtr_able, sdtr_able, tagqng_able; | ||
7080 | uchar max_cmd[ADV_MAX_TID + 1]; | ||
7775 | 7081 | ||
7776 | leftlen = cplen; | 7082 | /* If there is already an error, don't continue. */ |
7777 | totlen = len = 0; | 7083 | if (asc_dvc->err_code != 0) |
7084 | return ADV_ERROR; | ||
7778 | 7085 | ||
7779 | boardp = ASC_BOARDP(shost); | 7086 | /* |
7780 | s = &boardp->asc_stats; | 7087 | * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800. |
7088 | */ | ||
7089 | if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) { | ||
7090 | asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE; | ||
7091 | return ADV_ERROR; | ||
7092 | } | ||
7781 | 7093 | ||
7782 | active = &ASC_BOARDP(shost)->active; | 7094 | warn_code = 0; |
7783 | waiting = &ASC_BOARDP(shost)->waiting; | 7095 | iop_base = asc_dvc->iop_base; |
7784 | 7096 | ||
7785 | if (ASC_NARROW_BOARD(boardp)) { | 7097 | /* |
7786 | chip_scsi_id = boardp->dvc_cfg.asc_dvc_cfg.chip_scsi_id; | 7098 | * Save the RISC memory BIOS region before writing the microcode. |
7787 | } else { | 7099 | * The BIOS may already be loaded and using its RISC LRAM region |
7788 | chip_scsi_id = boardp->dvc_var.adv_dvc_var.chip_scsi_id; | 7100 | * so its region must be saved and restored. |
7101 | * | ||
7102 | * Note: This code makes the assumption, which is currently true, | ||
7103 | * that a chip reset does not clear RISC LRAM. | ||
7104 | */ | ||
7105 | for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { | ||
7106 | AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), | ||
7107 | bios_mem[i]); | ||
7789 | } | 7108 | } |
7790 | 7109 | ||
7791 | if ((chip_scsi_id == tgt_id) || | 7110 | /* |
7792 | ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(tgt_id)) == 0)) { | 7111 | * Save current per TID negotiated values. |
7793 | return 0; | 7112 | */ |
7113 | AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
7114 | AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
7115 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | ||
7116 | for (tid = 0; tid <= ADV_MAX_TID; tid++) { | ||
7117 | AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
7118 | max_cmd[tid]); | ||
7794 | } | 7119 | } |
7795 | 7120 | ||
7796 | do { | 7121 | /* |
7797 | if (active->q_tot_cnt[tgt_id] > 0 | 7122 | * RAM BIST (RAM Built-In Self Test) |
7798 | || waiting->q_tot_cnt[tgt_id] > 0) { | 7123 | * |
7799 | len = asc_prt_line(cp, leftlen, " target %d\n", tgt_id); | 7124 | * Address : I/O base + offset 0x38h register (byte). |
7800 | ASC_PRT_NEXT(); | 7125 | * Function: Bit 7-6(RW) : RAM mode |
7126 | * Normal Mode : 0x00 | ||
7127 | * Pre-test Mode : 0x40 | ||
7128 | * RAM Test Mode : 0x80 | ||
7129 | * Bit 5 : unused | ||
7130 | * Bit 4(RO) : Done bit | ||
7131 | * Bit 3-0(RO) : Status | ||
7132 | * Host Error : 0x08 | ||
7133 | * Int_RAM Error : 0x04 | ||
7134 | * RISC Error : 0x02 | ||
7135 | * SCSI Error : 0x01 | ||
7136 | * No Error : 0x00 | ||
7137 | * | ||
7138 | * Note: RAM BIST code should be put right here, before loading the | ||
7139 | * microcode and after saving the RISC memory BIOS region. | ||
7140 | */ | ||
7801 | 7141 | ||
7802 | len = asc_prt_line(cp, leftlen, | 7142 | /* |
7803 | " active: cnt [cur %d, max %d, tot %u], time [min %d, max %d, avg %lu.%01lu]\n", | 7143 | * LRAM Pre-test |
7804 | active->q_cur_cnt[tgt_id], | 7144 | * |
7805 | active->q_max_cnt[tgt_id], | 7145 | * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds. |
7806 | active->q_tot_cnt[tgt_id], | 7146 | * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return |
7807 | active->q_min_tim[tgt_id], | 7147 | * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset |
7808 | active->q_max_tim[tgt_id], | 7148 | * to NORMAL_MODE, return an error too. |
7809 | (active->q_tot_cnt[tgt_id] == | 7149 | */ |
7810 | 0) ? 0 : (active-> | 7150 | for (i = 0; i < 2; i++) { |
7811 | q_tot_tim[tgt_id] / | 7151 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE); |
7812 | active-> | 7152 | mdelay(10); /* Wait for 10ms before reading back. */ |
7813 | q_tot_cnt[tgt_id]), | 7153 | byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); |
7814 | (active->q_tot_cnt[tgt_id] == | 7154 | if ((byte & RAM_TEST_DONE) == 0 |
7815 | 0) ? 0 : ASC_TENTHS(active-> | 7155 | || (byte & 0x0F) != PRE_TEST_VALUE) { |
7816 | q_tot_tim | 7156 | asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; |
7817 | [tgt_id], | 7157 | return ADV_ERROR; |
7818 | active-> | 7158 | } |
7819 | q_tot_cnt | ||
7820 | [tgt_id])); | ||
7821 | ASC_PRT_NEXT(); | ||
7822 | 7159 | ||
7823 | len = asc_prt_line(cp, leftlen, | 7160 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); |
7824 | " waiting: cnt [cur %d, max %d, tot %u], time [min %u, max %u, avg %lu.%01lu]\n", | 7161 | mdelay(10); /* Wait for 10ms before reading back. */ |
7825 | waiting->q_cur_cnt[tgt_id], | 7162 | if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) |
7826 | waiting->q_max_cnt[tgt_id], | 7163 | != NORMAL_VALUE) { |
7827 | waiting->q_tot_cnt[tgt_id], | 7164 | asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; |
7828 | waiting->q_min_tim[tgt_id], | 7165 | return ADV_ERROR; |
7829 | waiting->q_max_tim[tgt_id], | ||
7830 | (waiting->q_tot_cnt[tgt_id] == | ||
7831 | 0) ? 0 : (waiting-> | ||
7832 | q_tot_tim[tgt_id] / | ||
7833 | waiting-> | ||
7834 | q_tot_cnt[tgt_id]), | ||
7835 | (waiting->q_tot_cnt[tgt_id] == | ||
7836 | 0) ? 0 : ASC_TENTHS(waiting-> | ||
7837 | q_tot_tim | ||
7838 | [tgt_id], | ||
7839 | waiting-> | ||
7840 | q_tot_cnt | ||
7841 | [tgt_id])); | ||
7842 | ASC_PRT_NEXT(); | ||
7843 | } | 7166 | } |
7844 | } while (0); | 7167 | } |
7845 | 7168 | ||
7846 | return totlen; | 7169 | /* |
7847 | } | 7170 | * LRAM Test - It takes about 1.5 ms to run through the test. |
7848 | #endif /* CONFIG_PROC_FS */ | 7171 | * |
7849 | #endif /* ADVANSYS_STATS */ | 7172 | * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds. |
7173 | * If Done bit not set or Status not 0, save register byte, set the | ||
7174 | * err_code, and return an error. | ||
7175 | */ | ||
7176 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE); | ||
7177 | mdelay(10); /* Wait for 10ms before checking status. */ | ||
7850 | 7178 | ||
7851 | #ifdef ADVANSYS_DEBUG | 7179 | byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); |
7852 | /* | 7180 | if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) { |
7853 | * asc_prt_scsi_host() | 7181 | /* Get here if Done bit not set or Status not 0. */ |
7854 | */ | 7182 | asc_dvc->bist_err_code = byte; /* for BIOS display message */ |
7855 | static void asc_prt_scsi_host(struct Scsi_Host *s) | 7183 | asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST; |
7856 | { | 7184 | return ADV_ERROR; |
7857 | asc_board_t *boardp; | 7185 | } |
7858 | 7186 | ||
7859 | boardp = ASC_BOARDP(s); | 7187 | /* We need to reset back to normal mode after LRAM test passes. */ |
7188 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); | ||
7860 | 7189 | ||
7861 | printk("Scsi_Host at addr 0x%lx\n", (ulong)s); | 7190 | asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C0800_buf, |
7862 | printk(" host_busy %u, host_no %d, last_reset %d,\n", | 7191 | _adv_asc38C0800_size, ADV_38C0800_MEMSIZE, |
7863 | s->host_busy, s->host_no, (unsigned)s->last_reset); | 7192 | _adv_asc38C0800_chksum); |
7193 | if (asc_dvc->err_code) | ||
7194 | return ADV_ERROR; | ||
7864 | 7195 | ||
7865 | printk(" base 0x%lx, io_port 0x%lx, n_io_port %u, irq 0x%x,\n", | 7196 | /* |
7866 | (ulong)s->base, (ulong)s->io_port, s->n_io_port, s->irq); | 7197 | * Restore the RISC memory BIOS region. |
7198 | */ | ||
7199 | for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { | ||
7200 | AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), | ||
7201 | bios_mem[i]); | ||
7202 | } | ||
7867 | 7203 | ||
7868 | printk(" dma_channel %d, this_id %d, can_queue %d,\n", | 7204 | /* |
7869 | s->dma_channel, s->this_id, s->can_queue); | 7205 | * Calculate and write the microcode code checksum to the microcode |
7206 | * code checksum location ASC_MC_CODE_CHK_SUM (0x2C). | ||
7207 | */ | ||
7208 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr); | ||
7209 | AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr); | ||
7210 | code_sum = 0; | ||
7211 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr); | ||
7212 | for (word = begin_addr; word < end_addr; word += 2) { | ||
7213 | code_sum += AdvReadWordAutoIncLram(iop_base); | ||
7214 | } | ||
7215 | AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum); | ||
7870 | 7216 | ||
7871 | printk(" cmd_per_lun %d, sg_tablesize %d, unchecked_isa_dma %d\n", | 7217 | /* |
7872 | s->cmd_per_lun, s->sg_tablesize, s->unchecked_isa_dma); | 7218 | * Read microcode version and date. |
7219 | */ | ||
7220 | AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, | ||
7221 | asc_dvc->cfg->mcode_date); | ||
7222 | AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, | ||
7223 | asc_dvc->cfg->mcode_version); | ||
7873 | 7224 | ||
7874 | if (ASC_NARROW_BOARD(boardp)) { | 7225 | /* |
7875 | asc_prt_asc_dvc_var(&ASC_BOARDP(s)->dvc_var.asc_dvc_var); | 7226 | * Set the chip type to indicate the ASC38C0800. |
7876 | asc_prt_asc_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.asc_dvc_cfg); | 7227 | */ |
7877 | } else { | 7228 | AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800); |
7878 | asc_prt_adv_dvc_var(&ASC_BOARDP(s)->dvc_var.adv_dvc_var); | 7229 | |
7879 | asc_prt_adv_dvc_cfg(&ASC_BOARDP(s)->dvc_cfg.adv_dvc_cfg); | 7230 | /* |
7231 | * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register. | ||
7232 | * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current | ||
7233 | * cable detection and then we are able to read C_DET[3:0]. | ||
7234 | * | ||
7235 | * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1 | ||
7236 | * Microcode Default Value' section below. | ||
7237 | */ | ||
7238 | scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); | ||
7239 | AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, | ||
7240 | scsi_cfg1 | DIS_TERM_DRV); | ||
7241 | |||
7242 | /* | ||
7243 | * If the PCI Configuration Command Register "Parity Error Response | ||
7244 | * Control" Bit was clear (0), then set the microcode variable | ||
7245 | * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode | ||
7246 | * to ignore DMA parity errors. | ||
7247 | */ | ||
7248 | if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) { | ||
7249 | AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
7250 | word |= CONTROL_FLAG_IGNORE_PERR; | ||
7251 | AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
7880 | } | 7252 | } |
7881 | } | ||
7882 | 7253 | ||
7883 | /* | 7254 | /* |
7884 | * asc_prt_scsi_cmnd() | 7255 | * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2] |
7885 | */ | 7256 | * bits for the default FIFO threshold. |
7886 | static void asc_prt_scsi_cmnd(struct scsi_cmnd *s) | 7257 | * |
7887 | { | 7258 | * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes. |
7888 | printk("struct scsi_cmnd at addr 0x%lx\n", (ulong)s); | 7259 | * |
7260 | * For DMA Errata #4 set the BC_THRESH_ENB bit. | ||
7261 | */ | ||
7262 | AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0, | ||
7263 | BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | | ||
7264 | READ_CMD_MRM); | ||
7889 | 7265 | ||
7890 | printk(" host 0x%lx, device 0x%lx, target %u, lun %u, channel %u,\n", | 7266 | /* |
7891 | (ulong)s->device->host, (ulong)s->device, s->device->id, | 7267 | * Microcode operating variables for WDTR, SDTR, and command tag |
7892 | s->device->lun, s->device->channel); | 7268 | * queuing will be set in slave_configure() based on what a |
7269 | * device reports it is capable of in Inquiry byte 7. | ||
7270 | * | ||
7271 | * If SCSI Bus Resets have been disabled, then directly set | ||
7272 | * SDTR and WDTR from the EEPROM configuration. This will allow | ||
7273 | * the BIOS and warm boot to work without a SCSI bus hang on | ||
7274 | * the Inquiry caused by host and target mismatched DTR values. | ||
7275 | * Without the SCSI Bus Reset, before an Inquiry a device can't | ||
7276 | * be assumed to be in Asynchronous, Narrow mode. | ||
7277 | */ | ||
7278 | if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) { | ||
7279 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, | ||
7280 | asc_dvc->wdtr_able); | ||
7281 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, | ||
7282 | asc_dvc->sdtr_able); | ||
7283 | } | ||
7893 | 7284 | ||
7894 | asc_prt_hex(" CDB", s->cmnd, s->cmd_len); | 7285 | /* |
7286 | * Set microcode operating variables for DISC and SDTR_SPEED1, | ||
7287 | * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM | ||
7288 | * configuration values. | ||
7289 | * | ||
7290 | * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, | ||
7291 | * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them | ||
7292 | * without determining here whether the device supports SDTR. | ||
7293 | */ | ||
7294 | AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, | ||
7295 | asc_dvc->cfg->disc_enable); | ||
7296 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1); | ||
7297 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2); | ||
7298 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3); | ||
7299 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4); | ||
7895 | 7300 | ||
7896 | printk("sc_data_direction %u, resid %d\n", | 7301 | /* |
7897 | s->sc_data_direction, s->resid); | 7302 | * Set SCSI_CFG0 Microcode Default Value. |
7303 | * | ||
7304 | * The microcode will set the SCSI_CFG0 register using this value | ||
7305 | * after it is started below. | ||
7306 | */ | ||
7307 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0, | ||
7308 | PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN | | ||
7309 | asc_dvc->chip_scsi_id); | ||
7898 | 7310 | ||
7899 | printk(" use_sg %u, sglist_len %u\n", s->use_sg, s->sglist_len); | 7311 | /* |
7312 | * Determine SCSI_CFG1 Microcode Default Value. | ||
7313 | * | ||
7314 | * The microcode will set the SCSI_CFG1 register using this value | ||
7315 | * after it is started below. | ||
7316 | */ | ||
7900 | 7317 | ||
7901 | printk(" serial_number 0x%x, retries %d, allowed %d\n", | 7318 | /* Read current SCSI_CFG1 Register value. */ |
7902 | (unsigned)s->serial_number, s->retries, s->allowed); | 7319 | scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); |
7903 | 7320 | ||
7904 | printk(" timeout_per_command %d\n", s->timeout_per_command); | 7321 | /* |
7322 | * If the internal narrow cable is reversed all of the SCSI_CTRL | ||
7323 | * register signals will be set. Check for and return an error if | ||
7324 | * this condition is found. | ||
7325 | */ | ||
7326 | if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) { | ||
7327 | asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE; | ||
7328 | return ADV_ERROR; | ||
7329 | } | ||
7905 | 7330 | ||
7906 | printk | 7331 | /* |
7907 | (" scsi_done 0x%lx, done 0x%lx, host_scribble 0x%lx, result 0x%x\n", | 7332 | * All kind of combinations of devices attached to one of four |
7908 | (ulong)s->scsi_done, (ulong)s->done, (ulong)s->host_scribble, | 7333 | * connectors are acceptable except HVD device attached. For example, |
7909 | s->result); | 7334 | * LVD device can be attached to SE connector while SE device attached |
7335 | * to LVD connector. If LVD device attached to SE connector, it only | ||
7336 | * runs up to Ultra speed. | ||
7337 | * | ||
7338 | * If an HVD device is attached to one of LVD connectors, return an | ||
7339 | * error. However, there is no way to detect HVD device attached to | ||
7340 | * SE connectors. | ||
7341 | */ | ||
7342 | if (scsi_cfg1 & HVD) { | ||
7343 | asc_dvc->err_code = ASC_IERR_HVD_DEVICE; | ||
7344 | return ADV_ERROR; | ||
7345 | } | ||
7910 | 7346 | ||
7911 | printk(" tag %u, pid %u\n", (unsigned)s->tag, (unsigned)s->pid); | 7347 | /* |
7912 | } | 7348 | * If either SE or LVD automatic termination control is enabled, then |
7349 | * set the termination value based on a table listed in a_condor.h. | ||
7350 | * | ||
7351 | * If manual termination was specified with an EEPROM setting then | ||
7352 | * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready | ||
7353 | * to be 'ored' into SCSI_CFG1. | ||
7354 | */ | ||
7355 | if ((asc_dvc->cfg->termination & TERM_SE) == 0) { | ||
7356 | /* SE automatic termination control is enabled. */ | ||
7357 | switch (scsi_cfg1 & C_DET_SE) { | ||
7358 | /* TERM_SE_HI: on, TERM_SE_LO: on */ | ||
7359 | case 0x1: | ||
7360 | case 0x2: | ||
7361 | case 0x3: | ||
7362 | asc_dvc->cfg->termination |= TERM_SE; | ||
7363 | break; | ||
7913 | 7364 | ||
7914 | /* | 7365 | /* TERM_SE_HI: on, TERM_SE_LO: off */ |
7915 | * asc_prt_asc_dvc_var() | 7366 | case 0x0: |
7916 | */ | 7367 | asc_dvc->cfg->termination |= TERM_SE_HI; |
7917 | static void asc_prt_asc_dvc_var(ASC_DVC_VAR *h) | 7368 | break; |
7918 | { | 7369 | } |
7919 | printk("ASC_DVC_VAR at addr 0x%lx\n", (ulong)h); | 7370 | } |
7920 | 7371 | ||
7921 | printk | 7372 | if ((asc_dvc->cfg->termination & TERM_LVD) == 0) { |
7922 | (" iop_base 0x%x, err_code 0x%x, dvc_cntl 0x%x, bug_fix_cntl %d,\n", | 7373 | /* LVD automatic termination control is enabled. */ |
7923 | h->iop_base, h->err_code, h->dvc_cntl, h->bug_fix_cntl); | 7374 | switch (scsi_cfg1 & C_DET_LVD) { |
7375 | /* TERM_LVD_HI: on, TERM_LVD_LO: on */ | ||
7376 | case 0x4: | ||
7377 | case 0x8: | ||
7378 | case 0xC: | ||
7379 | asc_dvc->cfg->termination |= TERM_LVD; | ||
7380 | break; | ||
7924 | 7381 | ||
7925 | printk | 7382 | /* TERM_LVD_HI: off, TERM_LVD_LO: off */ |
7926 | (" bus_type %d, isr_callback 0x%lx, exe_callback 0x%lx, init_sdtr 0x%x,\n", | 7383 | case 0x0: |
7927 | h->bus_type, (ulong)h->isr_callback, (ulong)h->exe_callback, | 7384 | break; |
7928 | (unsigned)h->init_sdtr); | 7385 | } |
7386 | } | ||
7929 | 7387 | ||
7930 | printk | 7388 | /* |
7931 | (" sdtr_done 0x%x, use_tagged_qng 0x%x, unit_not_ready 0x%x, chip_no 0x%x,\n", | 7389 | * Clear any set TERM_SE and TERM_LVD bits. |
7932 | (unsigned)h->sdtr_done, (unsigned)h->use_tagged_qng, | 7390 | */ |
7933 | (unsigned)h->unit_not_ready, (unsigned)h->chip_no); | 7391 | scsi_cfg1 &= (~TERM_SE & ~TERM_LVD); |
7934 | 7392 | ||
7935 | printk | 7393 | /* |
7936 | (" queue_full_or_busy 0x%x, start_motor 0x%x, scsi_reset_wait %u,\n", | 7394 | * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'. |
7937 | (unsigned)h->queue_full_or_busy, (unsigned)h->start_motor, | 7395 | */ |
7938 | (unsigned)h->scsi_reset_wait); | 7396 | scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0); |
7939 | 7397 | ||
7940 | printk | 7398 | /* |
7941 | (" is_in_int %u, max_total_qng %u, cur_total_qng %u, in_critical_cnt %u,\n", | 7399 | * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE |
7942 | (unsigned)h->is_in_int, (unsigned)h->max_total_qng, | 7400 | * bits and set possibly modified termination control bits in the |
7943 | (unsigned)h->cur_total_qng, (unsigned)h->in_critical_cnt); | 7401 | * Microcode SCSI_CFG1 Register Value. |
7402 | */ | ||
7403 | scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE); | ||
7944 | 7404 | ||
7945 | printk | 7405 | /* |
7946 | (" last_q_shortage %u, init_state 0x%x, no_scam 0x%x, pci_fix_asyn_xfer 0x%x,\n", | 7406 | * Set SCSI_CFG1 Microcode Default Value |
7947 | (unsigned)h->last_q_shortage, (unsigned)h->init_state, | 7407 | * |
7948 | (unsigned)h->no_scam, (unsigned)h->pci_fix_asyn_xfer); | 7408 | * Set possibly modified termination control and reset DIS_TERM_DRV |
7409 | * bits in the Microcode SCSI_CFG1 Register Value. | ||
7410 | * | ||
7411 | * The microcode will set the SCSI_CFG1 register using this value | ||
7412 | * after it is started below. | ||
7413 | */ | ||
7414 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1); | ||
7949 | 7415 | ||
7950 | printk(" cfg 0x%lx, irq_no 0x%x\n", (ulong)h->cfg, (unsigned)h->irq_no); | 7416 | /* |
7951 | } | 7417 | * Set MEM_CFG Microcode Default Value |
7418 | * | ||
7419 | * The microcode will set the MEM_CFG register using this value | ||
7420 | * after it is started below. | ||
7421 | * | ||
7422 | * MEM_CFG may be accessed as a word or byte, but only bits 0-7 | ||
7423 | * are defined. | ||
7424 | * | ||
7425 | * ASC-38C0800 has 16KB internal memory. | ||
7426 | */ | ||
7427 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, | ||
7428 | BIOS_EN | RAM_SZ_16KB); | ||
7952 | 7429 | ||
7953 | /* | 7430 | /* |
7954 | * asc_prt_asc_dvc_cfg() | 7431 | * Set SEL_MASK Microcode Default Value |
7955 | */ | 7432 | * |
7956 | static void asc_prt_asc_dvc_cfg(ASC_DVC_CFG *h) | 7433 | * The microcode will set the SEL_MASK register using this value |
7957 | { | 7434 | * after it is started below. |
7958 | printk("ASC_DVC_CFG at addr 0x%lx\n", (ulong)h); | 7435 | */ |
7436 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, | ||
7437 | ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); | ||
7959 | 7438 | ||
7960 | printk(" can_tagged_qng 0x%x, cmd_qng_enabled 0x%x,\n", | 7439 | AdvBuildCarrierFreelist(asc_dvc); |
7961 | h->can_tagged_qng, h->cmd_qng_enabled); | ||
7962 | printk(" disc_enable 0x%x, sdtr_enable 0x%x,\n", | ||
7963 | h->disc_enable, h->sdtr_enable); | ||
7964 | 7440 | ||
7965 | printk | 7441 | /* |
7966 | (" chip_scsi_id %d, isa_dma_speed %d, isa_dma_channel %d, chip_version %d,\n", | 7442 | * Set-up the Host->RISC Initiator Command Queue (ICQ). |
7967 | h->chip_scsi_id, h->isa_dma_speed, h->isa_dma_channel, | 7443 | */ |
7968 | h->chip_version); | ||
7969 | 7444 | ||
7970 | printk | 7445 | if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) { |
7971 | (" pci_device_id %d, lib_serial_no %u, lib_version %u, mcode_date 0x%x,\n", | 7446 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; |
7972 | to_pci_dev(h->dev)->device, h->lib_serial_no, h->lib_version, | 7447 | return ADV_ERROR; |
7973 | h->mcode_date); | 7448 | } |
7449 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
7450 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa)); | ||
7974 | 7451 | ||
7975 | printk(" mcode_version %d, overrun_buf 0x%lx\n", | 7452 | /* |
7976 | h->mcode_version, (ulong)h->overrun_buf); | 7453 | * The first command issued will be placed in the stopper carrier. |
7454 | */ | ||
7455 | asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
7456 | |||
7457 | /* | ||
7458 | * Set RISC ICQ physical address start value. | ||
7459 | * carr_pa is LE, must be native before write | ||
7460 | */ | ||
7461 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa); | ||
7462 | |||
7463 | /* | ||
7464 | * Set-up the RISC->Host Initiator Response Queue (IRQ). | ||
7465 | */ | ||
7466 | if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) { | ||
7467 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; | ||
7468 | return ADV_ERROR; | ||
7469 | } | ||
7470 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
7471 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa)); | ||
7472 | |||
7473 | /* | ||
7474 | * The first command completed by the RISC will be placed in | ||
7475 | * the stopper. | ||
7476 | * | ||
7477 | * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is | ||
7478 | * completed the RISC will set the ASC_RQ_STOPPER bit. | ||
7479 | */ | ||
7480 | asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
7481 | |||
7482 | /* | ||
7483 | * Set RISC IRQ physical address start value. | ||
7484 | * | ||
7485 | * carr_pa is LE, must be native before write * | ||
7486 | */ | ||
7487 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa); | ||
7488 | asc_dvc->carr_pending_cnt = 0; | ||
7489 | |||
7490 | AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES, | ||
7491 | (ADV_INTR_ENABLE_HOST_INTR | | ||
7492 | ADV_INTR_ENABLE_GLOBAL_INTR)); | ||
7493 | |||
7494 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word); | ||
7495 | AdvWriteWordRegister(iop_base, IOPW_PC, word); | ||
7496 | |||
7497 | /* finally, finally, gentlemen, start your engine */ | ||
7498 | AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN); | ||
7499 | |||
7500 | /* | ||
7501 | * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus | ||
7502 | * Resets should be performed. The RISC has to be running | ||
7503 | * to issue a SCSI Bus Reset. | ||
7504 | */ | ||
7505 | if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) { | ||
7506 | /* | ||
7507 | * If the BIOS Signature is present in memory, restore the | ||
7508 | * BIOS Handshake Configuration Table and do not perform | ||
7509 | * a SCSI Bus Reset. | ||
7510 | */ | ||
7511 | if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == | ||
7512 | 0x55AA) { | ||
7513 | /* | ||
7514 | * Restore per TID negotiated values. | ||
7515 | */ | ||
7516 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
7517 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
7518 | AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, | ||
7519 | tagqng_able); | ||
7520 | for (tid = 0; tid <= ADV_MAX_TID; tid++) { | ||
7521 | AdvWriteByteLram(iop_base, | ||
7522 | ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
7523 | max_cmd[tid]); | ||
7524 | } | ||
7525 | } else { | ||
7526 | if (AdvResetSB(asc_dvc) != ADV_TRUE) { | ||
7527 | warn_code = ASC_WARN_BUSRESET_ERROR; | ||
7528 | } | ||
7529 | } | ||
7530 | } | ||
7531 | |||
7532 | return warn_code; | ||
7977 | } | 7533 | } |
7978 | 7534 | ||
7979 | /* | 7535 | /* |
7980 | * asc_prt_asc_scsi_q() | 7536 | * Initialize the ASC-38C1600. |
7537 | * | ||
7538 | * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR. | ||
7539 | * | ||
7540 | * For a non-fatal error return a warning code. If there are no warnings | ||
7541 | * then 0 is returned. | ||
7542 | * | ||
7543 | * Needed after initialization for error recovery. | ||
7981 | */ | 7544 | */ |
7982 | static void asc_prt_asc_scsi_q(ASC_SCSI_Q *q) | 7545 | static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) |
7983 | { | 7546 | { |
7984 | ASC_SG_HEAD *sgp; | 7547 | AdvPortAddr iop_base; |
7548 | ushort warn_code; | ||
7549 | int begin_addr; | ||
7550 | int end_addr; | ||
7551 | ushort code_sum; | ||
7552 | long word; | ||
7985 | int i; | 7553 | int i; |
7554 | ushort scsi_cfg1; | ||
7555 | uchar byte; | ||
7556 | uchar tid; | ||
7557 | ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */ | ||
7558 | ushort wdtr_able, sdtr_able, ppr_able, tagqng_able; | ||
7559 | uchar max_cmd[ASC_MAX_TID + 1]; | ||
7986 | 7560 | ||
7987 | printk("ASC_SCSI_Q at addr 0x%lx\n", (ulong)q); | 7561 | /* If there is already an error, don't continue. */ |
7562 | if (asc_dvc->err_code != 0) { | ||
7563 | return ADV_ERROR; | ||
7564 | } | ||
7988 | 7565 | ||
7989 | printk | 7566 | /* |
7990 | (" target_ix 0x%x, target_lun %u, srb_ptr 0x%lx, tag_code 0x%x,\n", | 7567 | * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600. |
7991 | q->q2.target_ix, q->q1.target_lun, (ulong)q->q2.srb_ptr, | 7568 | */ |
7992 | q->q2.tag_code); | 7569 | if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) { |
7570 | asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE; | ||
7571 | return ADV_ERROR; | ||
7572 | } | ||
7993 | 7573 | ||
7994 | printk | 7574 | warn_code = 0; |
7995 | (" data_addr 0x%lx, data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n", | 7575 | iop_base = asc_dvc->iop_base; |
7996 | (ulong)le32_to_cpu(q->q1.data_addr), | ||
7997 | (ulong)le32_to_cpu(q->q1.data_cnt), | ||
7998 | (ulong)le32_to_cpu(q->q1.sense_addr), q->q1.sense_len); | ||
7999 | 7576 | ||
8000 | printk(" cdbptr 0x%lx, cdb_len %u, sg_head 0x%lx, sg_queue_cnt %u\n", | 7577 | /* |
8001 | (ulong)q->cdbptr, q->q2.cdb_len, | 7578 | * Save the RISC memory BIOS region before writing the microcode. |
8002 | (ulong)q->sg_head, q->q1.sg_queue_cnt); | 7579 | * The BIOS may already be loaded and using its RISC LRAM region |
7580 | * so its region must be saved and restored. | ||
7581 | * | ||
7582 | * Note: This code makes the assumption, which is currently true, | ||
7583 | * that a chip reset does not clear RISC LRAM. | ||
7584 | */ | ||
7585 | for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { | ||
7586 | AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), | ||
7587 | bios_mem[i]); | ||
7588 | } | ||
8003 | 7589 | ||
8004 | if (q->sg_head) { | 7590 | /* |
8005 | sgp = q->sg_head; | 7591 | * Save current per TID negotiated values. |
8006 | printk("ASC_SG_HEAD at addr 0x%lx\n", (ulong)sgp); | 7592 | */ |
8007 | printk(" entry_cnt %u, queue_cnt %u\n", sgp->entry_cnt, | 7593 | AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); |
8008 | sgp->queue_cnt); | 7594 | AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); |
8009 | for (i = 0; i < sgp->entry_cnt; i++) { | 7595 | AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); |
8010 | printk(" [%u]: addr 0x%lx, bytes %lu\n", | 7596 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); |
8011 | i, (ulong)le32_to_cpu(sgp->sg_list[i].addr), | 7597 | for (tid = 0; tid <= ASC_MAX_TID; tid++) { |
8012 | (ulong)le32_to_cpu(sgp->sg_list[i].bytes)); | 7598 | AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, |
7599 | max_cmd[tid]); | ||
7600 | } | ||
7601 | |||
7602 | /* | ||
7603 | * RAM BIST (Built-In Self Test) | ||
7604 | * | ||
7605 | * Address : I/O base + offset 0x38h register (byte). | ||
7606 | * Function: Bit 7-6(RW) : RAM mode | ||
7607 | * Normal Mode : 0x00 | ||
7608 | * Pre-test Mode : 0x40 | ||
7609 | * RAM Test Mode : 0x80 | ||
7610 | * Bit 5 : unused | ||
7611 | * Bit 4(RO) : Done bit | ||
7612 | * Bit 3-0(RO) : Status | ||
7613 | * Host Error : 0x08 | ||
7614 | * Int_RAM Error : 0x04 | ||
7615 | * RISC Error : 0x02 | ||
7616 | * SCSI Error : 0x01 | ||
7617 | * No Error : 0x00 | ||
7618 | * | ||
7619 | * Note: RAM BIST code should be put right here, before loading the | ||
7620 | * microcode and after saving the RISC memory BIOS region. | ||
7621 | */ | ||
7622 | |||
7623 | /* | ||
7624 | * LRAM Pre-test | ||
7625 | * | ||
7626 | * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds. | ||
7627 | * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return | ||
7628 | * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset | ||
7629 | * to NORMAL_MODE, return an error too. | ||
7630 | */ | ||
7631 | for (i = 0; i < 2; i++) { | ||
7632 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE); | ||
7633 | mdelay(10); /* Wait for 10ms before reading back. */ | ||
7634 | byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); | ||
7635 | if ((byte & RAM_TEST_DONE) == 0 | ||
7636 | || (byte & 0x0F) != PRE_TEST_VALUE) { | ||
7637 | asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; | ||
7638 | return ADV_ERROR; | ||
8013 | } | 7639 | } |
8014 | 7640 | ||
7641 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); | ||
7642 | mdelay(10); /* Wait for 10ms before reading back. */ | ||
7643 | if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) | ||
7644 | != NORMAL_VALUE) { | ||
7645 | asc_dvc->err_code = ASC_IERR_BIST_PRE_TEST; | ||
7646 | return ADV_ERROR; | ||
7647 | } | ||
8015 | } | 7648 | } |
8016 | } | ||
8017 | 7649 | ||
8018 | /* | 7650 | /* |
8019 | * asc_prt_asc_qdone_info() | 7651 | * LRAM Test - It takes about 1.5 ms to run through the test. |
8020 | */ | 7652 | * |
8021 | static void asc_prt_asc_qdone_info(ASC_QDONE_INFO *q) | 7653 | * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds. |
8022 | { | 7654 | * If Done bit not set or Status not 0, save register byte, set the |
8023 | printk("ASC_QDONE_INFO at addr 0x%lx\n", (ulong)q); | 7655 | * err_code, and return an error. |
8024 | printk(" srb_ptr 0x%lx, target_ix %u, cdb_len %u, tag_code %u,\n", | 7656 | */ |
8025 | (ulong)q->d2.srb_ptr, q->d2.target_ix, q->d2.cdb_len, | 7657 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE); |
8026 | q->d2.tag_code); | 7658 | mdelay(10); /* Wait for 10ms before checking status. */ |
8027 | printk | ||
8028 | (" done_stat 0x%x, host_stat 0x%x, scsi_stat 0x%x, scsi_msg 0x%x\n", | ||
8029 | q->d3.done_stat, q->d3.host_stat, q->d3.scsi_stat, q->d3.scsi_msg); | ||
8030 | } | ||
8031 | 7659 | ||
8032 | /* | 7660 | byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); |
8033 | * asc_prt_adv_dvc_var() | 7661 | if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) { |
8034 | * | 7662 | /* Get here if Done bit not set or Status not 0. */ |
8035 | * Display an ADV_DVC_VAR structure. | 7663 | asc_dvc->bist_err_code = byte; /* for BIOS display message */ |
8036 | */ | 7664 | asc_dvc->err_code = ASC_IERR_BIST_RAM_TEST; |
8037 | static void asc_prt_adv_dvc_var(ADV_DVC_VAR *h) | 7665 | return ADV_ERROR; |
8038 | { | 7666 | } |
8039 | printk(" ADV_DVC_VAR at addr 0x%lx\n", (ulong)h); | ||
8040 | 7667 | ||
8041 | printk(" iop_base 0x%lx, err_code 0x%x, ultra_able 0x%x\n", | 7668 | /* We need to reset back to normal mode after LRAM test passes. */ |
8042 | (ulong)h->iop_base, h->err_code, (unsigned)h->ultra_able); | 7669 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); |
8043 | 7670 | ||
8044 | printk(" isr_callback 0x%lx, sdtr_able 0x%x, wdtr_able 0x%x\n", | 7671 | asc_dvc->err_code = AdvLoadMicrocode(iop_base, _adv_asc38C1600_buf, |
8045 | (ulong)h->isr_callback, (unsigned)h->sdtr_able, | 7672 | _adv_asc38C1600_size, ADV_38C1600_MEMSIZE, |
8046 | (unsigned)h->wdtr_able); | 7673 | _adv_asc38C1600_chksum); |
7674 | if (asc_dvc->err_code) | ||
7675 | return ADV_ERROR; | ||
8047 | 7676 | ||
8048 | printk(" start_motor 0x%x, scsi_reset_wait 0x%x, irq_no 0x%x,\n", | 7677 | /* |
8049 | (unsigned)h->start_motor, | 7678 | * Restore the RISC memory BIOS region. |
8050 | (unsigned)h->scsi_reset_wait, (unsigned)h->irq_no); | 7679 | */ |
7680 | for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { | ||
7681 | AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), | ||
7682 | bios_mem[i]); | ||
7683 | } | ||
8051 | 7684 | ||
8052 | printk(" max_host_qng %u, max_dvc_qng %u, carr_freelist 0x%lxn\n", | 7685 | /* |
8053 | (unsigned)h->max_host_qng, (unsigned)h->max_dvc_qng, | 7686 | * Calculate and write the microcode code checksum to the microcode |
8054 | (ulong)h->carr_freelist); | 7687 | * code checksum location ASC_MC_CODE_CHK_SUM (0x2C). |
7688 | */ | ||
7689 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr); | ||
7690 | AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr); | ||
7691 | code_sum = 0; | ||
7692 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr); | ||
7693 | for (word = begin_addr; word < end_addr; word += 2) { | ||
7694 | code_sum += AdvReadWordAutoIncLram(iop_base); | ||
7695 | } | ||
7696 | AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum); | ||
8055 | 7697 | ||
8056 | printk(" icq_sp 0x%lx, irq_sp 0x%lx\n", | 7698 | /* |
8057 | (ulong)h->icq_sp, (ulong)h->irq_sp); | 7699 | * Read microcode version and date. |
7700 | */ | ||
7701 | AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, | ||
7702 | asc_dvc->cfg->mcode_date); | ||
7703 | AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, | ||
7704 | asc_dvc->cfg->mcode_version); | ||
8058 | 7705 | ||
8059 | printk(" no_scam 0x%x, tagqng_able 0x%x\n", | 7706 | /* |
8060 | (unsigned)h->no_scam, (unsigned)h->tagqng_able); | 7707 | * Set the chip type to indicate the ASC38C1600. |
7708 | */ | ||
7709 | AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600); | ||
8061 | 7710 | ||
8062 | printk(" chip_scsi_id 0x%x, cfg 0x%lx\n", | 7711 | /* |
8063 | (unsigned)h->chip_scsi_id, (ulong)h->cfg); | 7712 | * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register. |
8064 | } | 7713 | * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current |
7714 | * cable detection and then we are able to read C_DET[3:0]. | ||
7715 | * | ||
7716 | * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1 | ||
7717 | * Microcode Default Value' section below. | ||
7718 | */ | ||
7719 | scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); | ||
7720 | AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, | ||
7721 | scsi_cfg1 | DIS_TERM_DRV); | ||
8065 | 7722 | ||
8066 | /* | 7723 | /* |
8067 | * asc_prt_adv_dvc_cfg() | 7724 | * If the PCI Configuration Command Register "Parity Error Response |
8068 | * | 7725 | * Control" Bit was clear (0), then set the microcode variable |
8069 | * Display an ADV_DVC_CFG structure. | 7726 | * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode |
8070 | */ | 7727 | * to ignore DMA parity errors. |
8071 | static void asc_prt_adv_dvc_cfg(ADV_DVC_CFG *h) | 7728 | */ |
8072 | { | 7729 | if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) { |
8073 | printk(" ADV_DVC_CFG at addr 0x%lx\n", (ulong)h); | 7730 | AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); |
7731 | word |= CONTROL_FLAG_IGNORE_PERR; | ||
7732 | AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
7733 | } | ||
8074 | 7734 | ||
8075 | printk(" disc_enable 0x%x, termination 0x%x\n", | 7735 | /* |
8076 | h->disc_enable, h->termination); | 7736 | * If the BIOS control flag AIPP (Asynchronous Information |
7737 | * Phase Protection) disable bit is not set, then set the firmware | ||
7738 | * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable | ||
7739 | * AIPP checking and encoding. | ||
7740 | */ | ||
7741 | if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) { | ||
7742 | AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
7743 | word |= CONTROL_FLAG_ENABLE_AIPP; | ||
7744 | AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
7745 | } | ||
8077 | 7746 | ||
8078 | printk(" chip_version 0x%x, mcode_date 0x%x\n", | 7747 | /* |
8079 | h->chip_version, h->mcode_date); | 7748 | * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4], |
7749 | * and START_CTL_TH [3:2]. | ||
7750 | */ | ||
7751 | AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0, | ||
7752 | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM); | ||
8080 | 7753 | ||
8081 | printk(" mcode_version 0x%x, pci_device_id 0x%x, lib_version %u\n", | 7754 | /* |
8082 | h->mcode_version, to_pci_dev(h->dev)->device, h->lib_version); | 7755 | * Microcode operating variables for WDTR, SDTR, and command tag |
7756 | * queuing will be set in slave_configure() based on what a | ||
7757 | * device reports it is capable of in Inquiry byte 7. | ||
7758 | * | ||
7759 | * If SCSI Bus Resets have been disabled, then directly set | ||
7760 | * SDTR and WDTR from the EEPROM configuration. This will allow | ||
7761 | * the BIOS and warm boot to work without a SCSI bus hang on | ||
7762 | * the Inquiry caused by host and target mismatched DTR values. | ||
7763 | * Without the SCSI Bus Reset, before an Inquiry a device can't | ||
7764 | * be assumed to be in Asynchronous, Narrow mode. | ||
7765 | */ | ||
7766 | if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) { | ||
7767 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, | ||
7768 | asc_dvc->wdtr_able); | ||
7769 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, | ||
7770 | asc_dvc->sdtr_able); | ||
7771 | } | ||
8083 | 7772 | ||
8084 | printk(" control_flag 0x%x, pci_slot_info 0x%x\n", | 7773 | /* |
8085 | h->control_flag, h->pci_slot_info); | 7774 | * Set microcode operating variables for DISC and SDTR_SPEED1, |
8086 | } | 7775 | * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM |
7776 | * configuration values. | ||
7777 | * | ||
7778 | * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, | ||
7779 | * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them | ||
7780 | * without determining here whether the device supports SDTR. | ||
7781 | */ | ||
7782 | AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, | ||
7783 | asc_dvc->cfg->disc_enable); | ||
7784 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1); | ||
7785 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2); | ||
7786 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3); | ||
7787 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4); | ||
8087 | 7788 | ||
8088 | /* | 7789 | /* |
8089 | * asc_prt_adv_scsi_req_q() | 7790 | * Set SCSI_CFG0 Microcode Default Value. |
8090 | * | 7791 | * |
8091 | * Display an ADV_SCSI_REQ_Q structure. | 7792 | * The microcode will set the SCSI_CFG0 register using this value |
8092 | */ | 7793 | * after it is started below. |
8093 | static void asc_prt_adv_scsi_req_q(ADV_SCSI_REQ_Q *q) | 7794 | */ |
8094 | { | 7795 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0, |
8095 | int sg_blk_cnt; | 7796 | PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN | |
8096 | struct asc_sg_block *sg_ptr; | 7797 | asc_dvc->chip_scsi_id); |
8097 | 7798 | ||
8098 | printk("ADV_SCSI_REQ_Q at addr 0x%lx\n", (ulong)q); | 7799 | /* |
7800 | * Calculate SCSI_CFG1 Microcode Default Value. | ||
7801 | * | ||
7802 | * The microcode will set the SCSI_CFG1 register using this value | ||
7803 | * after it is started below. | ||
7804 | * | ||
7805 | * Each ASC-38C1600 function has only two cable detect bits. | ||
7806 | * The bus mode override bits are in IOPB_SOFT_OVER_WR. | ||
7807 | */ | ||
7808 | scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); | ||
8099 | 7809 | ||
8100 | printk(" target_id %u, target_lun %u, srb_ptr 0x%lx, a_flag 0x%x\n", | 7810 | /* |
8101 | q->target_id, q->target_lun, (ulong)q->srb_ptr, q->a_flag); | 7811 | * If the cable is reversed all of the SCSI_CTRL register signals |
7812 | * will be set. Check for and return an error if this condition is | ||
7813 | * found. | ||
7814 | */ | ||
7815 | if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) { | ||
7816 | asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE; | ||
7817 | return ADV_ERROR; | ||
7818 | } | ||
8102 | 7819 | ||
8103 | printk(" cntl 0x%x, data_addr 0x%lx, vdata_addr 0x%lx\n", | 7820 | /* |
8104 | q->cntl, (ulong)le32_to_cpu(q->data_addr), (ulong)q->vdata_addr); | 7821 | * Each ASC-38C1600 function has two connectors. Only an HVD device |
7822 | * can not be connected to either connector. An LVD device or SE device | ||
7823 | * may be connected to either connecor. If an SE device is connected, | ||
7824 | * then at most Ultra speed (20 Mhz) can be used on both connectors. | ||
7825 | * | ||
7826 | * If an HVD device is attached, return an error. | ||
7827 | */ | ||
7828 | if (scsi_cfg1 & HVD) { | ||
7829 | asc_dvc->err_code |= ASC_IERR_HVD_DEVICE; | ||
7830 | return ADV_ERROR; | ||
7831 | } | ||
8105 | 7832 | ||
8106 | printk(" data_cnt %lu, sense_addr 0x%lx, sense_len %u,\n", | 7833 | /* |
8107 | (ulong)le32_to_cpu(q->data_cnt), | 7834 | * Each function in the ASC-38C1600 uses only the SE cable detect and |
8108 | (ulong)le32_to_cpu(q->sense_addr), q->sense_len); | 7835 | * termination because there are two connectors for each function. Each |
7836 | * function may use either LVD or SE mode. Corresponding the SE automatic | ||
7837 | * termination control EEPROM bits are used for each function. Each | ||
7838 | * function has its own EEPROM. If SE automatic control is enabled for | ||
7839 | * the function, then set the termination value based on a table listed | ||
7840 | * in a_condor.h. | ||
7841 | * | ||
7842 | * If manual termination is specified in the EEPROM for the function, | ||
7843 | * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is | ||
7844 | * ready to be 'ored' into SCSI_CFG1. | ||
7845 | */ | ||
7846 | if ((asc_dvc->cfg->termination & TERM_SE) == 0) { | ||
7847 | struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc); | ||
7848 | /* SE automatic termination control is enabled. */ | ||
7849 | switch (scsi_cfg1 & C_DET_SE) { | ||
7850 | /* TERM_SE_HI: on, TERM_SE_LO: on */ | ||
7851 | case 0x1: | ||
7852 | case 0x2: | ||
7853 | case 0x3: | ||
7854 | asc_dvc->cfg->termination |= TERM_SE; | ||
7855 | break; | ||
8109 | 7856 | ||
8110 | printk | 7857 | case 0x0: |
8111 | (" cdb_len %u, done_status 0x%x, host_status 0x%x, scsi_status 0x%x\n", | 7858 | if (PCI_FUNC(pdev->devfn) == 0) { |
8112 | q->cdb_len, q->done_status, q->host_status, q->scsi_status); | 7859 | /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */ |
7860 | } else { | ||
7861 | /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */ | ||
7862 | asc_dvc->cfg->termination |= TERM_SE_HI; | ||
7863 | } | ||
7864 | break; | ||
7865 | } | ||
7866 | } | ||
8113 | 7867 | ||
8114 | printk(" sg_working_ix 0x%x, target_cmd %u\n", | 7868 | /* |
8115 | q->sg_working_ix, q->target_cmd); | 7869 | * Clear any set TERM_SE bits. |
7870 | */ | ||
7871 | scsi_cfg1 &= ~TERM_SE; | ||
8116 | 7872 | ||
8117 | printk(" scsiq_rptr 0x%lx, sg_real_addr 0x%lx, sg_list_ptr 0x%lx\n", | 7873 | /* |
8118 | (ulong)le32_to_cpu(q->scsiq_rptr), | 7874 | * Invert the TERM_SE bits and then set 'scsi_cfg1'. |
8119 | (ulong)le32_to_cpu(q->sg_real_addr), (ulong)q->sg_list_ptr); | 7875 | */ |
7876 | scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE); | ||
8120 | 7877 | ||
8121 | /* Display the request's ADV_SG_BLOCK structures. */ | 7878 | /* |
8122 | if (q->sg_list_ptr != NULL) { | 7879 | * Clear Big Endian and Terminator Polarity bits and set possibly |
8123 | sg_blk_cnt = 0; | 7880 | * modified termination control bits in the Microcode SCSI_CFG1 |
8124 | while (1) { | 7881 | * Register Value. |
7882 | * | ||
7883 | * Big Endian bit is not used even on big endian machines. | ||
7884 | */ | ||
7885 | scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL); | ||
7886 | |||
7887 | /* | ||
7888 | * Set SCSI_CFG1 Microcode Default Value | ||
7889 | * | ||
7890 | * Set possibly modified termination control bits in the Microcode | ||
7891 | * SCSI_CFG1 Register Value. | ||
7892 | * | ||
7893 | * The microcode will set the SCSI_CFG1 register using this value | ||
7894 | * after it is started below. | ||
7895 | */ | ||
7896 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1); | ||
7897 | |||
7898 | /* | ||
7899 | * Set MEM_CFG Microcode Default Value | ||
7900 | * | ||
7901 | * The microcode will set the MEM_CFG register using this value | ||
7902 | * after it is started below. | ||
7903 | * | ||
7904 | * MEM_CFG may be accessed as a word or byte, but only bits 0-7 | ||
7905 | * are defined. | ||
7906 | * | ||
7907 | * ASC-38C1600 has 32KB internal memory. | ||
7908 | * | ||
7909 | * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come | ||
7910 | * out a special 16K Adv Library and Microcode version. After the issue | ||
7911 | * resolved, we should turn back to the 32K support. Both a_condor.h and | ||
7912 | * mcode.sas files also need to be updated. | ||
7913 | * | ||
7914 | * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, | ||
7915 | * BIOS_EN | RAM_SZ_32KB); | ||
7916 | */ | ||
7917 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, | ||
7918 | BIOS_EN | RAM_SZ_16KB); | ||
7919 | |||
7920 | /* | ||
7921 | * Set SEL_MASK Microcode Default Value | ||
7922 | * | ||
7923 | * The microcode will set the SEL_MASK register using this value | ||
7924 | * after it is started below. | ||
7925 | */ | ||
7926 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, | ||
7927 | ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); | ||
7928 | |||
7929 | AdvBuildCarrierFreelist(asc_dvc); | ||
7930 | |||
7931 | /* | ||
7932 | * Set-up the Host->RISC Initiator Command Queue (ICQ). | ||
7933 | */ | ||
7934 | if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) { | ||
7935 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; | ||
7936 | return ADV_ERROR; | ||
7937 | } | ||
7938 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
7939 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa)); | ||
7940 | |||
7941 | /* | ||
7942 | * The first command issued will be placed in the stopper carrier. | ||
7943 | */ | ||
7944 | asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
7945 | |||
7946 | /* | ||
7947 | * Set RISC ICQ physical address start value. Initialize the | ||
7948 | * COMMA register to the same value otherwise the RISC will | ||
7949 | * prematurely detect a command is available. | ||
7950 | */ | ||
7951 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa); | ||
7952 | AdvWriteDWordRegister(iop_base, IOPDW_COMMA, | ||
7953 | le32_to_cpu(asc_dvc->icq_sp->carr_pa)); | ||
7954 | |||
7955 | /* | ||
7956 | * Set-up the RISC->Host Initiator Response Queue (IRQ). | ||
7957 | */ | ||
7958 | if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) { | ||
7959 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; | ||
7960 | return ADV_ERROR; | ||
7961 | } | ||
7962 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
7963 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa)); | ||
7964 | |||
7965 | /* | ||
7966 | * The first command completed by the RISC will be placed in | ||
7967 | * the stopper. | ||
7968 | * | ||
7969 | * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is | ||
7970 | * completed the RISC will set the ASC_RQ_STOPPER bit. | ||
7971 | */ | ||
7972 | asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
7973 | |||
7974 | /* | ||
7975 | * Set RISC IRQ physical address start value. | ||
7976 | */ | ||
7977 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa); | ||
7978 | asc_dvc->carr_pending_cnt = 0; | ||
7979 | |||
7980 | AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES, | ||
7981 | (ADV_INTR_ENABLE_HOST_INTR | | ||
7982 | ADV_INTR_ENABLE_GLOBAL_INTR)); | ||
7983 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word); | ||
7984 | AdvWriteWordRegister(iop_base, IOPW_PC, word); | ||
7985 | |||
7986 | /* finally, finally, gentlemen, start your engine */ | ||
7987 | AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN); | ||
7988 | |||
7989 | /* | ||
7990 | * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus | ||
7991 | * Resets should be performed. The RISC has to be running | ||
7992 | * to issue a SCSI Bus Reset. | ||
7993 | */ | ||
7994 | if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) { | ||
7995 | /* | ||
7996 | * If the BIOS Signature is present in memory, restore the | ||
7997 | * per TID microcode operating variables. | ||
7998 | */ | ||
7999 | if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == | ||
8000 | 0x55AA) { | ||
8125 | /* | 8001 | /* |
8126 | * 'sg_ptr' is a physical address. Convert it to a virtual | 8002 | * Restore per TID negotiated values. |
8127 | * address by indexing 'sg_blk_cnt' into the virtual address | ||
8128 | * array 'sg_list_ptr'. | ||
8129 | * | ||
8130 | * XXX - Assumes all SG physical blocks are virtually contiguous. | ||
8131 | */ | 8003 | */ |
8132 | sg_ptr = | 8004 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); |
8133 | &(((ADV_SG_BLOCK *)(q->sg_list_ptr))[sg_blk_cnt]); | 8005 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); |
8134 | asc_prt_adv_sgblock(sg_blk_cnt, sg_ptr); | 8006 | AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); |
8135 | if (sg_ptr->sg_ptr == 0) { | 8007 | AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, |
8136 | break; | 8008 | tagqng_able); |
8009 | for (tid = 0; tid <= ASC_MAX_TID; tid++) { | ||
8010 | AdvWriteByteLram(iop_base, | ||
8011 | ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
8012 | max_cmd[tid]); | ||
8013 | } | ||
8014 | } else { | ||
8015 | if (AdvResetSB(asc_dvc) != ADV_TRUE) { | ||
8016 | warn_code = ASC_WARN_BUSRESET_ERROR; | ||
8137 | } | 8017 | } |
8138 | sg_blk_cnt++; | ||
8139 | } | 8018 | } |
8140 | } | 8019 | } |
8020 | |||
8021 | return warn_code; | ||
8141 | } | 8022 | } |
8142 | 8023 | ||
8143 | /* | 8024 | /* |
8144 | * asc_prt_adv_sgblock() | 8025 | * Reset chip and SCSI Bus. |
8145 | * | 8026 | * |
8146 | * Display an ADV_SG_BLOCK structure. | 8027 | * Return Value: |
8028 | * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful. | ||
8029 | * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure. | ||
8147 | */ | 8030 | */ |
8148 | static void asc_prt_adv_sgblock(int sgblockno, ADV_SG_BLOCK *b) | 8031 | static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc) |
8149 | { | 8032 | { |
8150 | int i; | 8033 | int status; |
8034 | ushort wdtr_able, sdtr_able, tagqng_able; | ||
8035 | ushort ppr_able = 0; | ||
8036 | uchar tid, max_cmd[ADV_MAX_TID + 1]; | ||
8037 | AdvPortAddr iop_base; | ||
8038 | ushort bios_sig; | ||
8151 | 8039 | ||
8152 | printk(" ASC_SG_BLOCK at addr 0x%lx (sgblockno %d)\n", | 8040 | iop_base = asc_dvc->iop_base; |
8153 | (ulong)b, sgblockno); | 8041 | |
8154 | printk(" sg_cnt %u, sg_ptr 0x%lx\n", | 8042 | /* |
8155 | b->sg_cnt, (ulong)le32_to_cpu(b->sg_ptr)); | 8043 | * Save current per TID negotiated values. |
8156 | ASC_ASSERT(b->sg_cnt <= NO_OF_SG_PER_BLOCK); | 8044 | */ |
8157 | if (b->sg_ptr != 0) { | 8045 | AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); |
8158 | ASC_ASSERT(b->sg_cnt == NO_OF_SG_PER_BLOCK); | 8046 | AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); |
8047 | if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { | ||
8048 | AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); | ||
8159 | } | 8049 | } |
8160 | for (i = 0; i < b->sg_cnt; i++) { | 8050 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); |
8161 | printk(" [%u]: sg_addr 0x%lx, sg_count 0x%lx\n", | 8051 | for (tid = 0; tid <= ADV_MAX_TID; tid++) { |
8162 | i, (ulong)b->sg_list[i].sg_addr, | 8052 | AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, |
8163 | (ulong)b->sg_list[i].sg_count); | 8053 | max_cmd[tid]); |
8164 | } | 8054 | } |
8165 | } | ||
8166 | 8055 | ||
8167 | /* | 8056 | /* |
8168 | * asc_prt_hex() | 8057 | * Force the AdvInitAsc3550/38C0800Driver() function to |
8169 | * | 8058 | * perform a SCSI Bus Reset by clearing the BIOS signature word. |
8170 | * Print hexadecimal output in 4 byte groupings 32 bytes | 8059 | * The initialization functions assumes a SCSI Bus Reset is not |
8171 | * or 8 double-words per line. | 8060 | * needed if the BIOS signature word is present. |
8172 | */ | 8061 | */ |
8173 | static void asc_prt_hex(char *f, uchar *s, int l) | 8062 | AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig); |
8174 | { | 8063 | AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0); |
8175 | int i; | ||
8176 | int j; | ||
8177 | int k; | ||
8178 | int m; | ||
8179 | |||
8180 | printk("%s: (%d bytes)\n", f, l); | ||
8181 | 8064 | ||
8182 | for (i = 0; i < l; i += 32) { | 8065 | /* |
8066 | * Stop chip and reset it. | ||
8067 | */ | ||
8068 | AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP); | ||
8069 | AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET); | ||
8070 | mdelay(100); | ||
8071 | AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, | ||
8072 | ADV_CTRL_REG_CMD_WR_IO_REG); | ||
8183 | 8073 | ||
8184 | /* Display a maximum of 8 double-words per line. */ | 8074 | /* |
8185 | if ((k = (l - i) / 4) >= 8) { | 8075 | * Reset Adv Library error code, if any, and try |
8186 | k = 8; | 8076 | * re-initializing the chip. |
8187 | m = 0; | 8077 | */ |
8188 | } else { | 8078 | asc_dvc->err_code = 0; |
8189 | m = (l - i) % 4; | 8079 | if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { |
8190 | } | 8080 | status = AdvInitAsc38C1600Driver(asc_dvc); |
8081 | } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) { | ||
8082 | status = AdvInitAsc38C0800Driver(asc_dvc); | ||
8083 | } else { | ||
8084 | status = AdvInitAsc3550Driver(asc_dvc); | ||
8085 | } | ||
8191 | 8086 | ||
8192 | for (j = 0; j < k; j++) { | 8087 | /* Translate initialization return value to status value. */ |
8193 | printk(" %2.2X%2.2X%2.2X%2.2X", | 8088 | if (status == 0) { |
8194 | (unsigned)s[i + (j * 4)], | 8089 | status = ADV_TRUE; |
8195 | (unsigned)s[i + (j * 4) + 1], | 8090 | } else { |
8196 | (unsigned)s[i + (j * 4) + 2], | 8091 | status = ADV_FALSE; |
8197 | (unsigned)s[i + (j * 4) + 3]); | 8092 | } |
8198 | } | ||
8199 | 8093 | ||
8200 | switch (m) { | 8094 | /* |
8201 | case 0: | 8095 | * Restore the BIOS signature word. |
8202 | default: | 8096 | */ |
8203 | break; | 8097 | AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig); |
8204 | case 1: | ||
8205 | printk(" %2.2X", (unsigned)s[i + (j * 4)]); | ||
8206 | break; | ||
8207 | case 2: | ||
8208 | printk(" %2.2X%2.2X", | ||
8209 | (unsigned)s[i + (j * 4)], | ||
8210 | (unsigned)s[i + (j * 4) + 1]); | ||
8211 | break; | ||
8212 | case 3: | ||
8213 | printk(" %2.2X%2.2X%2.2X", | ||
8214 | (unsigned)s[i + (j * 4) + 1], | ||
8215 | (unsigned)s[i + (j * 4) + 2], | ||
8216 | (unsigned)s[i + (j * 4) + 3]); | ||
8217 | break; | ||
8218 | } | ||
8219 | 8098 | ||
8220 | printk("\n"); | 8099 | /* |
8100 | * Restore per TID negotiated values. | ||
8101 | */ | ||
8102 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
8103 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
8104 | if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { | ||
8105 | AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); | ||
8106 | } | ||
8107 | AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | ||
8108 | for (tid = 0; tid <= ADV_MAX_TID; tid++) { | ||
8109 | AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
8110 | max_cmd[tid]); | ||
8221 | } | 8111 | } |
8112 | |||
8113 | return status; | ||
8222 | } | 8114 | } |
8223 | #endif /* ADVANSYS_DEBUG */ | ||
8224 | 8115 | ||
8225 | /* | 8116 | /* |
8226 | * --- Asc Library Functions | 8117 | * adv_async_callback() - Adv Library asynchronous event callback function. |
8227 | */ | 8118 | */ |
8228 | 8119 | static void adv_async_callback(ADV_DVC_VAR *adv_dvc_varp, uchar code) | |
8229 | static ushort __init AscGetEisaChipCfg(PortAddr iop_base) | ||
8230 | { | 8120 | { |
8231 | PortAddr eisa_cfg_iop; | 8121 | switch (code) { |
8122 | case ADV_ASYNC_SCSI_BUS_RESET_DET: | ||
8123 | /* | ||
8124 | * The firmware detected a SCSI Bus reset. | ||
8125 | */ | ||
8126 | ASC_DBG(0, "ADV_ASYNC_SCSI_BUS_RESET_DET\n"); | ||
8127 | break; | ||
8232 | 8128 | ||
8233 | eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) | | 8129 | case ADV_ASYNC_RDMA_FAILURE: |
8234 | (PortAddr) (ASC_EISA_CFG_IOP_MASK); | 8130 | /* |
8235 | return (inpw(eisa_cfg_iop)); | 8131 | * Handle RDMA failure by resetting the SCSI Bus and |
8236 | } | 8132 | * possibly the chip if it is unresponsive. Log the error |
8133 | * with a unique code. | ||
8134 | */ | ||
8135 | ASC_DBG(0, "ADV_ASYNC_RDMA_FAILURE\n"); | ||
8136 | AdvResetChipAndSB(adv_dvc_varp); | ||
8137 | break; | ||
8237 | 8138 | ||
8238 | static uchar __init AscSetChipScsiID(PortAddr iop_base, uchar new_host_id) | 8139 | case ADV_HOST_SCSI_BUS_RESET: |
8239 | { | 8140 | /* |
8240 | ushort cfg_lsw; | 8141 | * Host generated SCSI bus reset occurred. |
8142 | */ | ||
8143 | ASC_DBG(0, "ADV_HOST_SCSI_BUS_RESET\n"); | ||
8144 | break; | ||
8241 | 8145 | ||
8242 | if (AscGetChipScsiID(iop_base) == new_host_id) { | 8146 | default: |
8243 | return (new_host_id); | 8147 | ASC_DBG(0, "unknown code 0x%x\n", code); |
8148 | break; | ||
8244 | } | 8149 | } |
8245 | cfg_lsw = AscGetChipCfgLsw(iop_base); | ||
8246 | cfg_lsw &= 0xF8FF; | ||
8247 | cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8); | ||
8248 | AscSetChipCfgLsw(iop_base, cfg_lsw); | ||
8249 | return (AscGetChipScsiID(iop_base)); | ||
8250 | } | 8150 | } |
8251 | 8151 | ||
8252 | static uchar __init AscGetChipScsiCtrl(PortAddr iop_base) | 8152 | /* |
8153 | * adv_isr_callback() - Second Level Interrupt Handler called by AdvISR(). | ||
8154 | * | ||
8155 | * Callback function for the Wide SCSI Adv Library. | ||
8156 | */ | ||
8157 | static void adv_isr_callback(ADV_DVC_VAR *adv_dvc_varp, ADV_SCSI_REQ_Q *scsiqp) | ||
8253 | { | 8158 | { |
8254 | uchar sc; | 8159 | struct asc_board *boardp; |
8160 | adv_req_t *reqp; | ||
8161 | adv_sgblk_t *sgblkp; | ||
8162 | struct scsi_cmnd *scp; | ||
8163 | struct Scsi_Host *shost; | ||
8164 | ADV_DCNT resid_cnt; | ||
8255 | 8165 | ||
8256 | AscSetBank(iop_base, 1); | 8166 | ASC_DBG(1, "adv_dvc_varp 0x%lx, scsiqp 0x%lx\n", |
8257 | sc = inp(iop_base + IOP_REG_SC); | 8167 | (ulong)adv_dvc_varp, (ulong)scsiqp); |
8258 | AscSetBank(iop_base, 0); | 8168 | ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp); |
8259 | return (sc); | ||
8260 | } | ||
8261 | 8169 | ||
8262 | static uchar __init AscGetChipVersion(PortAddr iop_base, ushort bus_type) | 8170 | /* |
8263 | { | 8171 | * Get the adv_req_t structure for the command that has been |
8264 | if ((bus_type & ASC_IS_EISA) != 0) { | 8172 | * completed. The adv_req_t structure actually contains the |
8265 | PortAddr eisa_iop; | 8173 | * completed ADV_SCSI_REQ_Q structure. |
8266 | uchar revision; | 8174 | */ |
8267 | eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) | | 8175 | reqp = (adv_req_t *)ADV_U32_TO_VADDR(scsiqp->srb_ptr); |
8268 | (PortAddr) ASC_EISA_REV_IOP_MASK; | 8176 | ASC_DBG(1, "reqp 0x%lx\n", (ulong)reqp); |
8269 | revision = inp(eisa_iop); | 8177 | if (reqp == NULL) { |
8270 | return ((uchar)((ASC_CHIP_MIN_VER_EISA - 1) + revision)); | 8178 | ASC_PRINT("adv_isr_callback: reqp is NULL\n"); |
8179 | return; | ||
8271 | } | 8180 | } |
8272 | return (AscGetChipVerNo(iop_base)); | ||
8273 | } | ||
8274 | 8181 | ||
8275 | static ushort __init AscGetChipBusType(PortAddr iop_base) | 8182 | /* |
8276 | { | 8183 | * Get the struct scsi_cmnd structure and Scsi_Host structure for the |
8277 | ushort chip_ver; | 8184 | * command that has been completed. |
8278 | 8185 | * | |
8279 | chip_ver = AscGetChipVerNo(iop_base); | 8186 | * Note: The adv_req_t request structure and adv_sgblk_t structure, |
8280 | if ((chip_ver >= ASC_CHIP_MIN_VER_VL) | 8187 | * if any, are dropped, because a board structure pointer can not be |
8281 | && (chip_ver <= ASC_CHIP_MAX_VER_VL) | 8188 | * determined. |
8282 | ) { | 8189 | */ |
8283 | if (((iop_base & 0x0C30) == 0x0C30) | 8190 | scp = reqp->cmndp; |
8284 | || ((iop_base & 0x0C50) == 0x0C50) | 8191 | ASC_DBG(1, "scp 0x%p\n", scp); |
8285 | ) { | 8192 | if (scp == NULL) { |
8286 | return (ASC_IS_EISA); | 8193 | ASC_PRINT |
8287 | } | 8194 | ("adv_isr_callback: scp is NULL; adv_req_t dropped.\n"); |
8288 | return (ASC_IS_VL); | 8195 | return; |
8289 | } | 8196 | } |
8290 | if ((chip_ver >= ASC_CHIP_MIN_VER_ISA) && | 8197 | ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len); |
8291 | (chip_ver <= ASC_CHIP_MAX_VER_ISA)) { | 8198 | |
8292 | if (chip_ver >= ASC_CHIP_MIN_VER_ISA_PNP) { | 8199 | shost = scp->device->host; |
8293 | return (ASC_IS_ISAPNP); | 8200 | ASC_STATS(shost, callback); |
8201 | ASC_DBG(1, "shost 0x%p\n", shost); | ||
8202 | |||
8203 | boardp = shost_priv(shost); | ||
8204 | BUG_ON(adv_dvc_varp != &boardp->dvc_var.adv_dvc_var); | ||
8205 | |||
8206 | /* | ||
8207 | * 'done_status' contains the command's ending status. | ||
8208 | */ | ||
8209 | switch (scsiqp->done_status) { | ||
8210 | case QD_NO_ERROR: | ||
8211 | ASC_DBG(2, "QD_NO_ERROR\n"); | ||
8212 | scp->result = 0; | ||
8213 | |||
8214 | /* | ||
8215 | * Check for an underrun condition. | ||
8216 | * | ||
8217 | * If there was no error and an underrun condition, then | ||
8218 | * then return the number of underrun bytes. | ||
8219 | */ | ||
8220 | resid_cnt = le32_to_cpu(scsiqp->data_cnt); | ||
8221 | if (scsi_bufflen(scp) != 0 && resid_cnt != 0 && | ||
8222 | resid_cnt <= scsi_bufflen(scp)) { | ||
8223 | ASC_DBG(1, "underrun condition %lu bytes\n", | ||
8224 | (ulong)resid_cnt); | ||
8225 | scsi_set_resid(scp, resid_cnt); | ||
8294 | } | 8226 | } |
8295 | return (ASC_IS_ISA); | 8227 | break; |
8296 | } else if ((chip_ver >= ASC_CHIP_MIN_VER_PCI) && | 8228 | |
8297 | (chip_ver <= ASC_CHIP_MAX_VER_PCI)) { | 8229 | case QD_WITH_ERROR: |
8298 | return (ASC_IS_PCI); | 8230 | ASC_DBG(2, "QD_WITH_ERROR\n"); |
8231 | switch (scsiqp->host_status) { | ||
8232 | case QHSTA_NO_ERROR: | ||
8233 | if (scsiqp->scsi_status == SAM_STAT_CHECK_CONDITION) { | ||
8234 | ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n"); | ||
8235 | ASC_DBG_PRT_SENSE(2, scp->sense_buffer, | ||
8236 | sizeof(scp->sense_buffer)); | ||
8237 | /* | ||
8238 | * Note: The 'status_byte()' macro used by | ||
8239 | * target drivers defined in scsi.h shifts the | ||
8240 | * status byte returned by host drivers right | ||
8241 | * by 1 bit. This is why target drivers also | ||
8242 | * use right shifted status byte definitions. | ||
8243 | * For instance target drivers use | ||
8244 | * CHECK_CONDITION, defined to 0x1, instead of | ||
8245 | * the SCSI defined check condition value of | ||
8246 | * 0x2. Host drivers are supposed to return | ||
8247 | * the status byte as it is defined by SCSI. | ||
8248 | */ | ||
8249 | scp->result = DRIVER_BYTE(DRIVER_SENSE) | | ||
8250 | STATUS_BYTE(scsiqp->scsi_status); | ||
8251 | } else { | ||
8252 | scp->result = STATUS_BYTE(scsiqp->scsi_status); | ||
8253 | } | ||
8254 | break; | ||
8255 | |||
8256 | default: | ||
8257 | /* Some other QHSTA error occurred. */ | ||
8258 | ASC_DBG(1, "host_status 0x%x\n", scsiqp->host_status); | ||
8259 | scp->result = HOST_BYTE(DID_BAD_TARGET); | ||
8260 | break; | ||
8261 | } | ||
8262 | break; | ||
8263 | |||
8264 | case QD_ABORTED_BY_HOST: | ||
8265 | ASC_DBG(1, "QD_ABORTED_BY_HOST\n"); | ||
8266 | scp->result = | ||
8267 | HOST_BYTE(DID_ABORT) | STATUS_BYTE(scsiqp->scsi_status); | ||
8268 | break; | ||
8269 | |||
8270 | default: | ||
8271 | ASC_DBG(1, "done_status 0x%x\n", scsiqp->done_status); | ||
8272 | scp->result = | ||
8273 | HOST_BYTE(DID_ERROR) | STATUS_BYTE(scsiqp->scsi_status); | ||
8274 | break; | ||
8299 | } | 8275 | } |
8300 | return (0); | ||
8301 | } | ||
8302 | 8276 | ||
8303 | static ASC_DCNT | 8277 | /* |
8304 | AscLoadMicroCode(PortAddr iop_base, | 8278 | * If the 'init_tidmask' bit isn't already set for the target and the |
8305 | ushort s_addr, uchar *mcode_buf, ushort mcode_size) | 8279 | * current request finished normally, then set the bit for the target |
8306 | { | 8280 | * to indicate that a device is present. |
8307 | ASC_DCNT chksum; | 8281 | */ |
8308 | ushort mcode_word_size; | 8282 | if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 && |
8309 | ushort mcode_chksum; | 8283 | scsiqp->done_status == QD_NO_ERROR && |
8284 | scsiqp->host_status == QHSTA_NO_ERROR) { | ||
8285 | boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id); | ||
8286 | } | ||
8310 | 8287 | ||
8311 | /* Write the microcode buffer starting at LRAM address 0. */ | 8288 | asc_scsi_done(scp); |
8312 | mcode_word_size = (ushort)(mcode_size >> 1); | ||
8313 | AscMemWordSetLram(iop_base, s_addr, 0, mcode_word_size); | ||
8314 | AscMemWordCopyPtrToLram(iop_base, s_addr, mcode_buf, mcode_word_size); | ||
8315 | 8289 | ||
8316 | chksum = AscMemSumLramWord(iop_base, s_addr, mcode_word_size); | 8290 | /* |
8317 | ASC_DBG1(1, "AscLoadMicroCode: chksum 0x%lx\n", (ulong)chksum); | 8291 | * Free all 'adv_sgblk_t' structures allocated for the request. |
8318 | mcode_chksum = (ushort)AscMemSumLramWord(iop_base, | 8292 | */ |
8319 | (ushort)ASC_CODE_SEC_BEG, | 8293 | while ((sgblkp = reqp->sgblkp) != NULL) { |
8320 | (ushort)((mcode_size - | 8294 | /* Remove 'sgblkp' from the request list. */ |
8321 | s_addr - (ushort) | 8295 | reqp->sgblkp = sgblkp->next_sgblkp; |
8322 | ASC_CODE_SEC_BEG) / | 8296 | |
8323 | 2)); | 8297 | /* Add 'sgblkp' to the board free list. */ |
8324 | ASC_DBG1(1, "AscLoadMicroCode: mcode_chksum 0x%lx\n", | 8298 | sgblkp->next_sgblkp = boardp->adv_sgblkp; |
8325 | (ulong)mcode_chksum); | 8299 | boardp->adv_sgblkp = sgblkp; |
8326 | AscWriteLramWord(iop_base, ASCV_MCODE_CHKSUM_W, mcode_chksum); | 8300 | } |
8327 | AscWriteLramWord(iop_base, ASCV_MCODE_SIZE_W, mcode_size); | 8301 | |
8328 | return (chksum); | 8302 | /* |
8303 | * Free the adv_req_t structure used with the command by adding | ||
8304 | * it back to the board free list. | ||
8305 | */ | ||
8306 | reqp->next_reqp = boardp->adv_reqp; | ||
8307 | boardp->adv_reqp = reqp; | ||
8308 | |||
8309 | ASC_DBG(1, "done\n"); | ||
8329 | } | 8310 | } |
8330 | 8311 | ||
8331 | static int AscFindSignature(PortAddr iop_base) | 8312 | /* |
8313 | * Adv Library Interrupt Service Routine | ||
8314 | * | ||
8315 | * This function is called by a driver's interrupt service routine. | ||
8316 | * The function disables and re-enables interrupts. | ||
8317 | * | ||
8318 | * When a microcode idle command is completed, the ADV_DVC_VAR | ||
8319 | * 'idle_cmd_done' field is set to ADV_TRUE. | ||
8320 | * | ||
8321 | * Note: AdvISR() can be called when interrupts are disabled or even | ||
8322 | * when there is no hardware interrupt condition present. It will | ||
8323 | * always check for completed idle commands and microcode requests. | ||
8324 | * This is an important feature that shouldn't be changed because it | ||
8325 | * allows commands to be completed from polling mode loops. | ||
8326 | * | ||
8327 | * Return: | ||
8328 | * ADV_TRUE(1) - interrupt was pending | ||
8329 | * ADV_FALSE(0) - no interrupt was pending | ||
8330 | */ | ||
8331 | static int AdvISR(ADV_DVC_VAR *asc_dvc) | ||
8332 | { | 8332 | { |
8333 | ushort sig_word; | 8333 | AdvPortAddr iop_base; |
8334 | uchar int_stat; | ||
8335 | ushort target_bit; | ||
8336 | ADV_CARR_T *free_carrp; | ||
8337 | ADV_VADDR irq_next_vpa; | ||
8338 | ADV_SCSI_REQ_Q *scsiq; | ||
8334 | 8339 | ||
8335 | ASC_DBG2(1, "AscFindSignature: AscGetChipSignatureByte(0x%x) 0x%x\n", | 8340 | iop_base = asc_dvc->iop_base; |
8336 | iop_base, AscGetChipSignatureByte(iop_base)); | 8341 | |
8337 | if (AscGetChipSignatureByte(iop_base) == (uchar)ASC_1000_ID1B) { | 8342 | /* Reading the register clears the interrupt. */ |
8338 | ASC_DBG2(1, | 8343 | int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG); |
8339 | "AscFindSignature: AscGetChipSignatureWord(0x%x) 0x%x\n", | 8344 | |
8340 | iop_base, AscGetChipSignatureWord(iop_base)); | 8345 | if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB | |
8341 | sig_word = AscGetChipSignatureWord(iop_base); | 8346 | ADV_INTR_STATUS_INTRC)) == 0) { |
8342 | if ((sig_word == (ushort)ASC_1000_ID0W) || | 8347 | return ADV_FALSE; |
8343 | (sig_word == (ushort)ASC_1000_ID0W_FIX)) { | ||
8344 | return (1); | ||
8345 | } | ||
8346 | } | 8348 | } |
8347 | return (0); | ||
8348 | } | ||
8349 | 8349 | ||
8350 | static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __initdata = { | 8350 | /* |
8351 | 0x100, ASC_IOADR_1, 0x120, ASC_IOADR_2, 0x140, ASC_IOADR_3, ASC_IOADR_4, | 8351 | * Notify the driver of an asynchronous microcode condition by |
8352 | ASC_IOADR_5, ASC_IOADR_6, ASC_IOADR_7, ASC_IOADR_8 | 8352 | * calling the adv_async_callback function. The function |
8353 | }; | 8353 | * is passed the microcode ASC_MC_INTRB_CODE byte value. |
8354 | */ | ||
8355 | if (int_stat & ADV_INTR_STATUS_INTRB) { | ||
8356 | uchar intrb_code; | ||
8354 | 8357 | ||
8355 | #ifdef CONFIG_ISA | 8358 | AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code); |
8356 | static uchar _isa_pnp_inited __initdata = 0; | ||
8357 | 8359 | ||
8358 | static PortAddr __init AscSearchIOPortAddr(PortAddr iop_beg, ushort bus_type) | 8360 | if (asc_dvc->chip_type == ADV_CHIP_ASC3550 || |
8359 | { | 8361 | asc_dvc->chip_type == ADV_CHIP_ASC38C0800) { |
8360 | if (bus_type & ASC_IS_VL) { | 8362 | if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE && |
8361 | while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) { | 8363 | asc_dvc->carr_pending_cnt != 0) { |
8362 | if (AscGetChipVersion(iop_beg, bus_type) <= | 8364 | AdvWriteByteRegister(iop_base, IOPB_TICKLE, |
8363 | ASC_CHIP_MAX_VER_VL) { | 8365 | ADV_TICKLE_A); |
8364 | return (iop_beg); | 8366 | if (asc_dvc->chip_type == ADV_CHIP_ASC3550) { |
8367 | AdvWriteByteRegister(iop_base, | ||
8368 | IOPB_TICKLE, | ||
8369 | ADV_TICKLE_NOP); | ||
8370 | } | ||
8365 | } | 8371 | } |
8366 | } | 8372 | } |
8367 | return (0); | 8373 | |
8374 | adv_async_callback(asc_dvc, intrb_code); | ||
8368 | } | 8375 | } |
8369 | if (bus_type & ASC_IS_ISA) { | 8376 | |
8370 | if (_isa_pnp_inited == 0) { | 8377 | /* |
8371 | AscSetISAPNPWaitForKey(); | 8378 | * Check if the IRQ stopper carrier contains a completed request. |
8372 | _isa_pnp_inited++; | 8379 | */ |
8373 | } | 8380 | while (((irq_next_vpa = |
8374 | while ((iop_beg = AscSearchIOPortAddr11(iop_beg)) != 0) { | 8381 | le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) { |
8375 | if ((AscGetChipVersion(iop_beg, bus_type) & | 8382 | /* |
8376 | ASC_CHIP_VER_ISA_BIT) != 0) { | 8383 | * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure. |
8377 | return (iop_beg); | 8384 | * The RISC will have set 'areq_vpa' to a virtual address. |
8378 | } | 8385 | * |
8386 | * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr | ||
8387 | * field to the carrier ADV_CARR_T.areq_vpa field. The conversion | ||
8388 | * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr' | ||
8389 | * in AdvExeScsiQueue(). | ||
8390 | */ | ||
8391 | scsiq = (ADV_SCSI_REQ_Q *) | ||
8392 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa)); | ||
8393 | |||
8394 | /* | ||
8395 | * Request finished with good status and the queue was not | ||
8396 | * DMAed to host memory by the firmware. Set all status fields | ||
8397 | * to indicate good status. | ||
8398 | */ | ||
8399 | if ((irq_next_vpa & ASC_RQ_GOOD) != 0) { | ||
8400 | scsiq->done_status = QD_NO_ERROR; | ||
8401 | scsiq->host_status = scsiq->scsi_status = 0; | ||
8402 | scsiq->data_cnt = 0L; | ||
8379 | } | 8403 | } |
8380 | return (0); | 8404 | |
8405 | /* | ||
8406 | * Advance the stopper pointer to the next carrier | ||
8407 | * ignoring the lower four bits. Free the previous | ||
8408 | * stopper carrier. | ||
8409 | */ | ||
8410 | free_carrp = asc_dvc->irq_sp; | ||
8411 | asc_dvc->irq_sp = (ADV_CARR_T *) | ||
8412 | ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa)); | ||
8413 | |||
8414 | free_carrp->next_vpa = | ||
8415 | cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); | ||
8416 | asc_dvc->carr_freelist = free_carrp; | ||
8417 | asc_dvc->carr_pending_cnt--; | ||
8418 | |||
8419 | target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id); | ||
8420 | |||
8421 | /* | ||
8422 | * Clear request microcode control flag. | ||
8423 | */ | ||
8424 | scsiq->cntl = 0; | ||
8425 | |||
8426 | /* | ||
8427 | * Notify the driver of the completed request by passing | ||
8428 | * the ADV_SCSI_REQ_Q pointer to its callback function. | ||
8429 | */ | ||
8430 | scsiq->a_flag |= ADV_SCSIQ_DONE; | ||
8431 | adv_isr_callback(asc_dvc, scsiq); | ||
8432 | /* | ||
8433 | * Note: After the driver callback function is called, 'scsiq' | ||
8434 | * can no longer be referenced. | ||
8435 | * | ||
8436 | * Fall through and continue processing other completed | ||
8437 | * requests... | ||
8438 | */ | ||
8381 | } | 8439 | } |
8382 | if (bus_type & ASC_IS_EISA) { | 8440 | return ADV_TRUE; |
8383 | if ((iop_beg = AscSearchIOPortAddrEISA(iop_beg)) != 0) { | 8441 | } |
8384 | return (iop_beg); | 8442 | |
8385 | } | 8443 | static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code) |
8386 | return (0); | 8444 | { |
8445 | if (asc_dvc->err_code == 0) { | ||
8446 | asc_dvc->err_code = err_code; | ||
8447 | AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W, | ||
8448 | err_code); | ||
8387 | } | 8449 | } |
8388 | return (0); | 8450 | return err_code; |
8389 | } | 8451 | } |
8390 | 8452 | ||
8391 | static PortAddr __init AscSearchIOPortAddr11(PortAddr s_addr) | 8453 | static void AscAckInterrupt(PortAddr iop_base) |
8392 | { | 8454 | { |
8393 | int i; | 8455 | uchar host_flag; |
8394 | PortAddr iop_base; | 8456 | uchar risc_flag; |
8457 | ushort loop; | ||
8395 | 8458 | ||
8396 | for (i = 0; i < ASC_IOADR_TABLE_MAX_IX; i++) { | 8459 | loop = 0; |
8397 | if (_asc_def_iop_base[i] > s_addr) { | 8460 | do { |
8461 | risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B); | ||
8462 | if (loop++ > 0x7FFF) { | ||
8398 | break; | 8463 | break; |
8399 | } | 8464 | } |
8400 | } | 8465 | } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0); |
8401 | for (; i < ASC_IOADR_TABLE_MAX_IX; i++) { | 8466 | host_flag = |
8402 | iop_base = _asc_def_iop_base[i]; | 8467 | AscReadLramByte(iop_base, |
8403 | if (!request_region(iop_base, ASC_IOADR_GAP, "advansys")) { | 8468 | ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT); |
8404 | ASC_DBG1(1, | 8469 | AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, |
8405 | "AscSearchIOPortAddr11: check_region() failed I/O port 0x%x\n", | 8470 | (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT)); |
8406 | iop_base); | 8471 | AscSetChipStatus(iop_base, CIW_INT_ACK); |
8407 | continue; | 8472 | loop = 0; |
8408 | } | 8473 | while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) { |
8409 | ASC_DBG1(1, "AscSearchIOPortAddr11: probing I/O port 0x%x\n", | 8474 | AscSetChipStatus(iop_base, CIW_INT_ACK); |
8410 | iop_base); | 8475 | if (loop++ > 3) { |
8411 | release_region(iop_base, ASC_IOADR_GAP); | 8476 | break; |
8412 | if (AscFindSignature(iop_base)) { | ||
8413 | return (iop_base); | ||
8414 | } | 8477 | } |
8415 | } | 8478 | } |
8416 | return (0); | 8479 | AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag); |
8417 | } | 8480 | } |
8418 | 8481 | ||
8419 | static void __init AscSetISAPNPWaitForKey(void) | 8482 | static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time) |
8420 | { | 8483 | { |
8421 | outp(ASC_ISA_PNP_PORT_ADDR, 0x02); | 8484 | const uchar *period_table; |
8422 | outp(ASC_ISA_PNP_PORT_WRITE, 0x02); | 8485 | int max_index; |
8423 | return; | 8486 | int min_index; |
8487 | int i; | ||
8488 | |||
8489 | period_table = asc_dvc->sdtr_period_tbl; | ||
8490 | max_index = (int)asc_dvc->max_sdtr_index; | ||
8491 | min_index = (int)asc_dvc->min_sdtr_index; | ||
8492 | if ((syn_time <= period_table[max_index])) { | ||
8493 | for (i = min_index; i < (max_index - 1); i++) { | ||
8494 | if (syn_time <= period_table[i]) { | ||
8495 | return (uchar)i; | ||
8496 | } | ||
8497 | } | ||
8498 | return (uchar)max_index; | ||
8499 | } else { | ||
8500 | return (uchar)(max_index + 1); | ||
8501 | } | ||
8424 | } | 8502 | } |
8425 | #endif /* CONFIG_ISA */ | ||
8426 | 8503 | ||
8427 | static void __init AscToggleIRQAct(PortAddr iop_base) | 8504 | static uchar |
8505 | AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset) | ||
8428 | { | 8506 | { |
8429 | AscSetChipStatus(iop_base, CIW_IRQ_ACT); | 8507 | EXT_MSG sdtr_buf; |
8430 | AscSetChipStatus(iop_base, 0); | 8508 | uchar sdtr_period_index; |
8431 | return; | 8509 | PortAddr iop_base; |
8510 | |||
8511 | iop_base = asc_dvc->iop_base; | ||
8512 | sdtr_buf.msg_type = EXTENDED_MESSAGE; | ||
8513 | sdtr_buf.msg_len = MS_SDTR_LEN; | ||
8514 | sdtr_buf.msg_req = EXTENDED_SDTR; | ||
8515 | sdtr_buf.xfer_period = sdtr_period; | ||
8516 | sdtr_offset &= ASC_SYN_MAX_OFFSET; | ||
8517 | sdtr_buf.req_ack_offset = sdtr_offset; | ||
8518 | sdtr_period_index = AscGetSynPeriodIndex(asc_dvc, sdtr_period); | ||
8519 | if (sdtr_period_index <= asc_dvc->max_sdtr_index) { | ||
8520 | AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG, | ||
8521 | (uchar *)&sdtr_buf, | ||
8522 | sizeof(EXT_MSG) >> 1); | ||
8523 | return ((sdtr_period_index << 4) | sdtr_offset); | ||
8524 | } else { | ||
8525 | sdtr_buf.req_ack_offset = 0; | ||
8526 | AscMemWordCopyPtrToLram(iop_base, ASCV_MSGOUT_BEG, | ||
8527 | (uchar *)&sdtr_buf, | ||
8528 | sizeof(EXT_MSG) >> 1); | ||
8529 | return 0; | ||
8530 | } | ||
8432 | } | 8531 | } |
8433 | 8532 | ||
8434 | static uchar __init AscGetChipIRQ(PortAddr iop_base, ushort bus_type) | 8533 | static uchar |
8534 | AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset) | ||
8435 | { | 8535 | { |
8436 | ushort cfg_lsw; | 8536 | uchar byte; |
8437 | uchar chip_irq; | 8537 | uchar sdtr_period_ix; |
8438 | 8538 | ||
8439 | if ((bus_type & ASC_IS_EISA) != 0) { | 8539 | sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period); |
8440 | cfg_lsw = AscGetEisaChipCfg(iop_base); | 8540 | if (sdtr_period_ix > asc_dvc->max_sdtr_index) |
8441 | chip_irq = (uchar)(((cfg_lsw >> 8) & 0x07) + 10); | 8541 | return 0xFF; |
8442 | if ((chip_irq == 13) || (chip_irq > 15)) { | 8542 | byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET); |
8443 | return (0); | 8543 | return byte; |
8444 | } | ||
8445 | return (chip_irq); | ||
8446 | } | ||
8447 | if ((bus_type & ASC_IS_VL) != 0) { | ||
8448 | cfg_lsw = AscGetChipCfgLsw(iop_base); | ||
8449 | chip_irq = (uchar)(((cfg_lsw >> 2) & 0x07)); | ||
8450 | if ((chip_irq == 0) || (chip_irq == 4) || (chip_irq == 7)) { | ||
8451 | return (0); | ||
8452 | } | ||
8453 | return ((uchar)(chip_irq + (ASC_MIN_IRQ_NO - 1))); | ||
8454 | } | ||
8455 | cfg_lsw = AscGetChipCfgLsw(iop_base); | ||
8456 | chip_irq = (uchar)(((cfg_lsw >> 2) & 0x03)); | ||
8457 | if (chip_irq == 3) | ||
8458 | chip_irq += (uchar)2; | ||
8459 | return ((uchar)(chip_irq + ASC_MIN_IRQ_NO)); | ||
8460 | } | 8544 | } |
8461 | 8545 | ||
8462 | static uchar __init | 8546 | static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data) |
8463 | AscSetChipIRQ(PortAddr iop_base, uchar irq_no, ushort bus_type) | ||
8464 | { | 8547 | { |
8465 | ushort cfg_lsw; | 8548 | ASC_SCSI_BIT_ID_TYPE org_id; |
8549 | int i; | ||
8550 | int sta = TRUE; | ||
8466 | 8551 | ||
8467 | if ((bus_type & ASC_IS_VL) != 0) { | 8552 | AscSetBank(iop_base, 1); |
8468 | if (irq_no != 0) { | 8553 | org_id = AscReadChipDvcID(iop_base); |
8469 | if ((irq_no < ASC_MIN_IRQ_NO) | 8554 | for (i = 0; i <= ASC_MAX_TID; i++) { |
8470 | || (irq_no > ASC_MAX_IRQ_NO)) { | 8555 | if (org_id == (0x01 << i)) |
8471 | irq_no = 0; | 8556 | break; |
8472 | } else { | 8557 | } |
8473 | irq_no -= (uchar)((ASC_MIN_IRQ_NO - 1)); | 8558 | org_id = (ASC_SCSI_BIT_ID_TYPE) i; |
8474 | } | 8559 | AscWriteChipDvcID(iop_base, id); |
8560 | if (AscReadChipDvcID(iop_base) == (0x01 << id)) { | ||
8561 | AscSetBank(iop_base, 0); | ||
8562 | AscSetChipSyn(iop_base, sdtr_data); | ||
8563 | if (AscGetChipSyn(iop_base) != sdtr_data) { | ||
8564 | sta = FALSE; | ||
8475 | } | 8565 | } |
8476 | cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE3); | 8566 | } else { |
8477 | cfg_lsw |= (ushort)0x0010; | 8567 | sta = FALSE; |
8478 | AscSetChipCfgLsw(iop_base, cfg_lsw); | ||
8479 | AscToggleIRQAct(iop_base); | ||
8480 | cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFE0); | ||
8481 | cfg_lsw |= (ushort)((irq_no & 0x07) << 2); | ||
8482 | AscSetChipCfgLsw(iop_base, cfg_lsw); | ||
8483 | AscToggleIRQAct(iop_base); | ||
8484 | return (AscGetChipIRQ(iop_base, bus_type)); | ||
8485 | } | ||
8486 | if ((bus_type & (ASC_IS_ISA)) != 0) { | ||
8487 | if (irq_no == 15) | ||
8488 | irq_no -= (uchar)2; | ||
8489 | irq_no -= (uchar)ASC_MIN_IRQ_NO; | ||
8490 | cfg_lsw = (ushort)(AscGetChipCfgLsw(iop_base) & 0xFFF3); | ||
8491 | cfg_lsw |= (ushort)((irq_no & 0x03) << 2); | ||
8492 | AscSetChipCfgLsw(iop_base, cfg_lsw); | ||
8493 | return (AscGetChipIRQ(iop_base, bus_type)); | ||
8494 | } | 8568 | } |
8495 | return (0); | 8569 | AscSetBank(iop_base, 1); |
8570 | AscWriteChipDvcID(iop_base, org_id); | ||
8571 | AscSetBank(iop_base, 0); | ||
8572 | return (sta); | ||
8496 | } | 8573 | } |
8497 | 8574 | ||
8498 | #ifdef CONFIG_ISA | 8575 | static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no) |
8499 | static void __init AscEnableIsaDma(uchar dma_channel) | ||
8500 | { | 8576 | { |
8501 | if (dma_channel < 4) { | 8577 | AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data); |
8502 | outp(0x000B, (ushort)(0xC0 | dma_channel)); | 8578 | AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data); |
8503 | outp(0x000A, dma_channel); | ||
8504 | } else if (dma_channel < 8) { | ||
8505 | outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4))); | ||
8506 | outp(0x00D4, (ushort)(dma_channel - 4)); | ||
8507 | } | ||
8508 | return; | ||
8509 | } | 8579 | } |
8510 | #endif /* CONFIG_ISA */ | ||
8511 | 8580 | ||
8512 | static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) | 8581 | static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) |
8513 | { | 8582 | { |
@@ -8528,9 +8597,9 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) | |||
8528 | uchar cur_dvc_qng; | 8597 | uchar cur_dvc_qng; |
8529 | uchar asyn_sdtr; | 8598 | uchar asyn_sdtr; |
8530 | uchar scsi_status; | 8599 | uchar scsi_status; |
8531 | asc_board_t *boardp; | 8600 | struct asc_board *boardp; |
8532 | 8601 | ||
8533 | ASC_ASSERT(asc_dvc->drv_ptr != NULL); | 8602 | BUG_ON(!asc_dvc->drv_ptr); |
8534 | boardp = asc_dvc->drv_ptr; | 8603 | boardp = asc_dvc->drv_ptr; |
8535 | 8604 | ||
8536 | iop_base = asc_dvc->iop_base; | 8605 | iop_base = asc_dvc->iop_base; |
@@ -8541,8 +8610,7 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) | |||
8541 | target_ix = AscReadLramByte(iop_base, | 8610 | target_ix = AscReadLramByte(iop_base, |
8542 | (ushort)(halt_q_addr + | 8611 | (ushort)(halt_q_addr + |
8543 | (ushort)ASC_SCSIQ_B_TARGET_IX)); | 8612 | (ushort)ASC_SCSIQ_B_TARGET_IX)); |
8544 | q_cntl = | 8613 | q_cntl = AscReadLramByte(iop_base, |
8545 | AscReadLramByte(iop_base, | ||
8546 | (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL)); | 8614 | (ushort)(halt_q_addr + (ushort)ASC_SCSIQ_B_CNTL)); |
8547 | tid_no = ASC_TIX_TO_TID(target_ix); | 8615 | tid_no = ASC_TIX_TO_TID(target_ix); |
8548 | target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no); | 8616 | target_id = (uchar)ASC_TID_TO_TARGET_ID(tid_no); |
@@ -8566,14 +8634,13 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) | |||
8566 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); | 8634 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); |
8567 | return (0); | 8635 | return (0); |
8568 | } else if (int_halt_code == ASC_HALT_EXTMSG_IN) { | 8636 | } else if (int_halt_code == ASC_HALT_EXTMSG_IN) { |
8569 | |||
8570 | AscMemWordCopyPtrFromLram(iop_base, | 8637 | AscMemWordCopyPtrFromLram(iop_base, |
8571 | ASCV_MSGIN_BEG, | 8638 | ASCV_MSGIN_BEG, |
8572 | (uchar *)&ext_msg, | 8639 | (uchar *)&ext_msg, |
8573 | sizeof(EXT_MSG) >> 1); | 8640 | sizeof(EXT_MSG) >> 1); |
8574 | 8641 | ||
8575 | if (ext_msg.msg_type == MS_EXTEND && | 8642 | if (ext_msg.msg_type == EXTENDED_MESSAGE && |
8576 | ext_msg.msg_req == MS_SDTR_CODE && | 8643 | ext_msg.msg_req == EXTENDED_SDTR && |
8577 | ext_msg.msg_len == MS_SDTR_LEN) { | 8644 | ext_msg.msg_len == MS_SDTR_LEN) { |
8578 | sdtr_accept = TRUE; | 8645 | sdtr_accept = TRUE; |
8579 | if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) { | 8646 | if ((ext_msg.req_ack_offset > ASC_SYN_MAX_OFFSET)) { |
@@ -8582,15 +8649,14 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) | |||
8582 | ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET; | 8649 | ext_msg.req_ack_offset = ASC_SYN_MAX_OFFSET; |
8583 | } | 8650 | } |
8584 | if ((ext_msg.xfer_period < | 8651 | if ((ext_msg.xfer_period < |
8585 | asc_dvc->sdtr_period_tbl[asc_dvc-> | 8652 | asc_dvc->sdtr_period_tbl[asc_dvc->min_sdtr_index]) |
8586 | host_init_sdtr_index]) | ||
8587 | || (ext_msg.xfer_period > | 8653 | || (ext_msg.xfer_period > |
8588 | asc_dvc->sdtr_period_tbl[asc_dvc-> | 8654 | asc_dvc->sdtr_period_tbl[asc_dvc-> |
8589 | max_sdtr_index])) { | 8655 | max_sdtr_index])) { |
8590 | sdtr_accept = FALSE; | 8656 | sdtr_accept = FALSE; |
8591 | ext_msg.xfer_period = | 8657 | ext_msg.xfer_period = |
8592 | asc_dvc->sdtr_period_tbl[asc_dvc-> | 8658 | asc_dvc->sdtr_period_tbl[asc_dvc-> |
8593 | host_init_sdtr_index]; | 8659 | min_sdtr_index]; |
8594 | } | 8660 | } |
8595 | if (sdtr_accept) { | 8661 | if (sdtr_accept) { |
8596 | sdtr_data = | 8662 | sdtr_data = |
@@ -8614,7 +8680,6 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) | |||
8614 | AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); | 8680 | AscSetChipSDTR(iop_base, asyn_sdtr, tid_no); |
8615 | } else { | 8681 | } else { |
8616 | if (sdtr_accept && (q_cntl & QC_MSG_OUT)) { | 8682 | if (sdtr_accept && (q_cntl & QC_MSG_OUT)) { |
8617 | |||
8618 | q_cntl &= ~QC_MSG_OUT; | 8683 | q_cntl &= ~QC_MSG_OUT; |
8619 | asc_dvc->sdtr_done |= target_id; | 8684 | asc_dvc->sdtr_done |= target_id; |
8620 | asc_dvc->init_sdtr |= target_id; | 8685 | asc_dvc->init_sdtr |= target_id; |
@@ -8629,7 +8694,6 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) | |||
8629 | tid_no); | 8694 | tid_no); |
8630 | boardp->sdtr_data[tid_no] = sdtr_data; | 8695 | boardp->sdtr_data[tid_no] = sdtr_data; |
8631 | } else { | 8696 | } else { |
8632 | |||
8633 | q_cntl |= QC_MSG_OUT; | 8697 | q_cntl |= QC_MSG_OUT; |
8634 | AscMsgOutSDTR(asc_dvc, | 8698 | AscMsgOutSDTR(asc_dvc, |
8635 | ext_msg.xfer_period, | 8699 | ext_msg.xfer_period, |
@@ -8655,8 +8719,8 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) | |||
8655 | q_cntl); | 8719 | q_cntl); |
8656 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); | 8720 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); |
8657 | return (0); | 8721 | return (0); |
8658 | } else if (ext_msg.msg_type == MS_EXTEND && | 8722 | } else if (ext_msg.msg_type == EXTENDED_MESSAGE && |
8659 | ext_msg.msg_req == MS_WDTR_CODE && | 8723 | ext_msg.msg_req == EXTENDED_WDTR && |
8660 | ext_msg.msg_len == MS_WDTR_LEN) { | 8724 | ext_msg.msg_len == MS_WDTR_LEN) { |
8661 | 8725 | ||
8662 | ext_msg.wdtr_width = 0; | 8726 | ext_msg.wdtr_width = 0; |
@@ -8749,9 +8813,9 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) | |||
8749 | (uchar *)&out_msg, | 8813 | (uchar *)&out_msg, |
8750 | sizeof(EXT_MSG) >> 1); | 8814 | sizeof(EXT_MSG) >> 1); |
8751 | 8815 | ||
8752 | if ((out_msg.msg_type == MS_EXTEND) && | 8816 | if ((out_msg.msg_type == EXTENDED_MESSAGE) && |
8753 | (out_msg.msg_len == MS_SDTR_LEN) && | 8817 | (out_msg.msg_len == MS_SDTR_LEN) && |
8754 | (out_msg.msg_req == MS_SDTR_CODE)) { | 8818 | (out_msg.msg_req == EXTENDED_SDTR)) { |
8755 | 8819 | ||
8756 | asc_dvc->init_sdtr &= ~target_id; | 8820 | asc_dvc->init_sdtr &= ~target_id; |
8757 | asc_dvc->sdtr_done &= ~target_id; | 8821 | asc_dvc->sdtr_done &= ~target_id; |
@@ -8797,9 +8861,9 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) | |||
8797 | cur_dvc_qng); | 8861 | cur_dvc_qng); |
8798 | 8862 | ||
8799 | /* | 8863 | /* |
8800 | * Set the device queue depth to the number of | 8864 | * Set the device queue depth to the |
8801 | * active requests when the QUEUE FULL condition | 8865 | * number of active requests when the |
8802 | * was encountered. | 8866 | * QUEUE FULL condition was encountered. |
8803 | */ | 8867 | */ |
8804 | boardp->queue_full |= target_id; | 8868 | boardp->queue_full |= target_id; |
8805 | boardp->queue_full_cnt[tid_no] = | 8869 | boardp->queue_full_cnt[tid_no] = |
@@ -8825,9 +8889,8 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) | |||
8825 | int i; | 8889 | int i; |
8826 | 8890 | ||
8827 | q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP); | 8891 | q_no = AscReadLramByte(iop_base, (ushort)ASCV_REQ_SG_LIST_QP); |
8828 | if (q_no == ASC_QLINK_END) { | 8892 | if (q_no == ASC_QLINK_END) |
8829 | return (0); | 8893 | return 0; |
8830 | } | ||
8831 | 8894 | ||
8832 | q_addr = ASC_QNO_TO_QADDR(q_no); | 8895 | q_addr = ASC_QNO_TO_QADDR(q_no); |
8833 | 8896 | ||
@@ -8879,8 +8942,8 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) | |||
8879 | sg_entry_cnt = ASC_MAX_SG_LIST - 1; | 8942 | sg_entry_cnt = ASC_MAX_SG_LIST - 1; |
8880 | 8943 | ||
8881 | /* | 8944 | /* |
8882 | * Keep track of remaining number of SG elements that will | 8945 | * Keep track of remaining number of SG elements that |
8883 | * need to be handled on the next interrupt. | 8946 | * will need to be handled on the next interrupt. |
8884 | */ | 8947 | */ |
8885 | scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1); | 8948 | scsiq->remain_sg_entry_cnt -= (ASC_MAX_SG_LIST - 1); |
8886 | } else { | 8949 | } else { |
@@ -8971,6 +9034,34 @@ static int AscIsrChipHalted(ASC_DVC_VAR *asc_dvc) | |||
8971 | return (0); | 9034 | return (0); |
8972 | } | 9035 | } |
8973 | 9036 | ||
9037 | /* | ||
9038 | * void | ||
9039 | * DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words) | ||
9040 | * | ||
9041 | * Calling/Exit State: | ||
9042 | * none | ||
9043 | * | ||
9044 | * Description: | ||
9045 | * Input an ASC_QDONE_INFO structure from the chip | ||
9046 | */ | ||
9047 | static void | ||
9048 | DvcGetQinfo(PortAddr iop_base, ushort s_addr, uchar *inbuf, int words) | ||
9049 | { | ||
9050 | int i; | ||
9051 | ushort word; | ||
9052 | |||
9053 | AscSetChipLramAddr(iop_base, s_addr); | ||
9054 | for (i = 0; i < 2 * words; i += 2) { | ||
9055 | if (i == 10) { | ||
9056 | continue; | ||
9057 | } | ||
9058 | word = inpw(iop_base + IOP_RAM_DATA); | ||
9059 | inbuf[i] = word & 0xff; | ||
9060 | inbuf[i + 1] = (word >> 8) & 0xff; | ||
9061 | } | ||
9062 | ASC_DBG_PRT_HEX(2, "DvcGetQinfo", inbuf, 2 * words); | ||
9063 | } | ||
9064 | |||
8974 | static uchar | 9065 | static uchar |
8975 | _AscCopyLramScsiDoneQ(PortAddr iop_base, | 9066 | _AscCopyLramScsiDoneQ(PortAddr iop_base, |
8976 | ushort q_addr, | 9067 | ushort q_addr, |
@@ -9014,7 +9105,124 @@ _AscCopyLramScsiDoneQ(PortAddr iop_base, | |||
9014 | ASC_SCSIQ_DW_REMAIN_XFER_CNT)); | 9105 | ASC_SCSIQ_DW_REMAIN_XFER_CNT)); |
9015 | 9106 | ||
9016 | scsiq->remain_bytes &= max_dma_count; | 9107 | scsiq->remain_bytes &= max_dma_count; |
9017 | return (sg_queue_cnt); | 9108 | return sg_queue_cnt; |
9109 | } | ||
9110 | |||
9111 | /* | ||
9112 | * asc_isr_callback() - Second Level Interrupt Handler called by AscISR(). | ||
9113 | * | ||
9114 | * Interrupt callback function for the Narrow SCSI Asc Library. | ||
9115 | */ | ||
9116 | static void asc_isr_callback(ASC_DVC_VAR *asc_dvc_varp, ASC_QDONE_INFO *qdonep) | ||
9117 | { | ||
9118 | struct asc_board *boardp; | ||
9119 | struct scsi_cmnd *scp; | ||
9120 | struct Scsi_Host *shost; | ||
9121 | |||
9122 | ASC_DBG(1, "asc_dvc_varp 0x%p, qdonep 0x%p\n", asc_dvc_varp, qdonep); | ||
9123 | ASC_DBG_PRT_ASC_QDONE_INFO(2, qdonep); | ||
9124 | |||
9125 | scp = advansys_srb_to_ptr(asc_dvc_varp, qdonep->d2.srb_ptr); | ||
9126 | if (!scp) | ||
9127 | return; | ||
9128 | |||
9129 | ASC_DBG_PRT_CDB(2, scp->cmnd, scp->cmd_len); | ||
9130 | |||
9131 | shost = scp->device->host; | ||
9132 | ASC_STATS(shost, callback); | ||
9133 | ASC_DBG(1, "shost 0x%p\n", shost); | ||
9134 | |||
9135 | boardp = shost_priv(shost); | ||
9136 | BUG_ON(asc_dvc_varp != &boardp->dvc_var.asc_dvc_var); | ||
9137 | |||
9138 | dma_unmap_single(boardp->dev, scp->SCp.dma_handle, | ||
9139 | sizeof(scp->sense_buffer), DMA_FROM_DEVICE); | ||
9140 | /* | ||
9141 | * 'qdonep' contains the command's ending status. | ||
9142 | */ | ||
9143 | switch (qdonep->d3.done_stat) { | ||
9144 | case QD_NO_ERROR: | ||
9145 | ASC_DBG(2, "QD_NO_ERROR\n"); | ||
9146 | scp->result = 0; | ||
9147 | |||
9148 | /* | ||
9149 | * Check for an underrun condition. | ||
9150 | * | ||
9151 | * If there was no error and an underrun condition, then | ||
9152 | * return the number of underrun bytes. | ||
9153 | */ | ||
9154 | if (scsi_bufflen(scp) != 0 && qdonep->remain_bytes != 0 && | ||
9155 | qdonep->remain_bytes <= scsi_bufflen(scp)) { | ||
9156 | ASC_DBG(1, "underrun condition %u bytes\n", | ||
9157 | (unsigned)qdonep->remain_bytes); | ||
9158 | scsi_set_resid(scp, qdonep->remain_bytes); | ||
9159 | } | ||
9160 | break; | ||
9161 | |||
9162 | case QD_WITH_ERROR: | ||
9163 | ASC_DBG(2, "QD_WITH_ERROR\n"); | ||
9164 | switch (qdonep->d3.host_stat) { | ||
9165 | case QHSTA_NO_ERROR: | ||
9166 | if (qdonep->d3.scsi_stat == SAM_STAT_CHECK_CONDITION) { | ||
9167 | ASC_DBG(2, "SAM_STAT_CHECK_CONDITION\n"); | ||
9168 | ASC_DBG_PRT_SENSE(2, scp->sense_buffer, | ||
9169 | sizeof(scp->sense_buffer)); | ||
9170 | /* | ||
9171 | * Note: The 'status_byte()' macro used by | ||
9172 | * target drivers defined in scsi.h shifts the | ||
9173 | * status byte returned by host drivers right | ||
9174 | * by 1 bit. This is why target drivers also | ||
9175 | * use right shifted status byte definitions. | ||
9176 | * For instance target drivers use | ||
9177 | * CHECK_CONDITION, defined to 0x1, instead of | ||
9178 | * the SCSI defined check condition value of | ||
9179 | * 0x2. Host drivers are supposed to return | ||
9180 | * the status byte as it is defined by SCSI. | ||
9181 | */ | ||
9182 | scp->result = DRIVER_BYTE(DRIVER_SENSE) | | ||
9183 | STATUS_BYTE(qdonep->d3.scsi_stat); | ||
9184 | } else { | ||
9185 | scp->result = STATUS_BYTE(qdonep->d3.scsi_stat); | ||
9186 | } | ||
9187 | break; | ||
9188 | |||
9189 | default: | ||
9190 | /* QHSTA error occurred */ | ||
9191 | ASC_DBG(1, "host_stat 0x%x\n", qdonep->d3.host_stat); | ||
9192 | scp->result = HOST_BYTE(DID_BAD_TARGET); | ||
9193 | break; | ||
9194 | } | ||
9195 | break; | ||
9196 | |||
9197 | case QD_ABORTED_BY_HOST: | ||
9198 | ASC_DBG(1, "QD_ABORTED_BY_HOST\n"); | ||
9199 | scp->result = | ||
9200 | HOST_BYTE(DID_ABORT) | MSG_BYTE(qdonep->d3. | ||
9201 | scsi_msg) | | ||
9202 | STATUS_BYTE(qdonep->d3.scsi_stat); | ||
9203 | break; | ||
9204 | |||
9205 | default: | ||
9206 | ASC_DBG(1, "done_stat 0x%x\n", qdonep->d3.done_stat); | ||
9207 | scp->result = | ||
9208 | HOST_BYTE(DID_ERROR) | MSG_BYTE(qdonep->d3. | ||
9209 | scsi_msg) | | ||
9210 | STATUS_BYTE(qdonep->d3.scsi_stat); | ||
9211 | break; | ||
9212 | } | ||
9213 | |||
9214 | /* | ||
9215 | * If the 'init_tidmask' bit isn't already set for the target and the | ||
9216 | * current request finished normally, then set the bit for the target | ||
9217 | * to indicate that a device is present. | ||
9218 | */ | ||
9219 | if ((boardp->init_tidmask & ADV_TID_TO_TIDMASK(scp->device->id)) == 0 && | ||
9220 | qdonep->d3.done_stat == QD_NO_ERROR && | ||
9221 | qdonep->d3.host_stat == QHSTA_NO_ERROR) { | ||
9222 | boardp->init_tidmask |= ADV_TID_TO_TIDMASK(scp->device->id); | ||
9223 | } | ||
9224 | |||
9225 | asc_scsi_done(scp); | ||
9018 | } | 9226 | } |
9019 | 9227 | ||
9020 | static int AscIsrQDone(ASC_DVC_VAR *asc_dvc) | 9228 | static int AscIsrQDone(ASC_DVC_VAR *asc_dvc) |
@@ -9035,10 +9243,8 @@ static int AscIsrQDone(ASC_DVC_VAR *asc_dvc) | |||
9035 | ASC_QDONE_INFO scsiq_buf; | 9243 | ASC_QDONE_INFO scsiq_buf; |
9036 | ASC_QDONE_INFO *scsiq; | 9244 | ASC_QDONE_INFO *scsiq; |
9037 | int false_overrun; | 9245 | int false_overrun; |
9038 | ASC_ISR_CALLBACK asc_isr_callback; | ||
9039 | 9246 | ||
9040 | iop_base = asc_dvc->iop_base; | 9247 | iop_base = asc_dvc->iop_base; |
9041 | asc_isr_callback = asc_dvc->isr_callback; | ||
9042 | n_q_used = 1; | 9248 | n_q_used = 1; |
9043 | scsiq = (ASC_QDONE_INFO *)&scsiq_buf; | 9249 | scsiq = (ASC_QDONE_INFO *)&scsiq_buf; |
9044 | done_q_tail = (uchar)AscGetVarDoneQTail(iop_base); | 9250 | done_q_tail = (uchar)AscGetVarDoneQTail(iop_base); |
@@ -9141,7 +9347,7 @@ static int AscIsrQDone(ASC_DVC_VAR *asc_dvc) | |||
9141 | AscSetChipControl(iop_base, | 9347 | AscSetChipControl(iop_base, |
9142 | (uchar)(CC_SCSI_RESET | 9348 | (uchar)(CC_SCSI_RESET |
9143 | | CC_HALT)); | 9349 | | CC_HALT)); |
9144 | DvcDelayNanoSecond(asc_dvc, 60000); | 9350 | udelay(60); |
9145 | AscSetChipControl(iop_base, CC_HALT); | 9351 | AscSetChipControl(iop_base, CC_HALT); |
9146 | AscSetChipStatus(iop_base, | 9352 | AscSetChipStatus(iop_base, |
9147 | CIW_CLR_SCSI_RESET_INT); | 9353 | CIW_CLR_SCSI_RESET_INT); |
@@ -9150,7 +9356,7 @@ static int AscIsrQDone(ASC_DVC_VAR *asc_dvc) | |||
9150 | } | 9356 | } |
9151 | } | 9357 | } |
9152 | if ((scsiq->cntl & QC_NO_CALLBACK) == 0) { | 9358 | if ((scsiq->cntl & QC_NO_CALLBACK) == 0) { |
9153 | (*asc_isr_callback) (asc_dvc, scsiq); | 9359 | asc_isr_callback(asc_dvc, scsiq); |
9154 | } else { | 9360 | } else { |
9155 | if ((AscReadLramByte(iop_base, | 9361 | if ((AscReadLramByte(iop_base, |
9156 | (ushort)(q_addr + (ushort) | 9362 | (ushort)(q_addr + (ushort) |
@@ -9168,7 +9374,7 @@ static int AscIsrQDone(ASC_DVC_VAR *asc_dvc) | |||
9168 | AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS); | 9374 | AscSetLibErrorCode(asc_dvc, ASCQ_ERR_Q_STATUS); |
9169 | FATAL_ERR_QDONE: | 9375 | FATAL_ERR_QDONE: |
9170 | if ((scsiq->cntl & QC_NO_CALLBACK) == 0) { | 9376 | if ((scsiq->cntl & QC_NO_CALLBACK) == 0) { |
9171 | (*asc_isr_callback) (asc_dvc, scsiq); | 9377 | asc_isr_callback(asc_dvc, scsiq); |
9172 | } | 9378 | } |
9173 | return (0x80); | 9379 | return (0x80); |
9174 | } | 9380 | } |
@@ -9190,22 +9396,19 @@ static int AscISR(ASC_DVC_VAR *asc_dvc) | |||
9190 | iop_base = asc_dvc->iop_base; | 9396 | iop_base = asc_dvc->iop_base; |
9191 | int_pending = FALSE; | 9397 | int_pending = FALSE; |
9192 | 9398 | ||
9193 | if (AscIsIntPending(iop_base) == 0) { | 9399 | if (AscIsIntPending(iop_base) == 0) |
9194 | return int_pending; | 9400 | return int_pending; |
9195 | } | ||
9196 | 9401 | ||
9197 | if (((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) | 9402 | if ((asc_dvc->init_state & ASC_INIT_STATE_END_LOAD_MC) == 0) { |
9198 | || (asc_dvc->isr_callback == 0) | 9403 | return ERR; |
9199 | ) { | ||
9200 | return (ERR); | ||
9201 | } | 9404 | } |
9202 | if (asc_dvc->in_critical_cnt != 0) { | 9405 | if (asc_dvc->in_critical_cnt != 0) { |
9203 | AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL); | 9406 | AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_ON_CRITICAL); |
9204 | return (ERR); | 9407 | return ERR; |
9205 | } | 9408 | } |
9206 | if (asc_dvc->is_in_int) { | 9409 | if (asc_dvc->is_in_int) { |
9207 | AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY); | 9410 | AscSetLibErrorCode(asc_dvc, ASCQ_ERR_ISR_RE_ENTRY); |
9208 | return (ERR); | 9411 | return ERR; |
9209 | } | 9412 | } |
9210 | asc_dvc->is_in_int = TRUE; | 9413 | asc_dvc->is_in_int = TRUE; |
9211 | ctrl_reg = AscGetChipControl(iop_base); | 9414 | ctrl_reg = AscGetChipControl(iop_base); |
@@ -9220,7 +9423,7 @@ static int AscISR(ASC_DVC_VAR *asc_dvc) | |||
9220 | saved_ctrl_reg &= (uchar)(~CC_HALT); | 9423 | saved_ctrl_reg &= (uchar)(~CC_HALT); |
9221 | while ((AscGetChipStatus(iop_base) & | 9424 | while ((AscGetChipStatus(iop_base) & |
9222 | CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) { | 9425 | CSW_SCSI_RESET_ACTIVE) && (i-- > 0)) { |
9223 | DvcSleepMilliSecond(100); | 9426 | mdelay(100); |
9224 | } | 9427 | } |
9225 | AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT)); | 9428 | AscSetChipControl(iop_base, (CC_CHIP_RESET | CC_HALT)); |
9226 | AscSetChipControl(iop_base, CC_HALT); | 9429 | AscSetChipControl(iop_base, CC_HALT); |
@@ -9235,9 +9438,7 @@ static int AscISR(ASC_DVC_VAR *asc_dvc) | |||
9235 | (uchar)(~ASC_HOST_FLAG_IN_ISR); | 9438 | (uchar)(~ASC_HOST_FLAG_IN_ISR); |
9236 | AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, | 9439 | AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, |
9237 | (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR)); | 9440 | (uchar)(host_flag | (uchar)ASC_HOST_FLAG_IN_ISR)); |
9238 | if ((chipstat & CSW_INT_PENDING) | 9441 | if ((chipstat & CSW_INT_PENDING) || (int_pending)) { |
9239 | || (int_pending) | ||
9240 | ) { | ||
9241 | AscAckInterrupt(iop_base); | 9442 | AscAckInterrupt(iop_base); |
9242 | int_pending = TRUE; | 9443 | int_pending = TRUE; |
9243 | if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) { | 9444 | if ((chipstat & CSW_HALTED) && (ctrl_reg & CC_SINGLE_STEP)) { |
@@ -9268,615 +9469,767 @@ static int AscISR(ASC_DVC_VAR *asc_dvc) | |||
9268 | AscSetChipLramAddr(iop_base, saved_ram_addr); | 9469 | AscSetChipLramAddr(iop_base, saved_ram_addr); |
9269 | AscSetChipControl(iop_base, saved_ctrl_reg); | 9470 | AscSetChipControl(iop_base, saved_ctrl_reg); |
9270 | asc_dvc->is_in_int = FALSE; | 9471 | asc_dvc->is_in_int = FALSE; |
9271 | return (int_pending); | 9472 | return int_pending; |
9272 | } | 9473 | } |
9273 | 9474 | ||
9274 | /* Microcode buffer is kept after initialization for error recovery. */ | 9475 | /* |
9275 | static uchar _asc_mcode_buf[] = { | 9476 | * advansys_reset() |
9276 | 0x01, 0x03, 0x01, 0x19, 0x0F, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 9477 | * |
9277 | 0x00, 0x00, 0x00, 0x00, | 9478 | * Reset the bus associated with the command 'scp'. |
9278 | 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x0F, 0x00, 0x00, 0x00, 0x00, | 9479 | * |
9279 | 0x00, 0x00, 0x00, 0x00, | 9480 | * This function runs its own thread. Interrupts must be blocked but |
9280 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 9481 | * sleeping is allowed and no locking other than for host structures is |
9281 | 0x00, 0x00, 0x00, 0x00, | 9482 | * required. Returns SUCCESS or FAILED. |
9282 | 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | 9483 | */ |
9283 | 0x00, 0x00, 0x00, 0x00, | 9484 | static int advansys_reset(struct scsi_cmnd *scp) |
9284 | 0x00, 0x00, 0x00, 0x00, 0xC3, 0x12, 0x0D, 0x05, 0x01, 0x00, 0x00, 0x00, | 9485 | { |
9285 | 0x00, 0xFF, 0x00, 0x00, | 9486 | struct Scsi_Host *shost = scp->device->host; |
9286 | 0x00, 0x00, 0x00, 0x00, 0xFF, 0x80, 0xFF, 0xFF, 0x01, 0x00, 0x00, 0x00, | 9487 | struct asc_board *boardp = shost_priv(shost); |
9287 | 0x00, 0x00, 0x00, 0x00, | 9488 | unsigned long flags; |
9288 | 0x00, 0x00, 0x00, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x00, 0xFF, | 9489 | int status; |
9289 | 0x00, 0x00, 0x00, 0x00, | 9490 | int ret = SUCCESS; |
9290 | 0xFF, 0xFF, 0xFF, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xE4, 0x88, | ||
9291 | 0x00, 0x00, 0x00, 0x00, | ||
9292 | 0x80, 0x73, 0x48, 0x04, 0x36, 0x00, 0x00, 0xA2, 0xC2, 0x00, 0x80, 0x73, | ||
9293 | 0x03, 0x23, 0x36, 0x40, | ||
9294 | 0xB6, 0x00, 0x36, 0x00, 0x05, 0xD6, 0x0C, 0xD2, 0x12, 0xDA, 0x00, 0xA2, | ||
9295 | 0xC2, 0x00, 0x92, 0x80, | ||
9296 | 0x1E, 0x98, 0x50, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xDF, 0x23, 0x36, 0x60, | ||
9297 | 0xB6, 0x00, 0x92, 0x80, | ||
9298 | 0x4F, 0x00, 0xF5, 0x00, 0x48, 0x98, 0xEF, 0x23, 0x36, 0x60, 0xB6, 0x00, | ||
9299 | 0x92, 0x80, 0x80, 0x62, | ||
9300 | 0x92, 0x80, 0x00, 0x46, 0x15, 0xEE, 0x13, 0xEA, 0x02, 0x01, 0x09, 0xD8, | ||
9301 | 0xCD, 0x04, 0x4D, 0x00, | ||
9302 | 0x00, 0xA3, 0xD6, 0x00, 0xA6, 0x97, 0x7F, 0x23, 0x04, 0x61, 0x84, 0x01, | ||
9303 | 0xE6, 0x84, 0xD2, 0xC1, | ||
9304 | 0x80, 0x73, 0xCD, 0x04, 0x4D, 0x00, 0x00, 0xA3, 0xDA, 0x01, 0xA6, 0x97, | ||
9305 | 0xC6, 0x81, 0xC2, 0x88, | ||
9306 | 0x80, 0x73, 0x80, 0x77, 0x00, 0x01, 0x01, 0xA1, 0xFE, 0x00, 0x4F, 0x00, | ||
9307 | 0x84, 0x97, 0x07, 0xA6, | ||
9308 | 0x08, 0x01, 0x00, 0x33, 0x03, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x01, 0xDE, | ||
9309 | 0xC2, 0x88, 0xCE, 0x00, | ||
9310 | 0x69, 0x60, 0xCE, 0x00, 0x02, 0x03, 0x4A, 0x60, 0x00, 0xA2, 0x78, 0x01, | ||
9311 | 0x80, 0x63, 0x07, 0xA6, | ||
9312 | 0x24, 0x01, 0x78, 0x81, 0x03, 0x03, 0x80, 0x63, 0xE2, 0x00, 0x07, 0xA6, | ||
9313 | 0x34, 0x01, 0x00, 0x33, | ||
9314 | 0x04, 0x00, 0xC2, 0x88, 0x03, 0x07, 0x02, 0x01, 0x04, 0xCA, 0x0D, 0x23, | ||
9315 | 0x68, 0x98, 0x4D, 0x04, | ||
9316 | 0x04, 0x85, 0x05, 0xD8, 0x0D, 0x23, 0x68, 0x98, 0xCD, 0x04, 0x15, 0x23, | ||
9317 | 0xF8, 0x88, 0xFB, 0x23, | ||
9318 | 0x02, 0x61, 0x82, 0x01, 0x80, 0x63, 0x02, 0x03, 0x06, 0xA3, 0x62, 0x01, | ||
9319 | 0x00, 0x33, 0x0A, 0x00, | ||
9320 | 0xC2, 0x88, 0x4E, 0x00, 0x07, 0xA3, 0x6E, 0x01, 0x00, 0x33, 0x0B, 0x00, | ||
9321 | 0xC2, 0x88, 0xCD, 0x04, | ||
9322 | 0x36, 0x2D, 0x00, 0x33, 0x1A, 0x00, 0xC2, 0x88, 0x50, 0x04, 0x88, 0x81, | ||
9323 | 0x06, 0xAB, 0x82, 0x01, | ||
9324 | 0x88, 0x81, 0x4E, 0x00, 0x07, 0xA3, 0x92, 0x01, 0x50, 0x00, 0x00, 0xA3, | ||
9325 | 0x3C, 0x01, 0x00, 0x05, | ||
9326 | 0x7C, 0x81, 0x46, 0x97, 0x02, 0x01, 0x05, 0xC6, 0x04, 0x23, 0xA0, 0x01, | ||
9327 | 0x15, 0x23, 0xA1, 0x01, | ||
9328 | 0xBE, 0x81, 0xFD, 0x23, 0x02, 0x61, 0x82, 0x01, 0x0A, 0xDA, 0x4A, 0x00, | ||
9329 | 0x06, 0x61, 0x00, 0xA0, | ||
9330 | 0xB4, 0x01, 0x80, 0x63, 0xCD, 0x04, 0x36, 0x2D, 0x00, 0x33, 0x1B, 0x00, | ||
9331 | 0xC2, 0x88, 0x06, 0x23, | ||
9332 | 0x68, 0x98, 0xCD, 0x04, 0xE6, 0x84, 0x06, 0x01, 0x00, 0xA2, 0xD4, 0x01, | ||
9333 | 0x57, 0x60, 0x00, 0xA0, | ||
9334 | 0xDA, 0x01, 0xE6, 0x84, 0x80, 0x23, 0xA0, 0x01, 0xE6, 0x84, 0x80, 0x73, | ||
9335 | 0x4B, 0x00, 0x06, 0x61, | ||
9336 | 0x00, 0xA2, 0x00, 0x02, 0x04, 0x01, 0x0C, 0xDE, 0x02, 0x01, 0x03, 0xCC, | ||
9337 | 0x4F, 0x00, 0x84, 0x97, | ||
9338 | 0xFC, 0x81, 0x08, 0x23, 0x02, 0x41, 0x82, 0x01, 0x4F, 0x00, 0x62, 0x97, | ||
9339 | 0x48, 0x04, 0x84, 0x80, | ||
9340 | 0xF0, 0x97, 0x00, 0x46, 0x56, 0x00, 0x03, 0xC0, 0x01, 0x23, 0xE8, 0x00, | ||
9341 | 0x81, 0x73, 0x06, 0x29, | ||
9342 | 0x03, 0x42, 0x06, 0xE2, 0x03, 0xEE, 0x6B, 0xEB, 0x11, 0x23, 0xF8, 0x88, | ||
9343 | 0x04, 0x98, 0xF0, 0x80, | ||
9344 | 0x80, 0x73, 0x80, 0x77, 0x07, 0xA4, 0x2A, 0x02, 0x7C, 0x95, 0x06, 0xA6, | ||
9345 | 0x34, 0x02, 0x03, 0xA6, | ||
9346 | 0x4C, 0x04, 0x46, 0x82, 0x04, 0x01, 0x03, 0xD8, 0xB4, 0x98, 0x6A, 0x96, | ||
9347 | 0x46, 0x82, 0xFE, 0x95, | ||
9348 | 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, 0xB6, 0x2D, 0x02, 0xA6, 0x6C, 0x02, | ||
9349 | 0x07, 0xA6, 0x5A, 0x02, | ||
9350 | 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x62, 0x02, 0xC2, 0x88, 0x7C, 0x95, | ||
9351 | 0x48, 0x82, 0x60, 0x96, | ||
9352 | 0x48, 0x82, 0x04, 0x23, 0xA0, 0x01, 0x14, 0x23, 0xA1, 0x01, 0x3C, 0x84, | ||
9353 | 0x04, 0x01, 0x0C, 0xDC, | ||
9354 | 0xE0, 0x23, 0x25, 0x61, 0xEF, 0x00, 0x14, 0x01, 0x4F, 0x04, 0xA8, 0x01, | ||
9355 | 0x6F, 0x00, 0xA5, 0x01, | ||
9356 | 0x03, 0x23, 0xA4, 0x01, 0x06, 0x23, 0x9C, 0x01, 0x24, 0x2B, 0x1C, 0x01, | ||
9357 | 0x02, 0xA6, 0xAA, 0x02, | ||
9358 | 0x07, 0xA6, 0x5A, 0x02, 0x06, 0xA6, 0x5E, 0x02, 0x03, 0xA6, 0x20, 0x04, | ||
9359 | 0x01, 0xA6, 0xB4, 0x02, | ||
9360 | 0x00, 0xA6, 0xB4, 0x02, 0x00, 0x33, 0x12, 0x00, 0xC2, 0x88, 0x00, 0x0E, | ||
9361 | 0x80, 0x63, 0x00, 0x43, | ||
9362 | 0x00, 0xA0, 0x8C, 0x02, 0x4D, 0x04, 0x04, 0x01, 0x0B, 0xDC, 0xE7, 0x23, | ||
9363 | 0x04, 0x61, 0x84, 0x01, | ||
9364 | 0x10, 0x31, 0x12, 0x35, 0x14, 0x01, 0xEC, 0x00, 0x6C, 0x38, 0x00, 0x3F, | ||
9365 | 0x00, 0x00, 0xEA, 0x82, | ||
9366 | 0x18, 0x23, 0x04, 0x61, 0x18, 0xA0, 0xE2, 0x02, 0x04, 0x01, 0xA2, 0xC8, | ||
9367 | 0x00, 0x33, 0x1F, 0x00, | ||
9368 | 0xC2, 0x88, 0x08, 0x31, 0x0A, 0x35, 0x0C, 0x39, 0x0E, 0x3D, 0x7E, 0x98, | ||
9369 | 0xB6, 0x2D, 0x01, 0xA6, | ||
9370 | 0x14, 0x03, 0x00, 0xA6, 0x14, 0x03, 0x07, 0xA6, 0x0C, 0x03, 0x06, 0xA6, | ||
9371 | 0x10, 0x03, 0x03, 0xA6, | ||
9372 | 0x20, 0x04, 0x02, 0xA6, 0x6C, 0x02, 0x00, 0x33, 0x33, 0x00, 0xC2, 0x88, | ||
9373 | 0x7C, 0x95, 0xEE, 0x82, | ||
9374 | 0x60, 0x96, 0xEE, 0x82, 0x82, 0x98, 0x80, 0x42, 0x7E, 0x98, 0x64, 0xE4, | ||
9375 | 0x04, 0x01, 0x2D, 0xC8, | ||
9376 | 0x31, 0x05, 0x07, 0x01, 0x00, 0xA2, 0x54, 0x03, 0x00, 0x43, 0x87, 0x01, | ||
9377 | 0x05, 0x05, 0x86, 0x98, | ||
9378 | 0x7E, 0x98, 0x00, 0xA6, 0x16, 0x03, 0x07, 0xA6, 0x4C, 0x03, 0x03, 0xA6, | ||
9379 | 0x3C, 0x04, 0x06, 0xA6, | ||
9380 | 0x50, 0x03, 0x01, 0xA6, 0x16, 0x03, 0x00, 0x33, 0x25, 0x00, 0xC2, 0x88, | ||
9381 | 0x7C, 0x95, 0x32, 0x83, | ||
9382 | 0x60, 0x96, 0x32, 0x83, 0x04, 0x01, 0x10, 0xCE, 0x07, 0xC8, 0x05, 0x05, | ||
9383 | 0xEB, 0x04, 0x00, 0x33, | ||
9384 | 0x00, 0x20, 0xC0, 0x20, 0x81, 0x62, 0x72, 0x83, 0x00, 0x01, 0x05, 0x05, | ||
9385 | 0xFF, 0xA2, 0x7A, 0x03, | ||
9386 | 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x2E, 0x83, 0x05, 0x05, 0x15, 0x01, | ||
9387 | 0x00, 0xA2, 0x9A, 0x03, | ||
9388 | 0xEC, 0x00, 0x6E, 0x00, 0x95, 0x01, 0x6C, 0x38, 0x00, 0x3F, 0x00, 0x00, | ||
9389 | 0x01, 0xA6, 0x96, 0x03, | ||
9390 | 0x00, 0xA6, 0x96, 0x03, 0x10, 0x84, 0x80, 0x42, 0x7E, 0x98, 0x01, 0xA6, | ||
9391 | 0xA4, 0x03, 0x00, 0xA6, | ||
9392 | 0xBC, 0x03, 0x10, 0x84, 0xA8, 0x98, 0x80, 0x42, 0x01, 0xA6, 0xA4, 0x03, | ||
9393 | 0x07, 0xA6, 0xB2, 0x03, | ||
9394 | 0xD4, 0x83, 0x7C, 0x95, 0xA8, 0x83, 0x00, 0x33, 0x2F, 0x00, 0xC2, 0x88, | ||
9395 | 0xA8, 0x98, 0x80, 0x42, | ||
9396 | 0x00, 0xA6, 0xBC, 0x03, 0x07, 0xA6, 0xCA, 0x03, 0xD4, 0x83, 0x7C, 0x95, | ||
9397 | 0xC0, 0x83, 0x00, 0x33, | ||
9398 | 0x26, 0x00, 0xC2, 0x88, 0x38, 0x2B, 0x80, 0x32, 0x80, 0x36, 0x04, 0x23, | ||
9399 | 0xA0, 0x01, 0x12, 0x23, | ||
9400 | 0xA1, 0x01, 0x10, 0x84, 0x07, 0xF0, 0x06, 0xA4, 0xF4, 0x03, 0x80, 0x6B, | ||
9401 | 0x80, 0x67, 0x05, 0x23, | ||
9402 | 0x83, 0x03, 0x80, 0x63, 0x03, 0xA6, 0x0E, 0x04, 0x07, 0xA6, 0x06, 0x04, | ||
9403 | 0x06, 0xA6, 0x0A, 0x04, | ||
9404 | 0x00, 0x33, 0x17, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0xF4, 0x83, 0x60, 0x96, | ||
9405 | 0xF4, 0x83, 0x20, 0x84, | ||
9406 | 0x07, 0xF0, 0x06, 0xA4, 0x20, 0x04, 0x80, 0x6B, 0x80, 0x67, 0x05, 0x23, | ||
9407 | 0x83, 0x03, 0x80, 0x63, | ||
9408 | 0xB6, 0x2D, 0x03, 0xA6, 0x3C, 0x04, 0x07, 0xA6, 0x34, 0x04, 0x06, 0xA6, | ||
9409 | 0x38, 0x04, 0x00, 0x33, | ||
9410 | 0x30, 0x00, 0xC2, 0x88, 0x7C, 0x95, 0x20, 0x84, 0x60, 0x96, 0x20, 0x84, | ||
9411 | 0x1D, 0x01, 0x06, 0xCC, | ||
9412 | 0x00, 0x33, 0x00, 0x84, 0xC0, 0x20, 0x00, 0x23, 0xEA, 0x00, 0x81, 0x62, | ||
9413 | 0xA2, 0x0D, 0x80, 0x63, | ||
9414 | 0x07, 0xA6, 0x5A, 0x04, 0x00, 0x33, 0x18, 0x00, 0xC2, 0x88, 0x03, 0x03, | ||
9415 | 0x80, 0x63, 0xA3, 0x01, | ||
9416 | 0x07, 0xA4, 0x64, 0x04, 0x23, 0x01, 0x00, 0xA2, 0x86, 0x04, 0x0A, 0xA0, | ||
9417 | 0x76, 0x04, 0xE0, 0x00, | ||
9418 | 0x00, 0x33, 0x1D, 0x00, 0xC2, 0x88, 0x0B, 0xA0, 0x82, 0x04, 0xE0, 0x00, | ||
9419 | 0x00, 0x33, 0x1E, 0x00, | ||
9420 | 0xC2, 0x88, 0x42, 0x23, 0xF8, 0x88, 0x00, 0x23, 0x22, 0xA3, 0xE6, 0x04, | ||
9421 | 0x08, 0x23, 0x22, 0xA3, | ||
9422 | 0xA2, 0x04, 0x28, 0x23, 0x22, 0xA3, 0xAE, 0x04, 0x02, 0x23, 0x22, 0xA3, | ||
9423 | 0xC4, 0x04, 0x42, 0x23, | ||
9424 | 0xF8, 0x88, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA0, 0xAE, 0x04, 0x45, 0x23, | ||
9425 | 0xF8, 0x88, 0x04, 0x98, | ||
9426 | 0x00, 0xA2, 0xC0, 0x04, 0xB4, 0x98, 0x00, 0x33, 0x00, 0x82, 0xC0, 0x20, | ||
9427 | 0x81, 0x62, 0xE8, 0x81, | ||
9428 | 0x47, 0x23, 0xF8, 0x88, 0x04, 0x01, 0x0B, 0xDE, 0x04, 0x98, 0xB4, 0x98, | ||
9429 | 0x00, 0x33, 0x00, 0x81, | ||
9430 | 0xC0, 0x20, 0x81, 0x62, 0x14, 0x01, 0x00, 0xA0, 0x00, 0x02, 0x43, 0x23, | ||
9431 | 0xF8, 0x88, 0x04, 0x23, | ||
9432 | 0xA0, 0x01, 0x44, 0x23, 0xA1, 0x01, 0x80, 0x73, 0x4D, 0x00, 0x03, 0xA3, | ||
9433 | 0xF4, 0x04, 0x00, 0x33, | ||
9434 | 0x27, 0x00, 0xC2, 0x88, 0x04, 0x01, 0x04, 0xDC, 0x02, 0x23, 0xA2, 0x01, | ||
9435 | 0x04, 0x23, 0xA0, 0x01, | ||
9436 | 0x04, 0x98, 0x26, 0x95, 0x4B, 0x00, 0xF6, 0x00, 0x4F, 0x04, 0x4F, 0x00, | ||
9437 | 0x00, 0xA3, 0x22, 0x05, | ||
9438 | 0x00, 0x05, 0x76, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x1C, 0x05, 0x0A, 0x85, | ||
9439 | 0x46, 0x97, 0xCD, 0x04, | ||
9440 | 0x24, 0x85, 0x48, 0x04, 0x84, 0x80, 0x02, 0x01, 0x03, 0xDA, 0x80, 0x23, | ||
9441 | 0x82, 0x01, 0x34, 0x85, | ||
9442 | 0x02, 0x23, 0xA0, 0x01, 0x4A, 0x00, 0x06, 0x61, 0x00, 0xA2, 0x40, 0x05, | ||
9443 | 0x1D, 0x01, 0x04, 0xD6, | ||
9444 | 0xFF, 0x23, 0x86, 0x41, 0x4B, 0x60, 0xCB, 0x00, 0xFF, 0x23, 0x80, 0x01, | ||
9445 | 0x49, 0x00, 0x81, 0x01, | ||
9446 | 0x04, 0x01, 0x02, 0xC8, 0x30, 0x01, 0x80, 0x01, 0xF7, 0x04, 0x03, 0x01, | ||
9447 | 0x49, 0x04, 0x80, 0x01, | ||
9448 | 0xC9, 0x00, 0x00, 0x05, 0x00, 0x01, 0xFF, 0xA0, 0x60, 0x05, 0x77, 0x04, | ||
9449 | 0x01, 0x23, 0xEA, 0x00, | ||
9450 | 0x5D, 0x00, 0xFE, 0xC7, 0x00, 0x62, 0x00, 0x23, 0xEA, 0x00, 0x00, 0x63, | ||
9451 | 0x07, 0xA4, 0xF8, 0x05, | ||
9452 | 0x03, 0x03, 0x02, 0xA0, 0x8E, 0x05, 0xF4, 0x85, 0x00, 0x33, 0x2D, 0x00, | ||
9453 | 0xC2, 0x88, 0x04, 0xA0, | ||
9454 | 0xB8, 0x05, 0x80, 0x63, 0x00, 0x23, 0xDF, 0x00, 0x4A, 0x00, 0x06, 0x61, | ||
9455 | 0x00, 0xA2, 0xA4, 0x05, | ||
9456 | 0x1D, 0x01, 0x06, 0xD6, 0x02, 0x23, 0x02, 0x41, 0x82, 0x01, 0x50, 0x00, | ||
9457 | 0x62, 0x97, 0x04, 0x85, | ||
9458 | 0x04, 0x23, 0x02, 0x41, 0x82, 0x01, 0x04, 0x85, 0x08, 0xA0, 0xBE, 0x05, | ||
9459 | 0xF4, 0x85, 0x03, 0xA0, | ||
9460 | 0xC4, 0x05, 0xF4, 0x85, 0x01, 0xA0, 0xCE, 0x05, 0x88, 0x00, 0x80, 0x63, | ||
9461 | 0xCC, 0x86, 0x07, 0xA0, | ||
9462 | 0xEE, 0x05, 0x5F, 0x00, 0x00, 0x2B, 0xDF, 0x08, 0x00, 0xA2, 0xE6, 0x05, | ||
9463 | 0x80, 0x67, 0x80, 0x63, | ||
9464 | 0x01, 0xA2, 0x7A, 0x06, 0x7C, 0x85, 0x06, 0x23, 0x68, 0x98, 0x48, 0x23, | ||
9465 | 0xF8, 0x88, 0x07, 0x23, | ||
9466 | 0x80, 0x00, 0x06, 0x87, 0x80, 0x63, 0x7C, 0x85, 0x00, 0x23, 0xDF, 0x00, | ||
9467 | 0x00, 0x63, 0x4A, 0x00, | ||
9468 | 0x06, 0x61, 0x00, 0xA2, 0x36, 0x06, 0x1D, 0x01, 0x16, 0xD4, 0xC0, 0x23, | ||
9469 | 0x07, 0x41, 0x83, 0x03, | ||
9470 | 0x80, 0x63, 0x06, 0xA6, 0x1C, 0x06, 0x00, 0x33, 0x37, 0x00, 0xC2, 0x88, | ||
9471 | 0x1D, 0x01, 0x01, 0xD6, | ||
9472 | 0x20, 0x23, 0x63, 0x60, 0x83, 0x03, 0x80, 0x63, 0x02, 0x23, 0xDF, 0x00, | ||
9473 | 0x07, 0xA6, 0x7C, 0x05, | ||
9474 | 0xEF, 0x04, 0x6F, 0x00, 0x00, 0x63, 0x4B, 0x00, 0x06, 0x41, 0xCB, 0x00, | ||
9475 | 0x52, 0x00, 0x06, 0x61, | ||
9476 | 0x00, 0xA2, 0x4E, 0x06, 0x1D, 0x01, 0x03, 0xCA, 0xC0, 0x23, 0x07, 0x41, | ||
9477 | 0x00, 0x63, 0x1D, 0x01, | ||
9478 | 0x04, 0xCC, 0x00, 0x33, 0x00, 0x83, 0xC0, 0x20, 0x81, 0x62, 0x80, 0x23, | ||
9479 | 0x07, 0x41, 0x00, 0x63, | ||
9480 | 0x80, 0x67, 0x08, 0x23, 0x83, 0x03, 0x80, 0x63, 0x00, 0x63, 0x01, 0x23, | ||
9481 | 0xDF, 0x00, 0x06, 0xA6, | ||
9482 | 0x84, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x80, 0x67, 0x80, 0x63, 0x00, 0x33, | ||
9483 | 0x00, 0x40, 0xC0, 0x20, | ||
9484 | 0x81, 0x62, 0x00, 0x63, 0x00, 0x00, 0xFE, 0x95, 0x83, 0x03, 0x80, 0x63, | ||
9485 | 0x06, 0xA6, 0x94, 0x06, | ||
9486 | 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x00, 0x01, 0xA0, 0x14, 0x07, 0x00, 0x2B, | ||
9487 | 0x40, 0x0E, 0x80, 0x63, | ||
9488 | 0x01, 0x00, 0x06, 0xA6, 0xAA, 0x06, 0x07, 0xA6, 0x7C, 0x05, 0x40, 0x0E, | ||
9489 | 0x80, 0x63, 0x00, 0x43, | ||
9490 | 0x00, 0xA0, 0xA2, 0x06, 0x06, 0xA6, 0xBC, 0x06, 0x07, 0xA6, 0x7C, 0x05, | ||
9491 | 0x80, 0x67, 0x40, 0x0E, | ||
9492 | 0x80, 0x63, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x23, 0xDF, 0x00, 0x00, 0x63, | ||
9493 | 0x07, 0xA6, 0xD6, 0x06, | ||
9494 | 0x00, 0x33, 0x2A, 0x00, 0xC2, 0x88, 0x03, 0x03, 0x80, 0x63, 0x89, 0x00, | ||
9495 | 0x0A, 0x2B, 0x07, 0xA6, | ||
9496 | 0xE8, 0x06, 0x00, 0x33, 0x29, 0x00, 0xC2, 0x88, 0x00, 0x43, 0x00, 0xA2, | ||
9497 | 0xF4, 0x06, 0xC0, 0x0E, | ||
9498 | 0x80, 0x63, 0xDE, 0x86, 0xC0, 0x0E, 0x00, 0x33, 0x00, 0x80, 0xC0, 0x20, | ||
9499 | 0x81, 0x62, 0x04, 0x01, | ||
9500 | 0x02, 0xDA, 0x80, 0x63, 0x7C, 0x85, 0x80, 0x7B, 0x80, 0x63, 0x06, 0xA6, | ||
9501 | 0x8C, 0x06, 0x00, 0x33, | ||
9502 | 0x2C, 0x00, 0xC2, 0x88, 0x0C, 0xA2, 0x2E, 0x07, 0xFE, 0x95, 0x83, 0x03, | ||
9503 | 0x80, 0x63, 0x06, 0xA6, | ||
9504 | 0x2C, 0x07, 0x07, 0xA6, 0x7C, 0x05, 0x00, 0x33, 0x3D, 0x00, 0xC2, 0x88, | ||
9505 | 0x00, 0x00, 0x80, 0x67, | ||
9506 | 0x83, 0x03, 0x80, 0x63, 0x0C, 0xA0, 0x44, 0x07, 0x07, 0xA6, 0x7C, 0x05, | ||
9507 | 0xBF, 0x23, 0x04, 0x61, | ||
9508 | 0x84, 0x01, 0xE6, 0x84, 0x00, 0x63, 0xF0, 0x04, 0x01, 0x01, 0xF1, 0x00, | ||
9509 | 0x00, 0x01, 0xF2, 0x00, | ||
9510 | 0x01, 0x05, 0x80, 0x01, 0x72, 0x04, 0x71, 0x00, 0x81, 0x01, 0x70, 0x04, | ||
9511 | 0x80, 0x05, 0x81, 0x05, | ||
9512 | 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x01, 0x01, 0xF1, 0x00, | ||
9513 | 0x70, 0x00, 0x81, 0x01, | ||
9514 | 0x70, 0x04, 0x71, 0x00, 0x81, 0x01, 0x72, 0x00, 0x80, 0x01, 0x71, 0x04, | ||
9515 | 0x70, 0x00, 0x80, 0x01, | ||
9516 | 0x70, 0x04, 0x00, 0x63, 0xF0, 0x04, 0xF2, 0x00, 0x72, 0x04, 0x00, 0x01, | ||
9517 | 0xF1, 0x00, 0x70, 0x00, | ||
9518 | 0x80, 0x01, 0x70, 0x04, 0x71, 0x00, 0x80, 0x01, 0x72, 0x00, 0x81, 0x01, | ||
9519 | 0x71, 0x04, 0x70, 0x00, | ||
9520 | 0x81, 0x01, 0x70, 0x04, 0x00, 0x63, 0x00, 0x23, 0xB3, 0x01, 0x83, 0x05, | ||
9521 | 0xA3, 0x01, 0xA2, 0x01, | ||
9522 | 0xA1, 0x01, 0x01, 0x23, 0xA0, 0x01, 0x00, 0x01, 0xC8, 0x00, 0x03, 0xA1, | ||
9523 | 0xC4, 0x07, 0x00, 0x33, | ||
9524 | 0x07, 0x00, 0xC2, 0x88, 0x80, 0x05, 0x81, 0x05, 0x04, 0x01, 0x11, 0xC8, | ||
9525 | 0x48, 0x00, 0xB0, 0x01, | ||
9526 | 0xB1, 0x01, 0x08, 0x23, 0xB2, 0x01, 0x05, 0x01, 0x48, 0x04, 0x00, 0x43, | ||
9527 | 0x00, 0xA2, 0xE4, 0x07, | ||
9528 | 0x00, 0x05, 0xDA, 0x87, 0x00, 0x01, 0xC8, 0x00, 0xFF, 0x23, 0x80, 0x01, | ||
9529 | 0x05, 0x05, 0x00, 0x63, | ||
9530 | 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, 0x00, 0x02, 0x80, 0x43, | ||
9531 | 0x76, 0x08, 0x80, 0x02, | ||
9532 | 0x77, 0x04, 0x00, 0x63, 0xF7, 0x04, 0x1A, 0x09, 0xF6, 0x08, 0x6E, 0x04, | ||
9533 | 0x00, 0x02, 0x00, 0xA0, | ||
9534 | 0x14, 0x08, 0x16, 0x88, 0x00, 0x43, 0x76, 0x08, 0x80, 0x02, 0x77, 0x04, | ||
9535 | 0x00, 0x63, 0xF3, 0x04, | ||
9536 | 0x00, 0x23, 0xF4, 0x00, 0x74, 0x00, 0x80, 0x43, 0xF4, 0x00, 0xCF, 0x40, | ||
9537 | 0x00, 0xA2, 0x44, 0x08, | ||
9538 | 0x74, 0x04, 0x02, 0x01, 0xF7, 0xC9, 0xF6, 0xD9, 0x00, 0x01, 0x01, 0xA1, | ||
9539 | 0x24, 0x08, 0x04, 0x98, | ||
9540 | 0x26, 0x95, 0x24, 0x88, 0x73, 0x04, 0x00, 0x63, 0xF3, 0x04, 0x75, 0x04, | ||
9541 | 0x5A, 0x88, 0x02, 0x01, | ||
9542 | 0x04, 0xD8, 0x46, 0x97, 0x04, 0x98, 0x26, 0x95, 0x4A, 0x88, 0x75, 0x00, | ||
9543 | 0x00, 0xA3, 0x64, 0x08, | ||
9544 | 0x00, 0x05, 0x4E, 0x88, 0x73, 0x04, 0x00, 0x63, 0x80, 0x7B, 0x80, 0x63, | ||
9545 | 0x06, 0xA6, 0x76, 0x08, | ||
9546 | 0x00, 0x33, 0x3E, 0x00, 0xC2, 0x88, 0x80, 0x67, 0x83, 0x03, 0x80, 0x63, | ||
9547 | 0x00, 0x63, 0x38, 0x2B, | ||
9548 | 0x9C, 0x88, 0x38, 0x2B, 0x92, 0x88, 0x32, 0x09, 0x31, 0x05, 0x92, 0x98, | ||
9549 | 0x05, 0x05, 0xB2, 0x09, | ||
9550 | 0x00, 0x63, 0x00, 0x32, 0x00, 0x36, 0x00, 0x3A, 0x00, 0x3E, 0x00, 0x63, | ||
9551 | 0x80, 0x32, 0x80, 0x36, | ||
9552 | 0x80, 0x3A, 0x80, 0x3E, 0xB4, 0x3D, 0x00, 0x63, 0x38, 0x2B, 0x40, 0x32, | ||
9553 | 0x40, 0x36, 0x40, 0x3A, | ||
9554 | 0x40, 0x3E, 0x00, 0x63, 0x5A, 0x20, 0xC9, 0x40, 0x00, 0xA0, 0xB4, 0x08, | ||
9555 | 0x5D, 0x00, 0xFE, 0xC3, | ||
9556 | 0x00, 0x63, 0x80, 0x73, 0xE6, 0x20, 0x02, 0x23, 0xE8, 0x00, 0x82, 0x73, | ||
9557 | 0xFF, 0xFD, 0x80, 0x73, | ||
9558 | 0x13, 0x23, 0xF8, 0x88, 0x66, 0x20, 0xC0, 0x20, 0x04, 0x23, 0xA0, 0x01, | ||
9559 | 0xA1, 0x23, 0xA1, 0x01, | ||
9560 | 0x81, 0x62, 0xE2, 0x88, 0x80, 0x73, 0x80, 0x77, 0x68, 0x00, 0x00, 0xA2, | ||
9561 | 0x80, 0x00, 0x03, 0xC2, | ||
9562 | 0xF1, 0xC7, 0x41, 0x23, 0xF8, 0x88, 0x11, 0x23, 0xA1, 0x01, 0x04, 0x23, | ||
9563 | 0xA0, 0x01, 0xE6, 0x84, | ||
9564 | }; | ||
9565 | 9491 | ||
9566 | static ushort _asc_mcode_size = sizeof(_asc_mcode_buf); | 9492 | ASC_DBG(1, "0x%p\n", scp); |
9567 | static ADV_DCNT _asc_mcode_chksum = 0x012C453FUL; | ||
9568 | 9493 | ||
9569 | #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16 | 9494 | ASC_STATS(shost, reset); |
9570 | static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = { | ||
9571 | INQUIRY, | ||
9572 | REQUEST_SENSE, | ||
9573 | READ_CAPACITY, | ||
9574 | READ_TOC, | ||
9575 | MODE_SELECT, | ||
9576 | MODE_SENSE, | ||
9577 | MODE_SELECT_10, | ||
9578 | MODE_SENSE_10, | ||
9579 | 0xFF, | ||
9580 | 0xFF, | ||
9581 | 0xFF, | ||
9582 | 0xFF, | ||
9583 | 0xFF, | ||
9584 | 0xFF, | ||
9585 | 0xFF, | ||
9586 | 0xFF | ||
9587 | }; | ||
9588 | 9495 | ||
9589 | static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq) | 9496 | scmd_printk(KERN_INFO, scp, "SCSI bus reset started...\n"); |
9590 | { | ||
9591 | PortAddr iop_base; | ||
9592 | ulong last_int_level; | ||
9593 | int sta; | ||
9594 | int n_q_required; | ||
9595 | int disable_syn_offset_one_fix; | ||
9596 | int i; | ||
9597 | ASC_PADDR addr; | ||
9598 | ASC_EXE_CALLBACK asc_exe_callback; | ||
9599 | ushort sg_entry_cnt = 0; | ||
9600 | ushort sg_entry_cnt_minus_one = 0; | ||
9601 | uchar target_ix; | ||
9602 | uchar tid_no; | ||
9603 | uchar sdtr_data; | ||
9604 | uchar extra_bytes; | ||
9605 | uchar scsi_cmd; | ||
9606 | uchar disable_cmd; | ||
9607 | ASC_SG_HEAD *sg_head; | ||
9608 | ASC_DCNT data_cnt; | ||
9609 | 9497 | ||
9610 | iop_base = asc_dvc->iop_base; | 9498 | if (ASC_NARROW_BOARD(boardp)) { |
9611 | sg_head = scsiq->sg_head; | 9499 | ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; |
9612 | asc_exe_callback = asc_dvc->exe_callback; | 9500 | |
9613 | if (asc_dvc->err_code != 0) | 9501 | /* Reset the chip and SCSI bus. */ |
9614 | return (ERR); | 9502 | ASC_DBG(1, "before AscInitAsc1000Driver()\n"); |
9615 | if (scsiq == (ASC_SCSI_Q *)0L) { | 9503 | status = AscInitAsc1000Driver(asc_dvc); |
9616 | AscSetLibErrorCode(asc_dvc, ASCQ_ERR_SCSIQ_NULL_PTR); | 9504 | |
9617 | return (ERR); | 9505 | /* Refer to ASC_IERR_* defintions for meaning of 'err_code'. */ |
9618 | } | 9506 | if (asc_dvc->err_code) { |
9619 | scsiq->q1.q_no = 0; | 9507 | scmd_printk(KERN_INFO, scp, "SCSI bus reset error: " |
9620 | if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) { | 9508 | "0x%x\n", asc_dvc->err_code); |
9621 | scsiq->q1.extra_bytes = 0; | 9509 | ret = FAILED; |
9622 | } | 9510 | } else if (status) { |
9623 | sta = 0; | 9511 | scmd_printk(KERN_INFO, scp, "SCSI bus reset warning: " |
9624 | target_ix = scsiq->q2.target_ix; | 9512 | "0x%x\n", status); |
9625 | tid_no = ASC_TIX_TO_TID(target_ix); | 9513 | } else { |
9626 | n_q_required = 1; | 9514 | scmd_printk(KERN_INFO, scp, "SCSI bus reset " |
9627 | if (scsiq->cdbptr[0] == REQUEST_SENSE) { | 9515 | "successful\n"); |
9628 | if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) { | 9516 | } |
9629 | asc_dvc->sdtr_done &= ~scsiq->q1.target_id; | 9517 | |
9630 | sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no); | 9518 | ASC_DBG(1, "after AscInitAsc1000Driver()\n"); |
9631 | AscMsgOutSDTR(asc_dvc, | 9519 | spin_lock_irqsave(shost->host_lock, flags); |
9632 | asc_dvc-> | 9520 | } else { |
9633 | sdtr_period_tbl[(sdtr_data >> 4) & | 9521 | /* |
9634 | (uchar)(asc_dvc-> | 9522 | * If the suggest reset bus flags are set, then reset the bus. |
9635 | max_sdtr_index - | 9523 | * Otherwise only reset the device. |
9636 | 1)], | 9524 | */ |
9637 | (uchar)(sdtr_data & (uchar) | 9525 | ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var; |
9638 | ASC_SYN_MAX_OFFSET)); | 9526 | |
9639 | scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT); | 9527 | /* |
9528 | * Reset the target's SCSI bus. | ||
9529 | */ | ||
9530 | ASC_DBG(1, "before AdvResetChipAndSB()\n"); | ||
9531 | switch (AdvResetChipAndSB(adv_dvc)) { | ||
9532 | case ASC_TRUE: | ||
9533 | scmd_printk(KERN_INFO, scp, "SCSI bus reset " | ||
9534 | "successful\n"); | ||
9535 | break; | ||
9536 | case ASC_FALSE: | ||
9537 | default: | ||
9538 | scmd_printk(KERN_INFO, scp, "SCSI bus reset error\n"); | ||
9539 | ret = FAILED; | ||
9540 | break; | ||
9640 | } | 9541 | } |
9542 | spin_lock_irqsave(shost->host_lock, flags); | ||
9543 | AdvISR(adv_dvc); | ||
9641 | } | 9544 | } |
9642 | last_int_level = DvcEnterCritical(); | 9545 | |
9643 | if (asc_dvc->in_critical_cnt != 0) { | 9546 | /* Save the time of the most recently completed reset. */ |
9644 | DvcLeaveCritical(last_int_level); | 9547 | boardp->last_reset = jiffies; |
9645 | AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY); | 9548 | spin_unlock_irqrestore(shost->host_lock, flags); |
9646 | return (ERR); | 9549 | |
9550 | ASC_DBG(1, "ret %d\n", ret); | ||
9551 | |||
9552 | return ret; | ||
9553 | } | ||
9554 | |||
9555 | /* | ||
9556 | * advansys_biosparam() | ||
9557 | * | ||
9558 | * Translate disk drive geometry if the "BIOS greater than 1 GB" | ||
9559 | * support is enabled for a drive. | ||
9560 | * | ||
9561 | * ip (information pointer) is an int array with the following definition: | ||
9562 | * ip[0]: heads | ||
9563 | * ip[1]: sectors | ||
9564 | * ip[2]: cylinders | ||
9565 | */ | ||
9566 | static int | ||
9567 | advansys_biosparam(struct scsi_device *sdev, struct block_device *bdev, | ||
9568 | sector_t capacity, int ip[]) | ||
9569 | { | ||
9570 | struct asc_board *boardp = shost_priv(sdev->host); | ||
9571 | |||
9572 | ASC_DBG(1, "begin\n"); | ||
9573 | ASC_STATS(sdev->host, biosparam); | ||
9574 | if (ASC_NARROW_BOARD(boardp)) { | ||
9575 | if ((boardp->dvc_var.asc_dvc_var.dvc_cntl & | ||
9576 | ASC_CNTL_BIOS_GT_1GB) && capacity > 0x200000) { | ||
9577 | ip[0] = 255; | ||
9578 | ip[1] = 63; | ||
9579 | } else { | ||
9580 | ip[0] = 64; | ||
9581 | ip[1] = 32; | ||
9582 | } | ||
9583 | } else { | ||
9584 | if ((boardp->dvc_var.adv_dvc_var.bios_ctrl & | ||
9585 | BIOS_CTRL_EXTENDED_XLAT) && capacity > 0x200000) { | ||
9586 | ip[0] = 255; | ||
9587 | ip[1] = 63; | ||
9588 | } else { | ||
9589 | ip[0] = 64; | ||
9590 | ip[1] = 32; | ||
9591 | } | ||
9647 | } | 9592 | } |
9648 | asc_dvc->in_critical_cnt++; | 9593 | ip[2] = (unsigned long)capacity / (ip[0] * ip[1]); |
9649 | if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) { | 9594 | ASC_DBG(1, "end\n"); |
9650 | if ((sg_entry_cnt = sg_head->entry_cnt) == 0) { | 9595 | return 0; |
9651 | asc_dvc->in_critical_cnt--; | 9596 | } |
9652 | DvcLeaveCritical(last_int_level); | 9597 | |
9653 | return (ERR); | 9598 | /* |
9599 | * First-level interrupt handler. | ||
9600 | * | ||
9601 | * 'dev_id' is a pointer to the interrupting adapter's Scsi_Host. | ||
9602 | */ | ||
9603 | static irqreturn_t advansys_interrupt(int irq, void *dev_id) | ||
9604 | { | ||
9605 | struct Scsi_Host *shost = dev_id; | ||
9606 | struct asc_board *boardp = shost_priv(shost); | ||
9607 | irqreturn_t result = IRQ_NONE; | ||
9608 | |||
9609 | ASC_DBG(2, "boardp 0x%p\n", boardp); | ||
9610 | spin_lock(shost->host_lock); | ||
9611 | if (ASC_NARROW_BOARD(boardp)) { | ||
9612 | if (AscIsIntPending(shost->io_port)) { | ||
9613 | result = IRQ_HANDLED; | ||
9614 | ASC_STATS(shost, interrupt); | ||
9615 | ASC_DBG(1, "before AscISR()\n"); | ||
9616 | AscISR(&boardp->dvc_var.asc_dvc_var); | ||
9654 | } | 9617 | } |
9655 | #if !CC_VERY_LONG_SG_LIST | 9618 | } else { |
9656 | if (sg_entry_cnt > ASC_MAX_SG_LIST) { | 9619 | ASC_DBG(1, "before AdvISR()\n"); |
9657 | asc_dvc->in_critical_cnt--; | 9620 | if (AdvISR(&boardp->dvc_var.adv_dvc_var)) { |
9658 | DvcLeaveCritical(last_int_level); | 9621 | result = IRQ_HANDLED; |
9659 | return (ERR); | 9622 | ASC_STATS(shost, interrupt); |
9660 | } | 9623 | } |
9661 | #endif /* !CC_VERY_LONG_SG_LIST */ | 9624 | } |
9662 | if (sg_entry_cnt == 1) { | 9625 | spin_unlock(shost->host_lock); |
9663 | scsiq->q1.data_addr = | 9626 | |
9664 | (ADV_PADDR)sg_head->sg_list[0].addr; | 9627 | ASC_DBG(1, "end\n"); |
9665 | scsiq->q1.data_cnt = | 9628 | return result; |
9666 | (ADV_DCNT)sg_head->sg_list[0].bytes; | 9629 | } |
9667 | scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE); | 9630 | |
9631 | static int AscHostReqRiscHalt(PortAddr iop_base) | ||
9632 | { | ||
9633 | int count = 0; | ||
9634 | int sta = 0; | ||
9635 | uchar saved_stop_code; | ||
9636 | |||
9637 | if (AscIsChipHalted(iop_base)) | ||
9638 | return (1); | ||
9639 | saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B); | ||
9640 | AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, | ||
9641 | ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP); | ||
9642 | do { | ||
9643 | if (AscIsChipHalted(iop_base)) { | ||
9644 | sta = 1; | ||
9645 | break; | ||
9668 | } | 9646 | } |
9669 | sg_entry_cnt_minus_one = sg_entry_cnt - 1; | 9647 | mdelay(100); |
9648 | } while (count++ < 20); | ||
9649 | AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code); | ||
9650 | return (sta); | ||
9651 | } | ||
9652 | |||
9653 | static int | ||
9654 | AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data) | ||
9655 | { | ||
9656 | int sta = FALSE; | ||
9657 | |||
9658 | if (AscHostReqRiscHalt(iop_base)) { | ||
9659 | sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data); | ||
9660 | AscStartChip(iop_base); | ||
9670 | } | 9661 | } |
9671 | scsi_cmd = scsiq->cdbptr[0]; | 9662 | return sta; |
9672 | disable_syn_offset_one_fix = FALSE; | 9663 | } |
9673 | if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) && | 9664 | |
9674 | !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) { | 9665 | static void AscAsyncFix(ASC_DVC_VAR *asc_dvc, struct scsi_device *sdev) |
9675 | if (scsiq->q1.cntl & QC_SG_HEAD) { | 9666 | { |
9676 | data_cnt = 0; | 9667 | char type = sdev->type; |
9677 | for (i = 0; i < sg_entry_cnt; i++) { | 9668 | ASC_SCSI_BIT_ID_TYPE tid_bits = 1 << sdev->id; |
9678 | data_cnt += | 9669 | |
9679 | (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i]. | 9670 | if (!(asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN)) |
9680 | bytes); | 9671 | return; |
9681 | } | 9672 | if (asc_dvc->init_sdtr & tid_bits) |
9673 | return; | ||
9674 | |||
9675 | if ((type == TYPE_ROM) && (strncmp(sdev->vendor, "HP ", 3) == 0)) | ||
9676 | asc_dvc->pci_fix_asyn_xfer_always |= tid_bits; | ||
9677 | |||
9678 | asc_dvc->pci_fix_asyn_xfer |= tid_bits; | ||
9679 | if ((type == TYPE_PROCESSOR) || (type == TYPE_SCANNER) || | ||
9680 | (type == TYPE_ROM) || (type == TYPE_TAPE)) | ||
9681 | asc_dvc->pci_fix_asyn_xfer &= ~tid_bits; | ||
9682 | |||
9683 | if (asc_dvc->pci_fix_asyn_xfer & tid_bits) | ||
9684 | AscSetRunChipSynRegAtID(asc_dvc->iop_base, sdev->id, | ||
9685 | ASYN_SDTR_DATA_FIX_PCI_REV_AB); | ||
9686 | } | ||
9687 | |||
9688 | static void | ||
9689 | advansys_narrow_slave_configure(struct scsi_device *sdev, ASC_DVC_VAR *asc_dvc) | ||
9690 | { | ||
9691 | ASC_SCSI_BIT_ID_TYPE tid_bit = 1 << sdev->id; | ||
9692 | ASC_SCSI_BIT_ID_TYPE orig_use_tagged_qng = asc_dvc->use_tagged_qng; | ||
9693 | |||
9694 | if (sdev->lun == 0) { | ||
9695 | ASC_SCSI_BIT_ID_TYPE orig_init_sdtr = asc_dvc->init_sdtr; | ||
9696 | if ((asc_dvc->cfg->sdtr_enable & tid_bit) && sdev->sdtr) { | ||
9697 | asc_dvc->init_sdtr |= tid_bit; | ||
9682 | } else { | 9698 | } else { |
9683 | data_cnt = le32_to_cpu(scsiq->q1.data_cnt); | 9699 | asc_dvc->init_sdtr &= ~tid_bit; |
9684 | } | 9700 | } |
9685 | if (data_cnt != 0UL) { | 9701 | |
9686 | if (data_cnt < 512UL) { | 9702 | if (orig_init_sdtr != asc_dvc->init_sdtr) |
9687 | disable_syn_offset_one_fix = TRUE; | 9703 | AscAsyncFix(asc_dvc, sdev); |
9688 | } else { | 9704 | } |
9689 | for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; | 9705 | |
9690 | i++) { | 9706 | if (sdev->tagged_supported) { |
9691 | disable_cmd = | 9707 | if (asc_dvc->cfg->cmd_qng_enabled & tid_bit) { |
9692 | _syn_offset_one_disable_cmd[i]; | 9708 | if (sdev->lun == 0) { |
9693 | if (disable_cmd == 0xFF) { | 9709 | asc_dvc->cfg->can_tagged_qng |= tid_bit; |
9694 | break; | 9710 | asc_dvc->use_tagged_qng |= tid_bit; |
9695 | } | ||
9696 | if (scsi_cmd == disable_cmd) { | ||
9697 | disable_syn_offset_one_fix = | ||
9698 | TRUE; | ||
9699 | break; | ||
9700 | } | ||
9701 | } | ||
9702 | } | 9711 | } |
9712 | scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, | ||
9713 | asc_dvc->max_dvc_qng[sdev->id]); | ||
9714 | } | ||
9715 | } else { | ||
9716 | if (sdev->lun == 0) { | ||
9717 | asc_dvc->cfg->can_tagged_qng &= ~tid_bit; | ||
9718 | asc_dvc->use_tagged_qng &= ~tid_bit; | ||
9703 | } | 9719 | } |
9720 | scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); | ||
9704 | } | 9721 | } |
9705 | if (disable_syn_offset_one_fix) { | 9722 | |
9706 | scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG; | 9723 | if ((sdev->lun == 0) && |
9707 | scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX | | 9724 | (orig_use_tagged_qng != asc_dvc->use_tagged_qng)) { |
9708 | ASC_TAG_FLAG_DISABLE_DISCONNECT); | 9725 | AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B, |
9726 | asc_dvc->cfg->disc_enable); | ||
9727 | AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B, | ||
9728 | asc_dvc->use_tagged_qng); | ||
9729 | AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B, | ||
9730 | asc_dvc->cfg->can_tagged_qng); | ||
9731 | |||
9732 | asc_dvc->max_dvc_qng[sdev->id] = | ||
9733 | asc_dvc->cfg->max_tag_qng[sdev->id]; | ||
9734 | AscWriteLramByte(asc_dvc->iop_base, | ||
9735 | (ushort)(ASCV_MAX_DVC_QNG_BEG + sdev->id), | ||
9736 | asc_dvc->max_dvc_qng[sdev->id]); | ||
9737 | } | ||
9738 | } | ||
9739 | |||
9740 | /* | ||
9741 | * Wide Transfers | ||
9742 | * | ||
9743 | * If the EEPROM enabled WDTR for the device and the device supports wide | ||
9744 | * bus (16 bit) transfers, then turn on the device's 'wdtr_able' bit and | ||
9745 | * write the new value to the microcode. | ||
9746 | */ | ||
9747 | static void | ||
9748 | advansys_wide_enable_wdtr(AdvPortAddr iop_base, unsigned short tidmask) | ||
9749 | { | ||
9750 | unsigned short cfg_word; | ||
9751 | AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word); | ||
9752 | if ((cfg_word & tidmask) != 0) | ||
9753 | return; | ||
9754 | |||
9755 | cfg_word |= tidmask; | ||
9756 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word); | ||
9757 | |||
9758 | /* | ||
9759 | * Clear the microcode SDTR and WDTR negotiation done indicators for | ||
9760 | * the target to cause it to negotiate with the new setting set above. | ||
9761 | * WDTR when accepted causes the target to enter asynchronous mode, so | ||
9762 | * SDTR must be negotiated. | ||
9763 | */ | ||
9764 | AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); | ||
9765 | cfg_word &= ~tidmask; | ||
9766 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); | ||
9767 | AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word); | ||
9768 | cfg_word &= ~tidmask; | ||
9769 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, cfg_word); | ||
9770 | } | ||
9771 | |||
9772 | /* | ||
9773 | * Synchronous Transfers | ||
9774 | * | ||
9775 | * If the EEPROM enabled SDTR for the device and the device | ||
9776 | * supports synchronous transfers, then turn on the device's | ||
9777 | * 'sdtr_able' bit. Write the new value to the microcode. | ||
9778 | */ | ||
9779 | static void | ||
9780 | advansys_wide_enable_sdtr(AdvPortAddr iop_base, unsigned short tidmask) | ||
9781 | { | ||
9782 | unsigned short cfg_word; | ||
9783 | AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word); | ||
9784 | if ((cfg_word & tidmask) != 0) | ||
9785 | return; | ||
9786 | |||
9787 | cfg_word |= tidmask; | ||
9788 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word); | ||
9789 | |||
9790 | /* | ||
9791 | * Clear the microcode "SDTR negotiation" done indicator for the | ||
9792 | * target to cause it to negotiate with the new setting set above. | ||
9793 | */ | ||
9794 | AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); | ||
9795 | cfg_word &= ~tidmask; | ||
9796 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, cfg_word); | ||
9797 | } | ||
9798 | |||
9799 | /* | ||
9800 | * PPR (Parallel Protocol Request) Capable | ||
9801 | * | ||
9802 | * If the device supports DT mode, then it must be PPR capable. | ||
9803 | * The PPR message will be used in place of the SDTR and WDTR | ||
9804 | * messages to negotiate synchronous speed and offset, transfer | ||
9805 | * width, and protocol options. | ||
9806 | */ | ||
9807 | static void advansys_wide_enable_ppr(ADV_DVC_VAR *adv_dvc, | ||
9808 | AdvPortAddr iop_base, unsigned short tidmask) | ||
9809 | { | ||
9810 | AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able); | ||
9811 | adv_dvc->ppr_able |= tidmask; | ||
9812 | AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, adv_dvc->ppr_able); | ||
9813 | } | ||
9814 | |||
9815 | static void | ||
9816 | advansys_wide_slave_configure(struct scsi_device *sdev, ADV_DVC_VAR *adv_dvc) | ||
9817 | { | ||
9818 | AdvPortAddr iop_base = adv_dvc->iop_base; | ||
9819 | unsigned short tidmask = 1 << sdev->id; | ||
9820 | |||
9821 | if (sdev->lun == 0) { | ||
9822 | /* | ||
9823 | * Handle WDTR, SDTR, and Tag Queuing. If the feature | ||
9824 | * is enabled in the EEPROM and the device supports the | ||
9825 | * feature, then enable it in the microcode. | ||
9826 | */ | ||
9827 | |||
9828 | if ((adv_dvc->wdtr_able & tidmask) && sdev->wdtr) | ||
9829 | advansys_wide_enable_wdtr(iop_base, tidmask); | ||
9830 | if ((adv_dvc->sdtr_able & tidmask) && sdev->sdtr) | ||
9831 | advansys_wide_enable_sdtr(iop_base, tidmask); | ||
9832 | if (adv_dvc->chip_type == ADV_CHIP_ASC38C1600 && sdev->ppr) | ||
9833 | advansys_wide_enable_ppr(adv_dvc, iop_base, tidmask); | ||
9834 | |||
9835 | /* | ||
9836 | * Tag Queuing is disabled for the BIOS which runs in polled | ||
9837 | * mode and would see no benefit from Tag Queuing. Also by | ||
9838 | * disabling Tag Queuing in the BIOS devices with Tag Queuing | ||
9839 | * bugs will at least work with the BIOS. | ||
9840 | */ | ||
9841 | if ((adv_dvc->tagqng_able & tidmask) && | ||
9842 | sdev->tagged_supported) { | ||
9843 | unsigned short cfg_word; | ||
9844 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word); | ||
9845 | cfg_word |= tidmask; | ||
9846 | AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, | ||
9847 | cfg_word); | ||
9848 | AdvWriteByteLram(iop_base, | ||
9849 | ASC_MC_NUMBER_OF_MAX_CMD + sdev->id, | ||
9850 | adv_dvc->max_dvc_qng); | ||
9851 | } | ||
9852 | } | ||
9853 | |||
9854 | if ((adv_dvc->tagqng_able & tidmask) && sdev->tagged_supported) { | ||
9855 | scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, | ||
9856 | adv_dvc->max_dvc_qng); | ||
9709 | } else { | 9857 | } else { |
9710 | scsiq->q2.tag_code &= 0x27; | 9858 | scsi_adjust_queue_depth(sdev, 0, sdev->host->cmd_per_lun); |
9711 | } | 9859 | } |
9712 | if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) { | 9860 | } |
9713 | if (asc_dvc->bug_fix_cntl) { | 9861 | |
9714 | if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) { | 9862 | /* |
9715 | if ((scsi_cmd == READ_6) || | 9863 | * Set the number of commands to queue per device for the |
9716 | (scsi_cmd == READ_10)) { | 9864 | * specified host adapter. |
9717 | addr = | 9865 | */ |
9718 | (ADV_PADDR)le32_to_cpu(sg_head-> | 9866 | static int advansys_slave_configure(struct scsi_device *sdev) |
9719 | sg_list | 9867 | { |
9720 | [sg_entry_cnt_minus_one]. | 9868 | struct asc_board *boardp = shost_priv(sdev->host); |
9721 | addr) + | 9869 | |
9722 | (ADV_DCNT)le32_to_cpu(sg_head-> | 9870 | if (ASC_NARROW_BOARD(boardp)) |
9723 | sg_list | 9871 | advansys_narrow_slave_configure(sdev, |
9724 | [sg_entry_cnt_minus_one]. | 9872 | &boardp->dvc_var.asc_dvc_var); |
9725 | bytes); | 9873 | else |
9726 | extra_bytes = | 9874 | advansys_wide_slave_configure(sdev, |
9727 | (uchar)((ushort)addr & 0x0003); | 9875 | &boardp->dvc_var.adv_dvc_var); |
9728 | if ((extra_bytes != 0) | 9876 | |
9729 | && | 9877 | return 0; |
9730 | ((scsiq->q2. | 9878 | } |
9731 | tag_code & | 9879 | |
9732 | ASC_TAG_FLAG_EXTRA_BYTES) | 9880 | static __le32 advansys_get_sense_buffer_dma(struct scsi_cmnd *scp) |
9733 | == 0)) { | 9881 | { |
9734 | scsiq->q2.tag_code |= | 9882 | struct asc_board *board = shost_priv(scp->device->host); |
9735 | ASC_TAG_FLAG_EXTRA_BYTES; | 9883 | scp->SCp.dma_handle = dma_map_single(board->dev, scp->sense_buffer, |
9736 | scsiq->q1.extra_bytes = | 9884 | sizeof(scp->sense_buffer), DMA_FROM_DEVICE); |
9737 | extra_bytes; | 9885 | dma_cache_sync(board->dev, scp->sense_buffer, |
9738 | data_cnt = | 9886 | sizeof(scp->sense_buffer), DMA_FROM_DEVICE); |
9739 | le32_to_cpu(sg_head-> | 9887 | return cpu_to_le32(scp->SCp.dma_handle); |
9740 | sg_list | 9888 | } |
9741 | [sg_entry_cnt_minus_one]. | 9889 | |
9742 | bytes); | 9890 | static int asc_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, |
9743 | data_cnt -= | 9891 | struct asc_scsi_q *asc_scsi_q) |
9744 | (ASC_DCNT) extra_bytes; | 9892 | { |
9745 | sg_head-> | 9893 | struct asc_dvc_var *asc_dvc = &boardp->dvc_var.asc_dvc_var; |
9746 | sg_list | 9894 | int use_sg; |
9747 | [sg_entry_cnt_minus_one]. | 9895 | |
9748 | bytes = | 9896 | memset(asc_scsi_q, 0, sizeof(*asc_scsi_q)); |
9749 | cpu_to_le32(data_cnt); | 9897 | |
9750 | } | 9898 | /* |
9751 | } | 9899 | * Point the ASC_SCSI_Q to the 'struct scsi_cmnd'. |
9752 | } | 9900 | */ |
9901 | asc_scsi_q->q2.srb_ptr = advansys_ptr_to_srb(asc_dvc, scp); | ||
9902 | if (asc_scsi_q->q2.srb_ptr == BAD_SRB) { | ||
9903 | scp->result = HOST_BYTE(DID_SOFT_ERROR); | ||
9904 | return ASC_ERROR; | ||
9905 | } | ||
9906 | |||
9907 | /* | ||
9908 | * Build the ASC_SCSI_Q request. | ||
9909 | */ | ||
9910 | asc_scsi_q->cdbptr = &scp->cmnd[0]; | ||
9911 | asc_scsi_q->q2.cdb_len = scp->cmd_len; | ||
9912 | asc_scsi_q->q1.target_id = ASC_TID_TO_TARGET_ID(scp->device->id); | ||
9913 | asc_scsi_q->q1.target_lun = scp->device->lun; | ||
9914 | asc_scsi_q->q2.target_ix = | ||
9915 | ASC_TIDLUN_TO_IX(scp->device->id, scp->device->lun); | ||
9916 | asc_scsi_q->q1.sense_addr = advansys_get_sense_buffer_dma(scp); | ||
9917 | asc_scsi_q->q1.sense_len = sizeof(scp->sense_buffer); | ||
9918 | |||
9919 | /* | ||
9920 | * If there are any outstanding requests for the current target, | ||
9921 | * then every 255th request send an ORDERED request. This heuristic | ||
9922 | * tries to retain the benefit of request sorting while preventing | ||
9923 | * request starvation. 255 is the max number of tags or pending commands | ||
9924 | * a device may have outstanding. | ||
9925 | * | ||
9926 | * The request count is incremented below for every successfully | ||
9927 | * started request. | ||
9928 | * | ||
9929 | */ | ||
9930 | if ((asc_dvc->cur_dvc_qng[scp->device->id] > 0) && | ||
9931 | (boardp->reqcnt[scp->device->id] % 255) == 0) { | ||
9932 | asc_scsi_q->q2.tag_code = MSG_ORDERED_TAG; | ||
9933 | } else { | ||
9934 | asc_scsi_q->q2.tag_code = MSG_SIMPLE_TAG; | ||
9935 | } | ||
9936 | |||
9937 | /* Build ASC_SCSI_Q */ | ||
9938 | use_sg = scsi_dma_map(scp); | ||
9939 | if (use_sg != 0) { | ||
9940 | int sgcnt; | ||
9941 | struct scatterlist *slp; | ||
9942 | struct asc_sg_head *asc_sg_head; | ||
9943 | |||
9944 | if (use_sg > scp->device->host->sg_tablesize) { | ||
9945 | scmd_printk(KERN_ERR, scp, "use_sg %d > " | ||
9946 | "sg_tablesize %d\n", use_sg, | ||
9947 | scp->device->host->sg_tablesize); | ||
9948 | scsi_dma_unmap(scp); | ||
9949 | scp->result = HOST_BYTE(DID_ERROR); | ||
9950 | return ASC_ERROR; | ||
9753 | } | 9951 | } |
9754 | sg_head->entry_to_copy = sg_head->entry_cnt; | 9952 | |
9755 | #if CC_VERY_LONG_SG_LIST | 9953 | asc_sg_head = kzalloc(sizeof(asc_scsi_q->sg_head) + |
9954 | use_sg * sizeof(struct asc_sg_list), GFP_ATOMIC); | ||
9955 | if (!asc_sg_head) { | ||
9956 | scsi_dma_unmap(scp); | ||
9957 | scp->result = HOST_BYTE(DID_SOFT_ERROR); | ||
9958 | return ASC_ERROR; | ||
9959 | } | ||
9960 | |||
9961 | asc_scsi_q->q1.cntl |= QC_SG_HEAD; | ||
9962 | asc_scsi_q->sg_head = asc_sg_head; | ||
9963 | asc_scsi_q->q1.data_cnt = 0; | ||
9964 | asc_scsi_q->q1.data_addr = 0; | ||
9965 | /* This is a byte value, otherwise it would need to be swapped. */ | ||
9966 | asc_sg_head->entry_cnt = asc_scsi_q->q1.sg_queue_cnt = use_sg; | ||
9967 | ASC_STATS_ADD(scp->device->host, xfer_elem, | ||
9968 | asc_sg_head->entry_cnt); | ||
9969 | |||
9756 | /* | 9970 | /* |
9757 | * Set the sg_entry_cnt to the maximum possible. The rest of | 9971 | * Convert scatter-gather list into ASC_SG_HEAD list. |
9758 | * the SG elements will be copied when the RISC completes the | ||
9759 | * SG elements that fit and halts. | ||
9760 | */ | 9972 | */ |
9761 | if (sg_entry_cnt > ASC_MAX_SG_LIST) { | 9973 | scsi_for_each_sg(scp, slp, use_sg, sgcnt) { |
9762 | sg_entry_cnt = ASC_MAX_SG_LIST; | 9974 | asc_sg_head->sg_list[sgcnt].addr = |
9975 | cpu_to_le32(sg_dma_address(slp)); | ||
9976 | asc_sg_head->sg_list[sgcnt].bytes = | ||
9977 | cpu_to_le32(sg_dma_len(slp)); | ||
9978 | ASC_STATS_ADD(scp->device->host, xfer_sect, | ||
9979 | DIV_ROUND_UP(sg_dma_len(slp), 512)); | ||
9763 | } | 9980 | } |
9764 | #endif /* CC_VERY_LONG_SG_LIST */ | 9981 | } |
9765 | n_q_required = AscSgListToQueue(sg_entry_cnt); | 9982 | |
9766 | if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >= | 9983 | ASC_STATS(scp->device->host, xfer_cnt); |
9767 | (uint) n_q_required) | 9984 | |
9768 | || ((scsiq->q1.cntl & QC_URGENT) != 0)) { | 9985 | ASC_DBG_PRT_ASC_SCSI_Q(2, asc_scsi_q); |
9769 | if ((sta = | 9986 | ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len); |
9770 | AscSendScsiQueue(asc_dvc, scsiq, | 9987 | |
9771 | n_q_required)) == 1) { | 9988 | return ASC_NOERROR; |
9772 | asc_dvc->in_critical_cnt--; | 9989 | } |
9773 | if (asc_exe_callback != 0) { | 9990 | |
9774 | (*asc_exe_callback) (asc_dvc, scsiq); | 9991 | /* |
9775 | } | 9992 | * Build scatter-gather list for Adv Library (Wide Board). |
9776 | DvcLeaveCritical(last_int_level); | 9993 | * |
9777 | return (sta); | 9994 | * Additional ADV_SG_BLOCK structures will need to be allocated |
9995 | * if the total number of scatter-gather elements exceeds | ||
9996 | * NO_OF_SG_PER_BLOCK (15). The ADV_SG_BLOCK structures are | ||
9997 | * assumed to be physically contiguous. | ||
9998 | * | ||
9999 | * Return: | ||
10000 | * ADV_SUCCESS(1) - SG List successfully created | ||
10001 | * ADV_ERROR(-1) - SG List creation failed | ||
10002 | */ | ||
10003 | static int | ||
10004 | adv_get_sglist(struct asc_board *boardp, adv_req_t *reqp, struct scsi_cmnd *scp, | ||
10005 | int use_sg) | ||
10006 | { | ||
10007 | adv_sgblk_t *sgblkp; | ||
10008 | ADV_SCSI_REQ_Q *scsiqp; | ||
10009 | struct scatterlist *slp; | ||
10010 | int sg_elem_cnt; | ||
10011 | ADV_SG_BLOCK *sg_block, *prev_sg_block; | ||
10012 | ADV_PADDR sg_block_paddr; | ||
10013 | int i; | ||
10014 | |||
10015 | scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q); | ||
10016 | slp = scsi_sglist(scp); | ||
10017 | sg_elem_cnt = use_sg; | ||
10018 | prev_sg_block = NULL; | ||
10019 | reqp->sgblkp = NULL; | ||
10020 | |||
10021 | for (;;) { | ||
10022 | /* | ||
10023 | * Allocate a 'adv_sgblk_t' structure from the board free | ||
10024 | * list. One 'adv_sgblk_t' structure holds NO_OF_SG_PER_BLOCK | ||
10025 | * (15) scatter-gather elements. | ||
10026 | */ | ||
10027 | if ((sgblkp = boardp->adv_sgblkp) == NULL) { | ||
10028 | ASC_DBG(1, "no free adv_sgblk_t\n"); | ||
10029 | ASC_STATS(scp->device->host, adv_build_nosg); | ||
10030 | |||
10031 | /* | ||
10032 | * Allocation failed. Free 'adv_sgblk_t' structures | ||
10033 | * already allocated for the request. | ||
10034 | */ | ||
10035 | while ((sgblkp = reqp->sgblkp) != NULL) { | ||
10036 | /* Remove 'sgblkp' from the request list. */ | ||
10037 | reqp->sgblkp = sgblkp->next_sgblkp; | ||
10038 | |||
10039 | /* Add 'sgblkp' to the board free list. */ | ||
10040 | sgblkp->next_sgblkp = boardp->adv_sgblkp; | ||
10041 | boardp->adv_sgblkp = sgblkp; | ||
9778 | } | 10042 | } |
10043 | return ASC_BUSY; | ||
9779 | } | 10044 | } |
9780 | } else { | 10045 | |
9781 | if (asc_dvc->bug_fix_cntl) { | 10046 | /* Complete 'adv_sgblk_t' board allocation. */ |
9782 | if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) { | 10047 | boardp->adv_sgblkp = sgblkp->next_sgblkp; |
9783 | if ((scsi_cmd == READ_6) || | 10048 | sgblkp->next_sgblkp = NULL; |
9784 | (scsi_cmd == READ_10)) { | 10049 | |
9785 | addr = | 10050 | /* |
9786 | le32_to_cpu(scsiq->q1.data_addr) + | 10051 | * Get 8 byte aligned virtual and physical addresses |
9787 | le32_to_cpu(scsiq->q1.data_cnt); | 10052 | * for the allocated ADV_SG_BLOCK structure. |
9788 | extra_bytes = | 10053 | */ |
9789 | (uchar)((ushort)addr & 0x0003); | 10054 | sg_block = (ADV_SG_BLOCK *)ADV_8BALIGN(&sgblkp->sg_block); |
9790 | if ((extra_bytes != 0) | 10055 | sg_block_paddr = virt_to_bus(sg_block); |
9791 | && | 10056 | |
9792 | ((scsiq->q2. | 10057 | /* |
9793 | tag_code & | 10058 | * Check if this is the first 'adv_sgblk_t' for the |
9794 | ASC_TAG_FLAG_EXTRA_BYTES) | 10059 | * request. |
9795 | == 0)) { | 10060 | */ |
9796 | data_cnt = | 10061 | if (reqp->sgblkp == NULL) { |
9797 | le32_to_cpu(scsiq->q1. | 10062 | /* Request's first scatter-gather block. */ |
9798 | data_cnt); | 10063 | reqp->sgblkp = sgblkp; |
9799 | if (((ushort)data_cnt & 0x01FF) | 10064 | |
9800 | == 0) { | 10065 | /* |
9801 | scsiq->q2.tag_code |= | 10066 | * Set ADV_SCSI_REQ_T ADV_SG_BLOCK virtual and physical |
9802 | ASC_TAG_FLAG_EXTRA_BYTES; | 10067 | * address pointers. |
9803 | data_cnt -= (ASC_DCNT) | 10068 | */ |
9804 | extra_bytes; | 10069 | scsiqp->sg_list_ptr = sg_block; |
9805 | scsiq->q1.data_cnt = | 10070 | scsiqp->sg_real_addr = cpu_to_le32(sg_block_paddr); |
9806 | cpu_to_le32 | 10071 | } else { |
9807 | (data_cnt); | 10072 | /* Request's second or later scatter-gather block. */ |
9808 | scsiq->q1.extra_bytes = | 10073 | sgblkp->next_sgblkp = reqp->sgblkp; |
9809 | extra_bytes; | 10074 | reqp->sgblkp = sgblkp; |
9810 | } | 10075 | |
9811 | } | 10076 | /* |
9812 | } | 10077 | * Point the previous ADV_SG_BLOCK structure to |
9813 | } | 10078 | * the newly allocated ADV_SG_BLOCK structure. |
10079 | */ | ||
10080 | prev_sg_block->sg_ptr = cpu_to_le32(sg_block_paddr); | ||
9814 | } | 10081 | } |
9815 | n_q_required = 1; | 10082 | |
9816 | if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) || | 10083 | for (i = 0; i < NO_OF_SG_PER_BLOCK; i++) { |
9817 | ((scsiq->q1.cntl & QC_URGENT) != 0)) { | 10084 | sg_block->sg_list[i].sg_addr = |
9818 | if ((sta = AscSendScsiQueue(asc_dvc, scsiq, | 10085 | cpu_to_le32(sg_dma_address(slp)); |
9819 | n_q_required)) == 1) { | 10086 | sg_block->sg_list[i].sg_count = |
9820 | asc_dvc->in_critical_cnt--; | 10087 | cpu_to_le32(sg_dma_len(slp)); |
9821 | if (asc_exe_callback != 0) { | 10088 | ASC_STATS_ADD(scp->device->host, xfer_sect, |
9822 | (*asc_exe_callback) (asc_dvc, scsiq); | 10089 | DIV_ROUND_UP(sg_dma_len(slp), 512)); |
9823 | } | 10090 | |
9824 | DvcLeaveCritical(last_int_level); | 10091 | if (--sg_elem_cnt == 0) { /* Last ADV_SG_BLOCK and scatter-gather entry. */ |
9825 | return (sta); | 10092 | sg_block->sg_cnt = i + 1; |
10093 | sg_block->sg_ptr = 0L; /* Last ADV_SG_BLOCK in list. */ | ||
10094 | return ADV_SUCCESS; | ||
9826 | } | 10095 | } |
10096 | slp++; | ||
9827 | } | 10097 | } |
10098 | sg_block->sg_cnt = NO_OF_SG_PER_BLOCK; | ||
10099 | prev_sg_block = sg_block; | ||
9828 | } | 10100 | } |
9829 | asc_dvc->in_critical_cnt--; | ||
9830 | DvcLeaveCritical(last_int_level); | ||
9831 | return (sta); | ||
9832 | } | 10101 | } |
9833 | 10102 | ||
10103 | /* | ||
10104 | * Build a request structure for the Adv Library (Wide Board). | ||
10105 | * | ||
10106 | * If an adv_req_t can not be allocated to issue the request, | ||
10107 | * then return ASC_BUSY. If an error occurs, then return ASC_ERROR. | ||
10108 | * | ||
10109 | * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the | ||
10110 | * microcode for DMA addresses or math operations are byte swapped | ||
10111 | * to little-endian order. | ||
10112 | */ | ||
9834 | static int | 10113 | static int |
9835 | AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required) | 10114 | adv_build_req(struct asc_board *boardp, struct scsi_cmnd *scp, |
10115 | ADV_SCSI_REQ_Q **adv_scsiqpp) | ||
9836 | { | 10116 | { |
9837 | PortAddr iop_base; | 10117 | adv_req_t *reqp; |
9838 | uchar free_q_head; | 10118 | ADV_SCSI_REQ_Q *scsiqp; |
9839 | uchar next_qp; | 10119 | int i; |
9840 | uchar tid_no; | 10120 | int ret; |
9841 | uchar target_ix; | 10121 | int use_sg; |
9842 | int sta; | ||
9843 | 10122 | ||
9844 | iop_base = asc_dvc->iop_base; | 10123 | /* |
9845 | target_ix = scsiq->q2.target_ix; | 10124 | * Allocate an adv_req_t structure from the board to execute |
9846 | tid_no = ASC_TIX_TO_TID(target_ix); | 10125 | * the command. |
9847 | sta = 0; | 10126 | */ |
9848 | free_q_head = (uchar)AscGetVarFreeQHead(iop_base); | 10127 | if (boardp->adv_reqp == NULL) { |
9849 | if (n_q_required > 1) { | 10128 | ASC_DBG(1, "no free adv_req_t\n"); |
9850 | if ((next_qp = AscAllocMultipleFreeQueue(iop_base, | 10129 | ASC_STATS(scp->device->host, adv_build_noreq); |
9851 | free_q_head, (uchar) | 10130 | return ASC_BUSY; |
9852 | (n_q_required))) | 10131 | } else { |
9853 | != (uchar)ASC_QLINK_END) { | 10132 | reqp = boardp->adv_reqp; |
9854 | asc_dvc->last_q_shortage = 0; | 10133 | boardp->adv_reqp = reqp->next_reqp; |
9855 | scsiq->sg_head->queue_cnt = n_q_required - 1; | 10134 | reqp->next_reqp = NULL; |
9856 | scsiq->q1.q_no = free_q_head; | 10135 | } |
9857 | if ((sta = AscPutReadySgListQueue(asc_dvc, scsiq, | 10136 | |
9858 | free_q_head)) == 1) { | 10137 | /* |
9859 | AscPutVarFreeQHead(iop_base, next_qp); | 10138 | * Get 32-byte aligned ADV_SCSI_REQ_Q and ADV_SG_BLOCK pointers. |
9860 | asc_dvc->cur_total_qng += (uchar)(n_q_required); | 10139 | */ |
9861 | asc_dvc->cur_dvc_qng[tid_no]++; | 10140 | scsiqp = (ADV_SCSI_REQ_Q *)ADV_32BALIGN(&reqp->scsi_req_q); |
9862 | } | 10141 | |
9863 | return (sta); | 10142 | /* |
10143 | * Initialize the structure. | ||
10144 | */ | ||
10145 | scsiqp->cntl = scsiqp->scsi_cntl = scsiqp->done_status = 0; | ||
10146 | |||
10147 | /* | ||
10148 | * Set the ADV_SCSI_REQ_Q 'srb_ptr' to point to the adv_req_t structure. | ||
10149 | */ | ||
10150 | scsiqp->srb_ptr = ADV_VADDR_TO_U32(reqp); | ||
10151 | |||
10152 | /* | ||
10153 | * Set the adv_req_t 'cmndp' to point to the struct scsi_cmnd structure. | ||
10154 | */ | ||
10155 | reqp->cmndp = scp; | ||
10156 | |||
10157 | /* | ||
10158 | * Build the ADV_SCSI_REQ_Q request. | ||
10159 | */ | ||
10160 | |||
10161 | /* Set CDB length and copy it to the request structure. */ | ||
10162 | scsiqp->cdb_len = scp->cmd_len; | ||
10163 | /* Copy first 12 CDB bytes to cdb[]. */ | ||
10164 | for (i = 0; i < scp->cmd_len && i < 12; i++) { | ||
10165 | scsiqp->cdb[i] = scp->cmnd[i]; | ||
10166 | } | ||
10167 | /* Copy last 4 CDB bytes, if present, to cdb16[]. */ | ||
10168 | for (; i < scp->cmd_len; i++) { | ||
10169 | scsiqp->cdb16[i - 12] = scp->cmnd[i]; | ||
10170 | } | ||
10171 | |||
10172 | scsiqp->target_id = scp->device->id; | ||
10173 | scsiqp->target_lun = scp->device->lun; | ||
10174 | |||
10175 | scsiqp->sense_addr = cpu_to_le32(virt_to_bus(&scp->sense_buffer[0])); | ||
10176 | scsiqp->sense_len = sizeof(scp->sense_buffer); | ||
10177 | |||
10178 | /* Build ADV_SCSI_REQ_Q */ | ||
10179 | |||
10180 | use_sg = scsi_dma_map(scp); | ||
10181 | if (use_sg == 0) { | ||
10182 | /* Zero-length transfer */ | ||
10183 | reqp->sgblkp = NULL; | ||
10184 | scsiqp->data_cnt = 0; | ||
10185 | scsiqp->vdata_addr = NULL; | ||
10186 | |||
10187 | scsiqp->data_addr = 0; | ||
10188 | scsiqp->sg_list_ptr = NULL; | ||
10189 | scsiqp->sg_real_addr = 0; | ||
10190 | } else { | ||
10191 | if (use_sg > ADV_MAX_SG_LIST) { | ||
10192 | scmd_printk(KERN_ERR, scp, "use_sg %d > " | ||
10193 | "ADV_MAX_SG_LIST %d\n", use_sg, | ||
10194 | scp->device->host->sg_tablesize); | ||
10195 | scsi_dma_unmap(scp); | ||
10196 | scp->result = HOST_BYTE(DID_ERROR); | ||
10197 | |||
10198 | /* | ||
10199 | * Free the 'adv_req_t' structure by adding it back | ||
10200 | * to the board free list. | ||
10201 | */ | ||
10202 | reqp->next_reqp = boardp->adv_reqp; | ||
10203 | boardp->adv_reqp = reqp; | ||
10204 | |||
10205 | return ASC_ERROR; | ||
9864 | } | 10206 | } |
9865 | } else if (n_q_required == 1) { | 10207 | |
9866 | if ((next_qp = AscAllocFreeQueue(iop_base, | 10208 | scsiqp->data_cnt = cpu_to_le32(scsi_bufflen(scp)); |
9867 | free_q_head)) != | 10209 | |
9868 | ASC_QLINK_END) { | 10210 | ret = adv_get_sglist(boardp, reqp, scp, use_sg); |
9869 | scsiq->q1.q_no = free_q_head; | 10211 | if (ret != ADV_SUCCESS) { |
9870 | if ((sta = AscPutReadyQueue(asc_dvc, scsiq, | 10212 | /* |
9871 | free_q_head)) == 1) { | 10213 | * Free the adv_req_t structure by adding it back to |
9872 | AscPutVarFreeQHead(iop_base, next_qp); | 10214 | * the board free list. |
9873 | asc_dvc->cur_total_qng++; | 10215 | */ |
9874 | asc_dvc->cur_dvc_qng[tid_no]++; | 10216 | reqp->next_reqp = boardp->adv_reqp; |
9875 | } | 10217 | boardp->adv_reqp = reqp; |
9876 | return (sta); | 10218 | |
10219 | return ret; | ||
9877 | } | 10220 | } |
10221 | |||
10222 | ASC_STATS_ADD(scp->device->host, xfer_elem, use_sg); | ||
9878 | } | 10223 | } |
9879 | return (sta); | 10224 | |
10225 | ASC_STATS(scp->device->host, xfer_cnt); | ||
10226 | |||
10227 | ASC_DBG_PRT_ADV_SCSI_REQ_Q(2, scsiqp); | ||
10228 | ASC_DBG_PRT_CDB(1, scp->cmnd, scp->cmd_len); | ||
10229 | |||
10230 | *adv_scsiqpp = scsiqp; | ||
10231 | |||
10232 | return ASC_NOERROR; | ||
9880 | } | 10233 | } |
9881 | 10234 | ||
9882 | static int AscSgListToQueue(int sg_list) | 10235 | static int AscSgListToQueue(int sg_list) |
@@ -9886,7 +10239,7 @@ static int AscSgListToQueue(int sg_list) | |||
9886 | n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q); | 10239 | n_sg_list_qs = ((sg_list - 1) / ASC_SG_LIST_PER_Q); |
9887 | if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0) | 10240 | if (((sg_list - 1) % ASC_SG_LIST_PER_Q) != 0) |
9888 | n_sg_list_qs++; | 10241 | n_sg_list_qs++; |
9889 | return (n_sg_list_qs + 1); | 10242 | return n_sg_list_qs + 1; |
9890 | } | 10243 | } |
9891 | 10244 | ||
9892 | static uint | 10245 | static uint |
@@ -9901,7 +10254,7 @@ AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs) | |||
9901 | tid_no = ASC_TIX_TO_TID(target_ix); | 10254 | tid_no = ASC_TIX_TO_TID(target_ix); |
9902 | if ((asc_dvc->unit_not_ready & target_id) || | 10255 | if ((asc_dvc->unit_not_ready & target_id) || |
9903 | (asc_dvc->queue_full_or_busy & target_id)) { | 10256 | (asc_dvc->queue_full_or_busy & target_id)) { |
9904 | return (0); | 10257 | return 0; |
9905 | } | 10258 | } |
9906 | if (n_qs == 1) { | 10259 | if (n_qs == 1) { |
9907 | cur_used_qs = (uint) asc_dvc->cur_total_qng + | 10260 | cur_used_qs = (uint) asc_dvc->cur_total_qng + |
@@ -9914,9 +10267,9 @@ AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs) | |||
9914 | cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs; | 10267 | cur_free_qs = (uint) asc_dvc->max_total_qng - cur_used_qs; |
9915 | if (asc_dvc->cur_dvc_qng[tid_no] >= | 10268 | if (asc_dvc->cur_dvc_qng[tid_no] >= |
9916 | asc_dvc->max_dvc_qng[tid_no]) { | 10269 | asc_dvc->max_dvc_qng[tid_no]) { |
9917 | return (0); | 10270 | return 0; |
9918 | } | 10271 | } |
9919 | return (cur_free_qs); | 10272 | return cur_free_qs; |
9920 | } | 10273 | } |
9921 | if (n_qs > 1) { | 10274 | if (n_qs > 1) { |
9922 | if ((n_qs > asc_dvc->last_q_shortage) | 10275 | if ((n_qs > asc_dvc->last_q_shortage) |
@@ -9924,7 +10277,62 @@ AscGetNumOfFreeQueue(ASC_DVC_VAR *asc_dvc, uchar target_ix, uchar n_qs) | |||
9924 | asc_dvc->last_q_shortage = n_qs; | 10277 | asc_dvc->last_q_shortage = n_qs; |
9925 | } | 10278 | } |
9926 | } | 10279 | } |
9927 | return (0); | 10280 | return 0; |
10281 | } | ||
10282 | |||
10283 | static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head) | ||
10284 | { | ||
10285 | ushort q_addr; | ||
10286 | uchar next_qp; | ||
10287 | uchar q_status; | ||
10288 | |||
10289 | q_addr = ASC_QNO_TO_QADDR(free_q_head); | ||
10290 | q_status = (uchar)AscReadLramByte(iop_base, | ||
10291 | (ushort)(q_addr + | ||
10292 | ASC_SCSIQ_B_STATUS)); | ||
10293 | next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD)); | ||
10294 | if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) | ||
10295 | return next_qp; | ||
10296 | return ASC_QLINK_END; | ||
10297 | } | ||
10298 | |||
10299 | static uchar | ||
10300 | AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q) | ||
10301 | { | ||
10302 | uchar i; | ||
10303 | |||
10304 | for (i = 0; i < n_free_q; i++) { | ||
10305 | free_q_head = AscAllocFreeQueue(iop_base, free_q_head); | ||
10306 | if (free_q_head == ASC_QLINK_END) | ||
10307 | break; | ||
10308 | } | ||
10309 | return free_q_head; | ||
10310 | } | ||
10311 | |||
10312 | /* | ||
10313 | * void | ||
10314 | * DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words) | ||
10315 | * | ||
10316 | * Calling/Exit State: | ||
10317 | * none | ||
10318 | * | ||
10319 | * Description: | ||
10320 | * Output an ASC_SCSI_Q structure to the chip | ||
10321 | */ | ||
10322 | static void | ||
10323 | DvcPutScsiQ(PortAddr iop_base, ushort s_addr, uchar *outbuf, int words) | ||
10324 | { | ||
10325 | int i; | ||
10326 | |||
10327 | ASC_DBG_PRT_HEX(2, "DvcPutScsiQ", outbuf, 2 * words); | ||
10328 | AscSetChipLramAddr(iop_base, s_addr); | ||
10329 | for (i = 0; i < 2 * words; i += 2) { | ||
10330 | if (i == 4 || i == 20) { | ||
10331 | continue; | ||
10332 | } | ||
10333 | outpw(iop_base + IOP_RAM_DATA, | ||
10334 | ((ushort)outbuf[i + 1] << 8) | outbuf[i]); | ||
10335 | } | ||
9928 | } | 10336 | } |
9929 | 10337 | ||
9930 | static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no) | 10338 | static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no) |
@@ -9966,7 +10374,7 @@ static int AscPutReadyQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no) | |||
9966 | (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS), | 10374 | (ushort)(q_addr + (ushort)ASC_SCSIQ_B_STATUS), |
9967 | (ushort)(((ushort)scsiq->q1. | 10375 | (ushort)(((ushort)scsiq->q1. |
9968 | q_no << 8) | (ushort)QS_READY)); | 10376 | q_no << 8) | (ushort)QS_READY)); |
9969 | return (1); | 10377 | return 1; |
9970 | } | 10378 | } |
9971 | 10379 | ||
9972 | static int | 10380 | static int |
@@ -10104,491 +10512,651 @@ AscPutReadySgListQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar q_no) | |||
10104 | } | 10512 | } |
10105 | 10513 | ||
10106 | static int | 10514 | static int |
10107 | AscSetRunChipSynRegAtID(PortAddr iop_base, uchar tid_no, uchar sdtr_data) | 10515 | AscSendScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq, uchar n_q_required) |
10108 | { | 10516 | { |
10109 | int sta = FALSE; | 10517 | PortAddr iop_base; |
10518 | uchar free_q_head; | ||
10519 | uchar next_qp; | ||
10520 | uchar tid_no; | ||
10521 | uchar target_ix; | ||
10522 | int sta; | ||
10110 | 10523 | ||
10111 | if (AscHostReqRiscHalt(iop_base)) { | 10524 | iop_base = asc_dvc->iop_base; |
10112 | sta = AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data); | 10525 | target_ix = scsiq->q2.target_ix; |
10113 | AscStartChip(iop_base); | 10526 | tid_no = ASC_TIX_TO_TID(target_ix); |
10114 | return (sta); | 10527 | sta = 0; |
10528 | free_q_head = (uchar)AscGetVarFreeQHead(iop_base); | ||
10529 | if (n_q_required > 1) { | ||
10530 | next_qp = AscAllocMultipleFreeQueue(iop_base, free_q_head, | ||
10531 | (uchar)n_q_required); | ||
10532 | if (next_qp != ASC_QLINK_END) { | ||
10533 | asc_dvc->last_q_shortage = 0; | ||
10534 | scsiq->sg_head->queue_cnt = n_q_required - 1; | ||
10535 | scsiq->q1.q_no = free_q_head; | ||
10536 | sta = AscPutReadySgListQueue(asc_dvc, scsiq, | ||
10537 | free_q_head); | ||
10538 | } | ||
10539 | } else if (n_q_required == 1) { | ||
10540 | next_qp = AscAllocFreeQueue(iop_base, free_q_head); | ||
10541 | if (next_qp != ASC_QLINK_END) { | ||
10542 | scsiq->q1.q_no = free_q_head; | ||
10543 | sta = AscPutReadyQueue(asc_dvc, scsiq, free_q_head); | ||
10544 | } | ||
10115 | } | 10545 | } |
10116 | return (sta); | 10546 | if (sta == 1) { |
10547 | AscPutVarFreeQHead(iop_base, next_qp); | ||
10548 | asc_dvc->cur_total_qng += n_q_required; | ||
10549 | asc_dvc->cur_dvc_qng[tid_no]++; | ||
10550 | } | ||
10551 | return sta; | ||
10117 | } | 10552 | } |
10118 | 10553 | ||
10119 | static int AscSetChipSynRegAtID(PortAddr iop_base, uchar id, uchar sdtr_data) | 10554 | #define ASC_SYN_OFFSET_ONE_DISABLE_LIST 16 |
10555 | static uchar _syn_offset_one_disable_cmd[ASC_SYN_OFFSET_ONE_DISABLE_LIST] = { | ||
10556 | INQUIRY, | ||
10557 | REQUEST_SENSE, | ||
10558 | READ_CAPACITY, | ||
10559 | READ_TOC, | ||
10560 | MODE_SELECT, | ||
10561 | MODE_SENSE, | ||
10562 | MODE_SELECT_10, | ||
10563 | MODE_SENSE_10, | ||
10564 | 0xFF, | ||
10565 | 0xFF, | ||
10566 | 0xFF, | ||
10567 | 0xFF, | ||
10568 | 0xFF, | ||
10569 | 0xFF, | ||
10570 | 0xFF, | ||
10571 | 0xFF | ||
10572 | }; | ||
10573 | |||
10574 | static int AscExeScsiQueue(ASC_DVC_VAR *asc_dvc, ASC_SCSI_Q *scsiq) | ||
10120 | { | 10575 | { |
10121 | ASC_SCSI_BIT_ID_TYPE org_id; | 10576 | PortAddr iop_base; |
10577 | int sta; | ||
10578 | int n_q_required; | ||
10579 | int disable_syn_offset_one_fix; | ||
10122 | int i; | 10580 | int i; |
10123 | int sta = TRUE; | 10581 | ASC_PADDR addr; |
10582 | ushort sg_entry_cnt = 0; | ||
10583 | ushort sg_entry_cnt_minus_one = 0; | ||
10584 | uchar target_ix; | ||
10585 | uchar tid_no; | ||
10586 | uchar sdtr_data; | ||
10587 | uchar extra_bytes; | ||
10588 | uchar scsi_cmd; | ||
10589 | uchar disable_cmd; | ||
10590 | ASC_SG_HEAD *sg_head; | ||
10591 | ASC_DCNT data_cnt; | ||
10124 | 10592 | ||
10125 | AscSetBank(iop_base, 1); | 10593 | iop_base = asc_dvc->iop_base; |
10126 | org_id = AscReadChipDvcID(iop_base); | 10594 | sg_head = scsiq->sg_head; |
10127 | for (i = 0; i <= ASC_MAX_TID; i++) { | 10595 | if (asc_dvc->err_code != 0) |
10128 | if (org_id == (0x01 << i)) | 10596 | return (ERR); |
10129 | break; | 10597 | scsiq->q1.q_no = 0; |
10598 | if ((scsiq->q2.tag_code & ASC_TAG_FLAG_EXTRA_BYTES) == 0) { | ||
10599 | scsiq->q1.extra_bytes = 0; | ||
10130 | } | 10600 | } |
10131 | org_id = (ASC_SCSI_BIT_ID_TYPE) i; | 10601 | sta = 0; |
10132 | AscWriteChipDvcID(iop_base, id); | 10602 | target_ix = scsiq->q2.target_ix; |
10133 | if (AscReadChipDvcID(iop_base) == (0x01 << id)) { | 10603 | tid_no = ASC_TIX_TO_TID(target_ix); |
10134 | AscSetBank(iop_base, 0); | 10604 | n_q_required = 1; |
10135 | AscSetChipSyn(iop_base, sdtr_data); | 10605 | if (scsiq->cdbptr[0] == REQUEST_SENSE) { |
10136 | if (AscGetChipSyn(iop_base) != sdtr_data) { | 10606 | if ((asc_dvc->init_sdtr & scsiq->q1.target_id) != 0) { |
10137 | sta = FALSE; | 10607 | asc_dvc->sdtr_done &= ~scsiq->q1.target_id; |
10608 | sdtr_data = AscGetMCodeInitSDTRAtID(iop_base, tid_no); | ||
10609 | AscMsgOutSDTR(asc_dvc, | ||
10610 | asc_dvc-> | ||
10611 | sdtr_period_tbl[(sdtr_data >> 4) & | ||
10612 | (uchar)(asc_dvc-> | ||
10613 | max_sdtr_index - | ||
10614 | 1)], | ||
10615 | (uchar)(sdtr_data & (uchar) | ||
10616 | ASC_SYN_MAX_OFFSET)); | ||
10617 | scsiq->q1.cntl |= (QC_MSG_OUT | QC_URGENT); | ||
10138 | } | 10618 | } |
10619 | } | ||
10620 | if (asc_dvc->in_critical_cnt != 0) { | ||
10621 | AscSetLibErrorCode(asc_dvc, ASCQ_ERR_CRITICAL_RE_ENTRY); | ||
10622 | return (ERR); | ||
10623 | } | ||
10624 | asc_dvc->in_critical_cnt++; | ||
10625 | if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) { | ||
10626 | if ((sg_entry_cnt = sg_head->entry_cnt) == 0) { | ||
10627 | asc_dvc->in_critical_cnt--; | ||
10628 | return (ERR); | ||
10629 | } | ||
10630 | #if !CC_VERY_LONG_SG_LIST | ||
10631 | if (sg_entry_cnt > ASC_MAX_SG_LIST) { | ||
10632 | asc_dvc->in_critical_cnt--; | ||
10633 | return (ERR); | ||
10634 | } | ||
10635 | #endif /* !CC_VERY_LONG_SG_LIST */ | ||
10636 | if (sg_entry_cnt == 1) { | ||
10637 | scsiq->q1.data_addr = | ||
10638 | (ADV_PADDR)sg_head->sg_list[0].addr; | ||
10639 | scsiq->q1.data_cnt = | ||
10640 | (ADV_DCNT)sg_head->sg_list[0].bytes; | ||
10641 | scsiq->q1.cntl &= ~(QC_SG_HEAD | QC_SG_SWAP_QUEUE); | ||
10642 | } | ||
10643 | sg_entry_cnt_minus_one = sg_entry_cnt - 1; | ||
10644 | } | ||
10645 | scsi_cmd = scsiq->cdbptr[0]; | ||
10646 | disable_syn_offset_one_fix = FALSE; | ||
10647 | if ((asc_dvc->pci_fix_asyn_xfer & scsiq->q1.target_id) && | ||
10648 | !(asc_dvc->pci_fix_asyn_xfer_always & scsiq->q1.target_id)) { | ||
10649 | if (scsiq->q1.cntl & QC_SG_HEAD) { | ||
10650 | data_cnt = 0; | ||
10651 | for (i = 0; i < sg_entry_cnt; i++) { | ||
10652 | data_cnt += | ||
10653 | (ADV_DCNT)le32_to_cpu(sg_head->sg_list[i]. | ||
10654 | bytes); | ||
10655 | } | ||
10656 | } else { | ||
10657 | data_cnt = le32_to_cpu(scsiq->q1.data_cnt); | ||
10658 | } | ||
10659 | if (data_cnt != 0UL) { | ||
10660 | if (data_cnt < 512UL) { | ||
10661 | disable_syn_offset_one_fix = TRUE; | ||
10662 | } else { | ||
10663 | for (i = 0; i < ASC_SYN_OFFSET_ONE_DISABLE_LIST; | ||
10664 | i++) { | ||
10665 | disable_cmd = | ||
10666 | _syn_offset_one_disable_cmd[i]; | ||
10667 | if (disable_cmd == 0xFF) { | ||
10668 | break; | ||
10669 | } | ||
10670 | if (scsi_cmd == disable_cmd) { | ||
10671 | disable_syn_offset_one_fix = | ||
10672 | TRUE; | ||
10673 | break; | ||
10674 | } | ||
10675 | } | ||
10676 | } | ||
10677 | } | ||
10678 | } | ||
10679 | if (disable_syn_offset_one_fix) { | ||
10680 | scsiq->q2.tag_code &= ~MSG_SIMPLE_TAG; | ||
10681 | scsiq->q2.tag_code |= (ASC_TAG_FLAG_DISABLE_ASYN_USE_SYN_FIX | | ||
10682 | ASC_TAG_FLAG_DISABLE_DISCONNECT); | ||
10139 | } else { | 10683 | } else { |
10140 | sta = FALSE; | 10684 | scsiq->q2.tag_code &= 0x27; |
10141 | } | 10685 | } |
10142 | AscSetBank(iop_base, 1); | 10686 | if ((scsiq->q1.cntl & QC_SG_HEAD) != 0) { |
10143 | AscWriteChipDvcID(iop_base, org_id); | 10687 | if (asc_dvc->bug_fix_cntl) { |
10144 | AscSetBank(iop_base, 0); | 10688 | if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) { |
10689 | if ((scsi_cmd == READ_6) || | ||
10690 | (scsi_cmd == READ_10)) { | ||
10691 | addr = | ||
10692 | (ADV_PADDR)le32_to_cpu(sg_head-> | ||
10693 | sg_list | ||
10694 | [sg_entry_cnt_minus_one]. | ||
10695 | addr) + | ||
10696 | (ADV_DCNT)le32_to_cpu(sg_head-> | ||
10697 | sg_list | ||
10698 | [sg_entry_cnt_minus_one]. | ||
10699 | bytes); | ||
10700 | extra_bytes = | ||
10701 | (uchar)((ushort)addr & 0x0003); | ||
10702 | if ((extra_bytes != 0) | ||
10703 | && | ||
10704 | ((scsiq->q2. | ||
10705 | tag_code & | ||
10706 | ASC_TAG_FLAG_EXTRA_BYTES) | ||
10707 | == 0)) { | ||
10708 | scsiq->q2.tag_code |= | ||
10709 | ASC_TAG_FLAG_EXTRA_BYTES; | ||
10710 | scsiq->q1.extra_bytes = | ||
10711 | extra_bytes; | ||
10712 | data_cnt = | ||
10713 | le32_to_cpu(sg_head-> | ||
10714 | sg_list | ||
10715 | [sg_entry_cnt_minus_one]. | ||
10716 | bytes); | ||
10717 | data_cnt -= | ||
10718 | (ASC_DCNT) extra_bytes; | ||
10719 | sg_head-> | ||
10720 | sg_list | ||
10721 | [sg_entry_cnt_minus_one]. | ||
10722 | bytes = | ||
10723 | cpu_to_le32(data_cnt); | ||
10724 | } | ||
10725 | } | ||
10726 | } | ||
10727 | } | ||
10728 | sg_head->entry_to_copy = sg_head->entry_cnt; | ||
10729 | #if CC_VERY_LONG_SG_LIST | ||
10730 | /* | ||
10731 | * Set the sg_entry_cnt to the maximum possible. The rest of | ||
10732 | * the SG elements will be copied when the RISC completes the | ||
10733 | * SG elements that fit and halts. | ||
10734 | */ | ||
10735 | if (sg_entry_cnt > ASC_MAX_SG_LIST) { | ||
10736 | sg_entry_cnt = ASC_MAX_SG_LIST; | ||
10737 | } | ||
10738 | #endif /* CC_VERY_LONG_SG_LIST */ | ||
10739 | n_q_required = AscSgListToQueue(sg_entry_cnt); | ||
10740 | if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, n_q_required) >= | ||
10741 | (uint) n_q_required) | ||
10742 | || ((scsiq->q1.cntl & QC_URGENT) != 0)) { | ||
10743 | if ((sta = | ||
10744 | AscSendScsiQueue(asc_dvc, scsiq, | ||
10745 | n_q_required)) == 1) { | ||
10746 | asc_dvc->in_critical_cnt--; | ||
10747 | return (sta); | ||
10748 | } | ||
10749 | } | ||
10750 | } else { | ||
10751 | if (asc_dvc->bug_fix_cntl) { | ||
10752 | if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_IF_NOT_DWB) { | ||
10753 | if ((scsi_cmd == READ_6) || | ||
10754 | (scsi_cmd == READ_10)) { | ||
10755 | addr = | ||
10756 | le32_to_cpu(scsiq->q1.data_addr) + | ||
10757 | le32_to_cpu(scsiq->q1.data_cnt); | ||
10758 | extra_bytes = | ||
10759 | (uchar)((ushort)addr & 0x0003); | ||
10760 | if ((extra_bytes != 0) | ||
10761 | && | ||
10762 | ((scsiq->q2. | ||
10763 | tag_code & | ||
10764 | ASC_TAG_FLAG_EXTRA_BYTES) | ||
10765 | == 0)) { | ||
10766 | data_cnt = | ||
10767 | le32_to_cpu(scsiq->q1. | ||
10768 | data_cnt); | ||
10769 | if (((ushort)data_cnt & 0x01FF) | ||
10770 | == 0) { | ||
10771 | scsiq->q2.tag_code |= | ||
10772 | ASC_TAG_FLAG_EXTRA_BYTES; | ||
10773 | data_cnt -= (ASC_DCNT) | ||
10774 | extra_bytes; | ||
10775 | scsiq->q1.data_cnt = | ||
10776 | cpu_to_le32 | ||
10777 | (data_cnt); | ||
10778 | scsiq->q1.extra_bytes = | ||
10779 | extra_bytes; | ||
10780 | } | ||
10781 | } | ||
10782 | } | ||
10783 | } | ||
10784 | } | ||
10785 | n_q_required = 1; | ||
10786 | if ((AscGetNumOfFreeQueue(asc_dvc, target_ix, 1) >= 1) || | ||
10787 | ((scsiq->q1.cntl & QC_URGENT) != 0)) { | ||
10788 | if ((sta = AscSendScsiQueue(asc_dvc, scsiq, | ||
10789 | n_q_required)) == 1) { | ||
10790 | asc_dvc->in_critical_cnt--; | ||
10791 | return (sta); | ||
10792 | } | ||
10793 | } | ||
10794 | } | ||
10795 | asc_dvc->in_critical_cnt--; | ||
10145 | return (sta); | 10796 | return (sta); |
10146 | } | 10797 | } |
10147 | 10798 | ||
10148 | static ushort AscInitLram(ASC_DVC_VAR *asc_dvc) | 10799 | /* |
10800 | * AdvExeScsiQueue() - Send a request to the RISC microcode program. | ||
10801 | * | ||
10802 | * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q, | ||
10803 | * add the carrier to the ICQ (Initiator Command Queue), and tickle the | ||
10804 | * RISC to notify it a new command is ready to be executed. | ||
10805 | * | ||
10806 | * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be | ||
10807 | * set to SCSI_MAX_RETRY. | ||
10808 | * | ||
10809 | * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode | ||
10810 | * for DMA addresses or math operations are byte swapped to little-endian | ||
10811 | * order. | ||
10812 | * | ||
10813 | * Return: | ||
10814 | * ADV_SUCCESS(1) - The request was successfully queued. | ||
10815 | * ADV_BUSY(0) - Resource unavailable; Retry again after pending | ||
10816 | * request completes. | ||
10817 | * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure | ||
10818 | * host IC error. | ||
10819 | */ | ||
10820 | static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) | ||
10149 | { | 10821 | { |
10150 | uchar i; | 10822 | AdvPortAddr iop_base; |
10151 | ushort s_addr; | 10823 | ADV_PADDR req_paddr; |
10152 | PortAddr iop_base; | 10824 | ADV_CARR_T *new_carrp; |
10153 | ushort warn_code; | ||
10154 | 10825 | ||
10155 | iop_base = asc_dvc->iop_base; | 10826 | /* |
10156 | warn_code = 0; | 10827 | * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID. |
10157 | AscMemWordSetLram(iop_base, ASC_QADR_BEG, 0, | 10828 | */ |
10158 | (ushort)(((int)(asc_dvc->max_total_qng + 2 + 1) * | 10829 | if (scsiq->target_id > ADV_MAX_TID) { |
10159 | 64) >> 1) | 10830 | scsiq->host_status = QHSTA_M_INVALID_DEVICE; |
10160 | ); | 10831 | scsiq->done_status = QD_WITH_ERROR; |
10161 | i = ASC_MIN_ACTIVE_QNO; | 10832 | return ADV_ERROR; |
10162 | s_addr = ASC_QADR_BEG + ASC_QBLK_SIZE; | ||
10163 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD), | ||
10164 | (uchar)(i + 1)); | ||
10165 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD), | ||
10166 | (uchar)(asc_dvc->max_total_qng)); | ||
10167 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO), | ||
10168 | (uchar)i); | ||
10169 | i++; | ||
10170 | s_addr += ASC_QBLK_SIZE; | ||
10171 | for (; i < asc_dvc->max_total_qng; i++, s_addr += ASC_QBLK_SIZE) { | ||
10172 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD), | ||
10173 | (uchar)(i + 1)); | ||
10174 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD), | ||
10175 | (uchar)(i - 1)); | ||
10176 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO), | ||
10177 | (uchar)i); | ||
10178 | } | ||
10179 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_FWD), | ||
10180 | (uchar)ASC_QLINK_END); | ||
10181 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_BWD), | ||
10182 | (uchar)(asc_dvc->max_total_qng - 1)); | ||
10183 | AscWriteLramByte(iop_base, (ushort)(s_addr + ASC_SCSIQ_B_QNO), | ||
10184 | (uchar)asc_dvc->max_total_qng); | ||
10185 | i++; | ||
10186 | s_addr += ASC_QBLK_SIZE; | ||
10187 | for (; i <= (uchar)(asc_dvc->max_total_qng + 3); | ||
10188 | i++, s_addr += ASC_QBLK_SIZE) { | ||
10189 | AscWriteLramByte(iop_base, | ||
10190 | (ushort)(s_addr + (ushort)ASC_SCSIQ_B_FWD), i); | ||
10191 | AscWriteLramByte(iop_base, | ||
10192 | (ushort)(s_addr + (ushort)ASC_SCSIQ_B_BWD), i); | ||
10193 | AscWriteLramByte(iop_base, | ||
10194 | (ushort)(s_addr + (ushort)ASC_SCSIQ_B_QNO), i); | ||
10195 | } | 10833 | } |
10196 | return (warn_code); | ||
10197 | } | ||
10198 | |||
10199 | static ushort AscInitQLinkVar(ASC_DVC_VAR *asc_dvc) | ||
10200 | { | ||
10201 | PortAddr iop_base; | ||
10202 | int i; | ||
10203 | ushort lram_addr; | ||
10204 | 10834 | ||
10205 | iop_base = asc_dvc->iop_base; | 10835 | iop_base = asc_dvc->iop_base; |
10206 | AscPutRiscVarFreeQHead(iop_base, 1); | ||
10207 | AscPutRiscVarDoneQTail(iop_base, asc_dvc->max_total_qng); | ||
10208 | AscPutVarFreeQHead(iop_base, 1); | ||
10209 | AscPutVarDoneQTail(iop_base, asc_dvc->max_total_qng); | ||
10210 | AscWriteLramByte(iop_base, ASCV_BUSY_QHEAD_B, | ||
10211 | (uchar)((int)asc_dvc->max_total_qng + 1)); | ||
10212 | AscWriteLramByte(iop_base, ASCV_DISC1_QHEAD_B, | ||
10213 | (uchar)((int)asc_dvc->max_total_qng + 2)); | ||
10214 | AscWriteLramByte(iop_base, (ushort)ASCV_TOTAL_READY_Q_B, | ||
10215 | asc_dvc->max_total_qng); | ||
10216 | AscWriteLramWord(iop_base, ASCV_ASCDVC_ERR_CODE_W, 0); | ||
10217 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0); | ||
10218 | AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, 0); | ||
10219 | AscWriteLramByte(iop_base, ASCV_SCSIBUSY_B, 0); | ||
10220 | AscWriteLramByte(iop_base, ASCV_WTM_FLAG_B, 0); | ||
10221 | AscPutQDoneInProgress(iop_base, 0); | ||
10222 | lram_addr = ASC_QADR_BEG; | ||
10223 | for (i = 0; i < 32; i++, lram_addr += 2) { | ||
10224 | AscWriteLramWord(iop_base, lram_addr, 0); | ||
10225 | } | ||
10226 | return (0); | ||
10227 | } | ||
10228 | 10836 | ||
10229 | static int AscSetLibErrorCode(ASC_DVC_VAR *asc_dvc, ushort err_code) | 10837 | /* |
10230 | { | 10838 | * Allocate a carrier ensuring at least one carrier always |
10231 | if (asc_dvc->err_code == 0) { | 10839 | * remains on the freelist and initialize fields. |
10232 | asc_dvc->err_code = err_code; | 10840 | */ |
10233 | AscWriteLramWord(asc_dvc->iop_base, ASCV_ASCDVC_ERR_CODE_W, | 10841 | if ((new_carrp = asc_dvc->carr_freelist) == NULL) { |
10234 | err_code); | 10842 | return ADV_BUSY; |
10235 | } | 10843 | } |
10236 | return (err_code); | 10844 | asc_dvc->carr_freelist = (ADV_CARR_T *) |
10237 | } | 10845 | ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa)); |
10846 | asc_dvc->carr_pending_cnt++; | ||
10238 | 10847 | ||
10239 | static uchar | 10848 | /* |
10240 | AscMsgOutSDTR(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar sdtr_offset) | 10849 | * Set the carrier to be a stopper by setting 'next_vpa' |
10241 | { | 10850 | * to the stopper value. The current stopper will be changed |
10242 | EXT_MSG sdtr_buf; | 10851 | * below to point to the new stopper. |
10243 | uchar sdtr_period_index; | 10852 | */ |
10244 | PortAddr iop_base; | 10853 | new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); |
10245 | 10854 | ||
10246 | iop_base = asc_dvc->iop_base; | 10855 | /* |
10247 | sdtr_buf.msg_type = MS_EXTEND; | 10856 | * Clear the ADV_SCSI_REQ_Q done flag. |
10248 | sdtr_buf.msg_len = MS_SDTR_LEN; | 10857 | */ |
10249 | sdtr_buf.msg_req = MS_SDTR_CODE; | 10858 | scsiq->a_flag &= ~ADV_SCSIQ_DONE; |
10250 | sdtr_buf.xfer_period = sdtr_period; | ||
10251 | sdtr_offset &= ASC_SYN_MAX_OFFSET; | ||
10252 | sdtr_buf.req_ack_offset = sdtr_offset; | ||
10253 | if ((sdtr_period_index = | ||
10254 | AscGetSynPeriodIndex(asc_dvc, sdtr_period)) <= | ||
10255 | asc_dvc->max_sdtr_index) { | ||
10256 | AscMemWordCopyPtrToLram(iop_base, | ||
10257 | ASCV_MSGOUT_BEG, | ||
10258 | (uchar *)&sdtr_buf, | ||
10259 | sizeof(EXT_MSG) >> 1); | ||
10260 | return ((sdtr_period_index << 4) | sdtr_offset); | ||
10261 | } else { | ||
10262 | 10859 | ||
10263 | sdtr_buf.req_ack_offset = 0; | 10860 | req_paddr = virt_to_bus(scsiq); |
10264 | AscMemWordCopyPtrToLram(iop_base, | 10861 | BUG_ON(req_paddr & 31); |
10265 | ASCV_MSGOUT_BEG, | 10862 | /* Wait for assertion before making little-endian */ |
10266 | (uchar *)&sdtr_buf, | 10863 | req_paddr = cpu_to_le32(req_paddr); |
10267 | sizeof(EXT_MSG) >> 1); | ||
10268 | return (0); | ||
10269 | } | ||
10270 | } | ||
10271 | 10864 | ||
10272 | static uchar | 10865 | /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */ |
10273 | AscCalSDTRData(ASC_DVC_VAR *asc_dvc, uchar sdtr_period, uchar syn_offset) | 10866 | scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq)); |
10274 | { | 10867 | scsiq->scsiq_rptr = req_paddr; |
10275 | uchar byte; | ||
10276 | uchar sdtr_period_ix; | ||
10277 | 10868 | ||
10278 | sdtr_period_ix = AscGetSynPeriodIndex(asc_dvc, sdtr_period); | 10869 | scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp)); |
10279 | if ((sdtr_period_ix > asc_dvc->max_sdtr_index) | 10870 | /* |
10280 | ) { | 10871 | * Every ADV_CARR_T.carr_pa is byte swapped to little-endian |
10281 | return (0xFF); | 10872 | * order during initialization. |
10282 | } | 10873 | */ |
10283 | byte = (sdtr_period_ix << 4) | (syn_offset & ASC_SYN_MAX_OFFSET); | 10874 | scsiq->carr_pa = asc_dvc->icq_sp->carr_pa; |
10284 | return (byte); | ||
10285 | } | ||
10286 | 10875 | ||
10287 | static void AscSetChipSDTR(PortAddr iop_base, uchar sdtr_data, uchar tid_no) | 10876 | /* |
10288 | { | 10877 | * Use the current stopper to send the ADV_SCSI_REQ_Q command to |
10289 | AscSetChipSynRegAtID(iop_base, tid_no, sdtr_data); | 10878 | * the microcode. The newly allocated stopper will become the new |
10290 | AscPutMCodeSDTRDoneAtID(iop_base, tid_no, sdtr_data); | 10879 | * stopper. |
10291 | return; | 10880 | */ |
10292 | } | 10881 | asc_dvc->icq_sp->areq_vpa = req_paddr; |
10293 | 10882 | ||
10294 | static uchar AscGetSynPeriodIndex(ASC_DVC_VAR *asc_dvc, uchar syn_time) | 10883 | /* |
10295 | { | 10884 | * Set the 'next_vpa' pointer for the old stopper to be the |
10296 | uchar *period_table; | 10885 | * physical address of the new stopper. The RISC can only |
10297 | int max_index; | 10886 | * follow physical addresses. |
10298 | int min_index; | 10887 | */ |
10299 | int i; | 10888 | asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa; |
10300 | 10889 | ||
10301 | period_table = asc_dvc->sdtr_period_tbl; | 10890 | /* |
10302 | max_index = (int)asc_dvc->max_sdtr_index; | 10891 | * Set the host adapter stopper pointer to point to the new carrier. |
10303 | min_index = (int)asc_dvc->host_init_sdtr_index; | 10892 | */ |
10304 | if ((syn_time <= period_table[max_index])) { | 10893 | asc_dvc->icq_sp = new_carrp; |
10305 | for (i = min_index; i < (max_index - 1); i++) { | 10894 | |
10306 | if (syn_time <= period_table[i]) { | 10895 | if (asc_dvc->chip_type == ADV_CHIP_ASC3550 || |
10307 | return ((uchar)i); | 10896 | asc_dvc->chip_type == ADV_CHIP_ASC38C0800) { |
10308 | } | 10897 | /* |
10898 | * Tickle the RISC to tell it to read its Command Queue Head pointer. | ||
10899 | */ | ||
10900 | AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A); | ||
10901 | if (asc_dvc->chip_type == ADV_CHIP_ASC3550) { | ||
10902 | /* | ||
10903 | * Clear the tickle value. In the ASC-3550 the RISC flag | ||
10904 | * command 'clr_tickle_a' does not work unless the host | ||
10905 | * value is cleared. | ||
10906 | */ | ||
10907 | AdvWriteByteRegister(iop_base, IOPB_TICKLE, | ||
10908 | ADV_TICKLE_NOP); | ||
10309 | } | 10909 | } |
10310 | return ((uchar)max_index); | 10910 | } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { |
10311 | } else { | 10911 | /* |
10312 | return ((uchar)(max_index + 1)); | 10912 | * Notify the RISC a carrier is ready by writing the physical |
10913 | * address of the new carrier stopper to the COMMA register. | ||
10914 | */ | ||
10915 | AdvWriteDWordRegister(iop_base, IOPDW_COMMA, | ||
10916 | le32_to_cpu(new_carrp->carr_pa)); | ||
10313 | } | 10917 | } |
10918 | |||
10919 | return ADV_SUCCESS; | ||
10314 | } | 10920 | } |
10315 | 10921 | ||
10316 | static uchar AscAllocFreeQueue(PortAddr iop_base, uchar free_q_head) | 10922 | /* |
10923 | * Execute a single 'Scsi_Cmnd'. | ||
10924 | */ | ||
10925 | static int asc_execute_scsi_cmnd(struct scsi_cmnd *scp) | ||
10317 | { | 10926 | { |
10318 | ushort q_addr; | 10927 | int ret, err_code; |
10319 | uchar next_qp; | 10928 | struct asc_board *boardp = shost_priv(scp->device->host); |
10320 | uchar q_status; | ||
10321 | 10929 | ||
10322 | q_addr = ASC_QNO_TO_QADDR(free_q_head); | 10930 | ASC_DBG(1, "scp 0x%p\n", scp); |
10323 | q_status = (uchar)AscReadLramByte(iop_base, | ||
10324 | (ushort)(q_addr + | ||
10325 | ASC_SCSIQ_B_STATUS)); | ||
10326 | next_qp = AscReadLramByte(iop_base, (ushort)(q_addr + ASC_SCSIQ_B_FWD)); | ||
10327 | if (((q_status & QS_READY) == 0) && (next_qp != ASC_QLINK_END)) { | ||
10328 | return (next_qp); | ||
10329 | } | ||
10330 | return (ASC_QLINK_END); | ||
10331 | } | ||
10332 | 10931 | ||
10333 | static uchar | 10932 | if (ASC_NARROW_BOARD(boardp)) { |
10334 | AscAllocMultipleFreeQueue(PortAddr iop_base, uchar free_q_head, uchar n_free_q) | 10933 | ASC_DVC_VAR *asc_dvc = &boardp->dvc_var.asc_dvc_var; |
10335 | { | 10934 | struct asc_scsi_q asc_scsi_q; |
10336 | uchar i; | ||
10337 | 10935 | ||
10338 | for (i = 0; i < n_free_q; i++) { | 10936 | /* asc_build_req() can not return ASC_BUSY. */ |
10339 | if ((free_q_head = AscAllocFreeQueue(iop_base, free_q_head)) | 10937 | ret = asc_build_req(boardp, scp, &asc_scsi_q); |
10340 | == ASC_QLINK_END) { | 10938 | if (ret == ASC_ERROR) { |
10341 | return (ASC_QLINK_END); | 10939 | ASC_STATS(scp->device->host, build_error); |
10940 | return ASC_ERROR; | ||
10342 | } | 10941 | } |
10343 | } | ||
10344 | return (free_q_head); | ||
10345 | } | ||
10346 | 10942 | ||
10347 | static int AscHostReqRiscHalt(PortAddr iop_base) | 10943 | ret = AscExeScsiQueue(asc_dvc, &asc_scsi_q); |
10348 | { | 10944 | kfree(asc_scsi_q.sg_head); |
10349 | int count = 0; | 10945 | err_code = asc_dvc->err_code; |
10350 | int sta = 0; | 10946 | } else { |
10351 | uchar saved_stop_code; | 10947 | ADV_DVC_VAR *adv_dvc = &boardp->dvc_var.adv_dvc_var; |
10948 | ADV_SCSI_REQ_Q *adv_scsiqp; | ||
10352 | 10949 | ||
10353 | if (AscIsChipHalted(iop_base)) | 10950 | switch (adv_build_req(boardp, scp, &adv_scsiqp)) { |
10354 | return (1); | 10951 | case ASC_NOERROR: |
10355 | saved_stop_code = AscReadLramByte(iop_base, ASCV_STOP_CODE_B); | 10952 | ASC_DBG(3, "adv_build_req ASC_NOERROR\n"); |
10356 | AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, | ||
10357 | ASC_STOP_HOST_REQ_RISC_HALT | ASC_STOP_REQ_RISC_STOP); | ||
10358 | do { | ||
10359 | if (AscIsChipHalted(iop_base)) { | ||
10360 | sta = 1; | ||
10361 | break; | 10953 | break; |
10954 | case ASC_BUSY: | ||
10955 | ASC_DBG(1, "adv_build_req ASC_BUSY\n"); | ||
10956 | /* | ||
10957 | * The asc_stats fields 'adv_build_noreq' and | ||
10958 | * 'adv_build_nosg' count wide board busy conditions. | ||
10959 | * They are updated in adv_build_req and | ||
10960 | * adv_get_sglist, respectively. | ||
10961 | */ | ||
10962 | return ASC_BUSY; | ||
10963 | case ASC_ERROR: | ||
10964 | default: | ||
10965 | ASC_DBG(1, "adv_build_req ASC_ERROR\n"); | ||
10966 | ASC_STATS(scp->device->host, build_error); | ||
10967 | return ASC_ERROR; | ||
10362 | } | 10968 | } |
10363 | DvcSleepMilliSecond(100); | ||
10364 | } while (count++ < 20); | ||
10365 | AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, saved_stop_code); | ||
10366 | return (sta); | ||
10367 | } | ||
10368 | 10969 | ||
10369 | static int AscStopQueueExe(PortAddr iop_base) | 10970 | ret = AdvExeScsiQueue(adv_dvc, adv_scsiqp); |
10370 | { | 10971 | err_code = adv_dvc->err_code; |
10371 | int count = 0; | 10972 | } |
10372 | 10973 | ||
10373 | if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) { | 10974 | switch (ret) { |
10374 | AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, | 10975 | case ASC_NOERROR: |
10375 | ASC_STOP_REQ_RISC_STOP); | 10976 | ASC_STATS(scp->device->host, exe_noerror); |
10376 | do { | 10977 | /* |
10377 | if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) & | 10978 | * Increment monotonically increasing per device |
10378 | ASC_STOP_ACK_RISC_STOP) { | 10979 | * successful request counter. Wrapping doesn't matter. |
10379 | return (1); | 10980 | */ |
10380 | } | 10981 | boardp->reqcnt[scp->device->id]++; |
10381 | DvcSleepMilliSecond(100); | 10982 | ASC_DBG(1, "ExeScsiQueue() ASC_NOERROR\n"); |
10382 | } while (count++ < 20); | 10983 | break; |
10984 | case ASC_BUSY: | ||
10985 | ASC_STATS(scp->device->host, exe_busy); | ||
10986 | break; | ||
10987 | case ASC_ERROR: | ||
10988 | scmd_printk(KERN_ERR, scp, "ExeScsiQueue() ASC_ERROR, " | ||
10989 | "err_code 0x%x\n", err_code); | ||
10990 | ASC_STATS(scp->device->host, exe_error); | ||
10991 | scp->result = HOST_BYTE(DID_ERROR); | ||
10992 | break; | ||
10993 | default: | ||
10994 | scmd_printk(KERN_ERR, scp, "ExeScsiQueue() unknown, " | ||
10995 | "err_code 0x%x\n", err_code); | ||
10996 | ASC_STATS(scp->device->host, exe_unknown); | ||
10997 | scp->result = HOST_BYTE(DID_ERROR); | ||
10998 | break; | ||
10383 | } | 10999 | } |
10384 | return (0); | ||
10385 | } | ||
10386 | 11000 | ||
10387 | static void DvcDelayMicroSecond(ADV_DVC_VAR *asc_dvc, ushort micro_sec) | 11001 | ASC_DBG(1, "end\n"); |
10388 | { | 11002 | return ret; |
10389 | udelay(micro_sec); | ||
10390 | } | 11003 | } |
10391 | 11004 | ||
10392 | static void DvcDelayNanoSecond(ASC_DVC_VAR *asc_dvc, ASC_DCNT nano_sec) | 11005 | /* |
11006 | * advansys_queuecommand() - interrupt-driven I/O entrypoint. | ||
11007 | * | ||
11008 | * This function always returns 0. Command return status is saved | ||
11009 | * in the 'scp' result field. | ||
11010 | */ | ||
11011 | static int | ||
11012 | advansys_queuecommand(struct scsi_cmnd *scp, void (*done)(struct scsi_cmnd *)) | ||
10393 | { | 11013 | { |
10394 | udelay((nano_sec + 999) / 1000); | 11014 | struct Scsi_Host *shost = scp->device->host; |
10395 | } | 11015 | int asc_res, result = 0; |
10396 | 11016 | ||
10397 | #ifdef CONFIG_ISA | 11017 | ASC_STATS(shost, queuecommand); |
10398 | static ASC_DCNT __init AscGetEisaProductID(PortAddr iop_base) | 11018 | scp->scsi_done = done; |
10399 | { | ||
10400 | PortAddr eisa_iop; | ||
10401 | ushort product_id_high, product_id_low; | ||
10402 | ASC_DCNT product_id; | ||
10403 | |||
10404 | eisa_iop = ASC_GET_EISA_SLOT(iop_base) | ASC_EISA_PID_IOP_MASK; | ||
10405 | product_id_low = inpw(eisa_iop); | ||
10406 | product_id_high = inpw(eisa_iop + 2); | ||
10407 | product_id = ((ASC_DCNT) product_id_high << 16) | | ||
10408 | (ASC_DCNT) product_id_low; | ||
10409 | return (product_id); | ||
10410 | } | ||
10411 | 11019 | ||
10412 | static PortAddr __init AscSearchIOPortAddrEISA(PortAddr iop_base) | 11020 | asc_res = asc_execute_scsi_cmnd(scp); |
10413 | { | ||
10414 | ASC_DCNT eisa_product_id; | ||
10415 | 11021 | ||
10416 | if (iop_base == 0) { | 11022 | switch (asc_res) { |
10417 | iop_base = ASC_EISA_MIN_IOP_ADDR; | 11023 | case ASC_NOERROR: |
10418 | } else { | 11024 | break; |
10419 | if (iop_base == ASC_EISA_MAX_IOP_ADDR) | 11025 | case ASC_BUSY: |
10420 | return (0); | 11026 | result = SCSI_MLQUEUE_HOST_BUSY; |
10421 | if ((iop_base & 0x0050) == 0x0050) { | 11027 | break; |
10422 | iop_base += ASC_EISA_BIG_IOP_GAP; | 11028 | case ASC_ERROR: |
10423 | } else { | 11029 | default: |
10424 | iop_base += ASC_EISA_SMALL_IOP_GAP; | 11030 | asc_scsi_done(scp); |
10425 | } | 11031 | break; |
10426 | } | ||
10427 | while (iop_base <= ASC_EISA_MAX_IOP_ADDR) { | ||
10428 | eisa_product_id = AscGetEisaProductID(iop_base); | ||
10429 | if ((eisa_product_id == ASC_EISA_ID_740) || | ||
10430 | (eisa_product_id == ASC_EISA_ID_750)) { | ||
10431 | if (AscFindSignature(iop_base)) { | ||
10432 | inpw(iop_base + 4); | ||
10433 | return (iop_base); | ||
10434 | } | ||
10435 | } | ||
10436 | if (iop_base == ASC_EISA_MAX_IOP_ADDR) | ||
10437 | return (0); | ||
10438 | if ((iop_base & 0x0050) == 0x0050) { | ||
10439 | iop_base += ASC_EISA_BIG_IOP_GAP; | ||
10440 | } else { | ||
10441 | iop_base += ASC_EISA_SMALL_IOP_GAP; | ||
10442 | } | ||
10443 | } | 11032 | } |
10444 | return (0); | 11033 | |
11034 | return result; | ||
10445 | } | 11035 | } |
10446 | #endif /* CONFIG_ISA */ | ||
10447 | 11036 | ||
10448 | static int AscStartChip(PortAddr iop_base) | 11037 | static ushort __devinit AscGetEisaChipCfg(PortAddr iop_base) |
10449 | { | 11038 | { |
10450 | AscSetChipControl(iop_base, 0); | 11039 | PortAddr eisa_cfg_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) | |
10451 | if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) { | 11040 | (PortAddr) (ASC_EISA_CFG_IOP_MASK); |
10452 | return (0); | 11041 | return inpw(eisa_cfg_iop); |
10453 | } | ||
10454 | return (1); | ||
10455 | } | 11042 | } |
10456 | 11043 | ||
10457 | static int AscStopChip(PortAddr iop_base) | 11044 | /* |
11045 | * Return the BIOS address of the adapter at the specified | ||
11046 | * I/O port and with the specified bus type. | ||
11047 | */ | ||
11048 | static unsigned short __devinit | ||
11049 | AscGetChipBiosAddress(PortAddr iop_base, unsigned short bus_type) | ||
10458 | { | 11050 | { |
10459 | uchar cc_val; | 11051 | unsigned short cfg_lsw; |
11052 | unsigned short bios_addr; | ||
10460 | 11053 | ||
10461 | cc_val = | 11054 | /* |
10462 | AscGetChipControl(iop_base) & | 11055 | * The PCI BIOS is re-located by the motherboard BIOS. Because |
10463 | (~(CC_SINGLE_STEP | CC_TEST | CC_DIAG)); | 11056 | * of this the driver can not determine where a PCI BIOS is |
10464 | AscSetChipControl(iop_base, (uchar)(cc_val | CC_HALT)); | 11057 | * loaded and executes. |
10465 | AscSetChipIH(iop_base, INS_HALT); | 11058 | */ |
10466 | AscSetChipIH(iop_base, INS_RFLAG_WTM); | 11059 | if (bus_type & ASC_IS_PCI) |
10467 | if ((AscGetChipStatus(iop_base) & CSW_HALTED) == 0) { | 11060 | return 0; |
10468 | return (0); | ||
10469 | } | ||
10470 | return (1); | ||
10471 | } | ||
10472 | 11061 | ||
10473 | static int AscIsChipHalted(PortAddr iop_base) | 11062 | if ((bus_type & ASC_IS_EISA) != 0) { |
10474 | { | 11063 | cfg_lsw = AscGetEisaChipCfg(iop_base); |
10475 | if ((AscGetChipStatus(iop_base) & CSW_HALTED) != 0) { | 11064 | cfg_lsw &= 0x000F; |
10476 | if ((AscGetChipControl(iop_base) & CC_HALT) != 0) { | 11065 | bios_addr = ASC_BIOS_MIN_ADDR + cfg_lsw * ASC_BIOS_BANK_SIZE; |
10477 | return (1); | 11066 | return bios_addr; |
10478 | } | ||
10479 | } | 11067 | } |
10480 | return (0); | ||
10481 | } | ||
10482 | 11068 | ||
10483 | static void AscSetChipIH(PortAddr iop_base, ushort ins_code) | 11069 | cfg_lsw = AscGetChipCfgLsw(iop_base); |
10484 | { | 11070 | |
10485 | AscSetBank(iop_base, 1); | 11071 | /* |
10486 | AscWriteChipIH(iop_base, ins_code); | 11072 | * ISA PnP uses the top bit as the 32K BIOS flag |
10487 | AscSetBank(iop_base, 0); | 11073 | */ |
10488 | return; | 11074 | if (bus_type == ASC_IS_ISAPNP) |
11075 | cfg_lsw &= 0x7FFF; | ||
11076 | bios_addr = ASC_BIOS_MIN_ADDR + (cfg_lsw >> 12) * ASC_BIOS_BANK_SIZE; | ||
11077 | return bios_addr; | ||
10489 | } | 11078 | } |
10490 | 11079 | ||
10491 | static void AscAckInterrupt(PortAddr iop_base) | 11080 | static uchar __devinit AscSetChipScsiID(PortAddr iop_base, uchar new_host_id) |
10492 | { | 11081 | { |
10493 | uchar host_flag; | 11082 | ushort cfg_lsw; |
10494 | uchar risc_flag; | ||
10495 | ushort loop; | ||
10496 | 11083 | ||
10497 | loop = 0; | 11084 | if (AscGetChipScsiID(iop_base) == new_host_id) { |
10498 | do { | 11085 | return (new_host_id); |
10499 | risc_flag = AscReadLramByte(iop_base, ASCV_RISC_FLAG_B); | ||
10500 | if (loop++ > 0x7FFF) { | ||
10501 | break; | ||
10502 | } | ||
10503 | } while ((risc_flag & ASC_RISC_FLAG_GEN_INT) != 0); | ||
10504 | host_flag = | ||
10505 | AscReadLramByte(iop_base, | ||
10506 | ASCV_HOST_FLAG_B) & (~ASC_HOST_FLAG_ACK_INT); | ||
10507 | AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, | ||
10508 | (uchar)(host_flag | ASC_HOST_FLAG_ACK_INT)); | ||
10509 | AscSetChipStatus(iop_base, CIW_INT_ACK); | ||
10510 | loop = 0; | ||
10511 | while (AscGetChipStatus(iop_base) & CSW_INT_PENDING) { | ||
10512 | AscSetChipStatus(iop_base, CIW_INT_ACK); | ||
10513 | if (loop++ > 3) { | ||
10514 | break; | ||
10515 | } | ||
10516 | } | 11086 | } |
10517 | AscWriteLramByte(iop_base, ASCV_HOST_FLAG_B, host_flag); | 11087 | cfg_lsw = AscGetChipCfgLsw(iop_base); |
10518 | return; | 11088 | cfg_lsw &= 0xF8FF; |
11089 | cfg_lsw |= (ushort)((new_host_id & ASC_MAX_TID) << 8); | ||
11090 | AscSetChipCfgLsw(iop_base, cfg_lsw); | ||
11091 | return (AscGetChipScsiID(iop_base)); | ||
10519 | } | 11092 | } |
10520 | 11093 | ||
10521 | static void AscDisableInterrupt(PortAddr iop_base) | 11094 | static unsigned char __devinit AscGetChipScsiCtrl(PortAddr iop_base) |
10522 | { | 11095 | { |
10523 | ushort cfg; | 11096 | unsigned char sc; |
10524 | 11097 | ||
10525 | cfg = AscGetChipCfgLsw(iop_base); | 11098 | AscSetBank(iop_base, 1); |
10526 | AscSetChipCfgLsw(iop_base, cfg & (~ASC_CFG0_HOST_INT_ON)); | 11099 | sc = inp(iop_base + IOP_REG_SC); |
10527 | return; | 11100 | AscSetBank(iop_base, 0); |
11101 | return sc; | ||
10528 | } | 11102 | } |
10529 | 11103 | ||
10530 | static void AscEnableInterrupt(PortAddr iop_base) | 11104 | static unsigned char __devinit |
11105 | AscGetChipVersion(PortAddr iop_base, unsigned short bus_type) | ||
10531 | { | 11106 | { |
10532 | ushort cfg; | 11107 | if (bus_type & ASC_IS_EISA) { |
10533 | 11108 | PortAddr eisa_iop; | |
10534 | cfg = AscGetChipCfgLsw(iop_base); | 11109 | unsigned char revision; |
10535 | AscSetChipCfgLsw(iop_base, cfg | ASC_CFG0_HOST_INT_ON); | 11110 | eisa_iop = (PortAddr) ASC_GET_EISA_SLOT(iop_base) | |
10536 | return; | 11111 | (PortAddr) ASC_EISA_REV_IOP_MASK; |
11112 | revision = inp(eisa_iop); | ||
11113 | return ASC_CHIP_MIN_VER_EISA - 1 + revision; | ||
11114 | } | ||
11115 | return AscGetChipVerNo(iop_base); | ||
10537 | } | 11116 | } |
10538 | 11117 | ||
10539 | static void AscSetBank(PortAddr iop_base, uchar bank) | 11118 | #ifdef CONFIG_ISA |
11119 | static void __devinit AscEnableIsaDma(uchar dma_channel) | ||
10540 | { | 11120 | { |
10541 | uchar val; | 11121 | if (dma_channel < 4) { |
10542 | 11122 | outp(0x000B, (ushort)(0xC0 | dma_channel)); | |
10543 | val = AscGetChipControl(iop_base) & | 11123 | outp(0x000A, dma_channel); |
10544 | (~ | 11124 | } else if (dma_channel < 8) { |
10545 | (CC_SINGLE_STEP | CC_TEST | CC_DIAG | CC_SCSI_RESET | | 11125 | outp(0x00D6, (ushort)(0xC0 | (dma_channel - 4))); |
10546 | CC_CHIP_RESET)); | 11126 | outp(0x00D4, (ushort)(dma_channel - 4)); |
10547 | if (bank == 1) { | ||
10548 | val |= CC_BANK_ONE; | ||
10549 | } else if (bank == 2) { | ||
10550 | val |= CC_DIAG | CC_BANK_ONE; | ||
10551 | } else { | ||
10552 | val &= ~CC_BANK_ONE; | ||
10553 | } | 11127 | } |
10554 | AscSetChipControl(iop_base, val); | ||
10555 | return; | ||
10556 | } | 11128 | } |
11129 | #endif /* CONFIG_ISA */ | ||
10557 | 11130 | ||
10558 | static int AscResetChipAndScsiBus(ASC_DVC_VAR *asc_dvc) | 11131 | static int AscStopQueueExe(PortAddr iop_base) |
10559 | { | 11132 | { |
10560 | PortAddr iop_base; | 11133 | int count = 0; |
10561 | int i = 10; | ||
10562 | 11134 | ||
10563 | iop_base = asc_dvc->iop_base; | 11135 | if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) == 0) { |
10564 | while ((AscGetChipStatus(iop_base) & CSW_SCSI_RESET_ACTIVE) | 11136 | AscWriteLramByte(iop_base, ASCV_STOP_CODE_B, |
10565 | && (i-- > 0)) { | 11137 | ASC_STOP_REQ_RISC_STOP); |
10566 | DvcSleepMilliSecond(100); | 11138 | do { |
11139 | if (AscReadLramByte(iop_base, ASCV_STOP_CODE_B) & | ||
11140 | ASC_STOP_ACK_RISC_STOP) { | ||
11141 | return (1); | ||
11142 | } | ||
11143 | mdelay(100); | ||
11144 | } while (count++ < 20); | ||
10567 | } | 11145 | } |
10568 | AscStopChip(iop_base); | 11146 | return (0); |
10569 | AscSetChipControl(iop_base, CC_CHIP_RESET | CC_SCSI_RESET | CC_HALT); | ||
10570 | DvcDelayNanoSecond(asc_dvc, 60000); | ||
10571 | AscSetChipIH(iop_base, INS_RFLAG_WTM); | ||
10572 | AscSetChipIH(iop_base, INS_HALT); | ||
10573 | AscSetChipControl(iop_base, CC_CHIP_RESET | CC_HALT); | ||
10574 | AscSetChipControl(iop_base, CC_HALT); | ||
10575 | DvcSleepMilliSecond(200); | ||
10576 | AscSetChipStatus(iop_base, CIW_CLR_SCSI_RESET_INT); | ||
10577 | AscSetChipStatus(iop_base, 0); | ||
10578 | return (AscIsChipHalted(iop_base)); | ||
10579 | } | 11147 | } |
10580 | 11148 | ||
10581 | static ASC_DCNT __init AscGetMaxDmaCount(ushort bus_type) | 11149 | static ASC_DCNT __devinit AscGetMaxDmaCount(ushort bus_type) |
10582 | { | 11150 | { |
10583 | if (bus_type & ASC_IS_ISA) | 11151 | if (bus_type & ASC_IS_ISA) |
10584 | return (ASC_MAX_ISA_DMA_COUNT); | 11152 | return ASC_MAX_ISA_DMA_COUNT; |
10585 | else if (bus_type & (ASC_IS_EISA | ASC_IS_VL)) | 11153 | else if (bus_type & (ASC_IS_EISA | ASC_IS_VL)) |
10586 | return (ASC_MAX_VL_DMA_COUNT); | 11154 | return ASC_MAX_VL_DMA_COUNT; |
10587 | return (ASC_MAX_PCI_DMA_COUNT); | 11155 | return ASC_MAX_PCI_DMA_COUNT; |
10588 | } | 11156 | } |
10589 | 11157 | ||
10590 | #ifdef CONFIG_ISA | 11158 | #ifdef CONFIG_ISA |
10591 | static ushort __init AscGetIsaDmaChannel(PortAddr iop_base) | 11159 | static ushort __devinit AscGetIsaDmaChannel(PortAddr iop_base) |
10592 | { | 11160 | { |
10593 | ushort channel; | 11161 | ushort channel; |
10594 | 11162 | ||
@@ -10600,7 +11168,7 @@ static ushort __init AscGetIsaDmaChannel(PortAddr iop_base) | |||
10600 | return (channel + 4); | 11168 | return (channel + 4); |
10601 | } | 11169 | } |
10602 | 11170 | ||
10603 | static ushort __init AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel) | 11171 | static ushort __devinit AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel) |
10604 | { | 11172 | { |
10605 | ushort cfg_lsw; | 11173 | ushort cfg_lsw; |
10606 | uchar value; | 11174 | uchar value; |
@@ -10615,19 +11183,10 @@ static ushort __init AscSetIsaDmaChannel(PortAddr iop_base, ushort dma_channel) | |||
10615 | AscSetChipCfgLsw(iop_base, cfg_lsw); | 11183 | AscSetChipCfgLsw(iop_base, cfg_lsw); |
10616 | return (AscGetIsaDmaChannel(iop_base)); | 11184 | return (AscGetIsaDmaChannel(iop_base)); |
10617 | } | 11185 | } |
10618 | return (0); | 11186 | return 0; |
10619 | } | ||
10620 | |||
10621 | static uchar __init AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value) | ||
10622 | { | ||
10623 | speed_value &= 0x07; | ||
10624 | AscSetBank(iop_base, 1); | ||
10625 | AscWriteChipDmaSpeed(iop_base, speed_value); | ||
10626 | AscSetBank(iop_base, 0); | ||
10627 | return (AscGetIsaDmaSpeed(iop_base)); | ||
10628 | } | 11187 | } |
10629 | 11188 | ||
10630 | static uchar __init AscGetIsaDmaSpeed(PortAddr iop_base) | 11189 | static uchar __devinit AscGetIsaDmaSpeed(PortAddr iop_base) |
10631 | { | 11190 | { |
10632 | uchar speed_value; | 11191 | uchar speed_value; |
10633 | 11192 | ||
@@ -10635,223 +11194,20 @@ static uchar __init AscGetIsaDmaSpeed(PortAddr iop_base) | |||
10635 | speed_value = AscReadChipDmaSpeed(iop_base); | 11194 | speed_value = AscReadChipDmaSpeed(iop_base); |
10636 | speed_value &= 0x07; | 11195 | speed_value &= 0x07; |
10637 | AscSetBank(iop_base, 0); | 11196 | AscSetBank(iop_base, 0); |
10638 | return (speed_value); | 11197 | return speed_value; |
10639 | } | 11198 | } |
10640 | #endif /* CONFIG_ISA */ | ||
10641 | 11199 | ||
10642 | static ushort __init | 11200 | static uchar __devinit AscSetIsaDmaSpeed(PortAddr iop_base, uchar speed_value) |
10643 | AscReadPCIConfigWord(ASC_DVC_VAR *asc_dvc, ushort pci_config_offset) | ||
10644 | { | 11201 | { |
10645 | uchar lsb, msb; | 11202 | speed_value &= 0x07; |
10646 | 11203 | AscSetBank(iop_base, 1); | |
10647 | lsb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset); | 11204 | AscWriteChipDmaSpeed(iop_base, speed_value); |
10648 | msb = DvcReadPCIConfigByte(asc_dvc, pci_config_offset + 1); | 11205 | AscSetBank(iop_base, 0); |
10649 | return ((ushort)((msb << 8) | lsb)); | 11206 | return AscGetIsaDmaSpeed(iop_base); |
10650 | } | ||
10651 | |||
10652 | static ushort __init AscInitGetConfig(ASC_DVC_VAR *asc_dvc) | ||
10653 | { | ||
10654 | ushort warn_code; | ||
10655 | PortAddr iop_base; | ||
10656 | ushort PCIDeviceID; | ||
10657 | ushort PCIVendorID; | ||
10658 | uchar PCIRevisionID; | ||
10659 | uchar prevCmdRegBits; | ||
10660 | |||
10661 | warn_code = 0; | ||
10662 | iop_base = asc_dvc->iop_base; | ||
10663 | asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG; | ||
10664 | if (asc_dvc->err_code != 0) { | ||
10665 | return (UW_ERR); | ||
10666 | } | ||
10667 | if (asc_dvc->bus_type == ASC_IS_PCI) { | ||
10668 | PCIVendorID = AscReadPCIConfigWord(asc_dvc, | ||
10669 | AscPCIConfigVendorIDRegister); | ||
10670 | |||
10671 | PCIDeviceID = AscReadPCIConfigWord(asc_dvc, | ||
10672 | AscPCIConfigDeviceIDRegister); | ||
10673 | |||
10674 | PCIRevisionID = DvcReadPCIConfigByte(asc_dvc, | ||
10675 | AscPCIConfigRevisionIDRegister); | ||
10676 | |||
10677 | if (PCIVendorID != PCI_VENDOR_ID_ASP) { | ||
10678 | warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; | ||
10679 | } | ||
10680 | prevCmdRegBits = DvcReadPCIConfigByte(asc_dvc, | ||
10681 | AscPCIConfigCommandRegister); | ||
10682 | |||
10683 | if ((prevCmdRegBits & AscPCICmdRegBits_IOMemBusMaster) != | ||
10684 | AscPCICmdRegBits_IOMemBusMaster) { | ||
10685 | DvcWritePCIConfigByte(asc_dvc, | ||
10686 | AscPCIConfigCommandRegister, | ||
10687 | (prevCmdRegBits | | ||
10688 | AscPCICmdRegBits_IOMemBusMaster)); | ||
10689 | |||
10690 | if ((DvcReadPCIConfigByte(asc_dvc, | ||
10691 | AscPCIConfigCommandRegister) | ||
10692 | & AscPCICmdRegBits_IOMemBusMaster) | ||
10693 | != AscPCICmdRegBits_IOMemBusMaster) { | ||
10694 | warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; | ||
10695 | } | ||
10696 | } | ||
10697 | if ((PCIDeviceID == PCI_DEVICE_ID_ASP_1200A) || | ||
10698 | (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940)) { | ||
10699 | DvcWritePCIConfigByte(asc_dvc, | ||
10700 | AscPCIConfigLatencyTimer, 0x00); | ||
10701 | if (DvcReadPCIConfigByte | ||
10702 | (asc_dvc, AscPCIConfigLatencyTimer) | ||
10703 | != 0x00) { | ||
10704 | warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; | ||
10705 | } | ||
10706 | } else if (PCIDeviceID == PCI_DEVICE_ID_ASP_ABP940U) { | ||
10707 | if (DvcReadPCIConfigByte(asc_dvc, | ||
10708 | AscPCIConfigLatencyTimer) < | ||
10709 | 0x20) { | ||
10710 | DvcWritePCIConfigByte(asc_dvc, | ||
10711 | AscPCIConfigLatencyTimer, | ||
10712 | 0x20); | ||
10713 | |||
10714 | if (DvcReadPCIConfigByte(asc_dvc, | ||
10715 | AscPCIConfigLatencyTimer) | ||
10716 | < 0x20) { | ||
10717 | warn_code |= | ||
10718 | ASC_WARN_SET_PCI_CONFIG_SPACE; | ||
10719 | } | ||
10720 | } | ||
10721 | } | ||
10722 | } | ||
10723 | |||
10724 | if (AscFindSignature(iop_base)) { | ||
10725 | warn_code |= AscInitAscDvcVar(asc_dvc); | ||
10726 | warn_code |= AscInitFromEEP(asc_dvc); | ||
10727 | asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG; | ||
10728 | if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) { | ||
10729 | asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT; | ||
10730 | } | ||
10731 | } else { | ||
10732 | asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; | ||
10733 | } | ||
10734 | return (warn_code); | ||
10735 | } | ||
10736 | |||
10737 | static ushort __init AscInitSetConfig(ASC_DVC_VAR *asc_dvc) | ||
10738 | { | ||
10739 | ushort warn_code = 0; | ||
10740 | |||
10741 | asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG; | ||
10742 | if (asc_dvc->err_code != 0) | ||
10743 | return (UW_ERR); | ||
10744 | if (AscFindSignature(asc_dvc->iop_base)) { | ||
10745 | warn_code |= AscInitFromAscDvcVar(asc_dvc); | ||
10746 | asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG; | ||
10747 | } else { | ||
10748 | asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; | ||
10749 | } | ||
10750 | return (warn_code); | ||
10751 | } | 11207 | } |
10752 | |||
10753 | static ushort __init AscInitFromAscDvcVar(ASC_DVC_VAR *asc_dvc) | ||
10754 | { | ||
10755 | PortAddr iop_base; | ||
10756 | ushort cfg_msw; | ||
10757 | ushort warn_code; | ||
10758 | ushort pci_device_id = 0; | ||
10759 | |||
10760 | iop_base = asc_dvc->iop_base; | ||
10761 | #ifdef CONFIG_PCI | ||
10762 | if (asc_dvc->cfg->dev) | ||
10763 | pci_device_id = to_pci_dev(asc_dvc->cfg->dev)->device; | ||
10764 | #endif | ||
10765 | warn_code = 0; | ||
10766 | cfg_msw = AscGetChipCfgMsw(iop_base); | ||
10767 | if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) { | ||
10768 | cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK)); | ||
10769 | warn_code |= ASC_WARN_CFG_MSW_RECOVER; | ||
10770 | AscSetChipCfgMsw(iop_base, cfg_msw); | ||
10771 | } | ||
10772 | if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) != | ||
10773 | asc_dvc->cfg->cmd_qng_enabled) { | ||
10774 | asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled; | ||
10775 | warn_code |= ASC_WARN_CMD_QNG_CONFLICT; | ||
10776 | } | ||
10777 | if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) { | ||
10778 | warn_code |= ASC_WARN_AUTO_CONFIG; | ||
10779 | } | ||
10780 | if ((asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL)) != 0) { | ||
10781 | if (AscSetChipIRQ(iop_base, asc_dvc->irq_no, asc_dvc->bus_type) | ||
10782 | != asc_dvc->irq_no) { | ||
10783 | asc_dvc->err_code |= ASC_IERR_SET_IRQ_NO; | ||
10784 | } | ||
10785 | } | ||
10786 | if (asc_dvc->bus_type & ASC_IS_PCI) { | ||
10787 | cfg_msw &= 0xFFC0; | ||
10788 | AscSetChipCfgMsw(iop_base, cfg_msw); | ||
10789 | if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) { | ||
10790 | } else { | ||
10791 | if ((pci_device_id == PCI_DEVICE_ID_ASP_1200A) || | ||
10792 | (pci_device_id == PCI_DEVICE_ID_ASP_ABP940)) { | ||
10793 | asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB; | ||
10794 | asc_dvc->bug_fix_cntl |= | ||
10795 | ASC_BUG_FIX_ASYN_USE_SYN; | ||
10796 | } | ||
10797 | } | ||
10798 | } else if (asc_dvc->bus_type == ASC_IS_ISAPNP) { | ||
10799 | if (AscGetChipVersion(iop_base, asc_dvc->bus_type) | ||
10800 | == ASC_CHIP_VER_ASYN_BUG) { | ||
10801 | asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN; | ||
10802 | } | ||
10803 | } | ||
10804 | if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) != | ||
10805 | asc_dvc->cfg->chip_scsi_id) { | ||
10806 | asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID; | ||
10807 | } | ||
10808 | #ifdef CONFIG_ISA | ||
10809 | if (asc_dvc->bus_type & ASC_IS_ISA) { | ||
10810 | AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel); | ||
10811 | AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed); | ||
10812 | } | ||
10813 | #endif /* CONFIG_ISA */ | 11208 | #endif /* CONFIG_ISA */ |
10814 | return (warn_code); | ||
10815 | } | ||
10816 | |||
10817 | static ushort AscInitAsc1000Driver(ASC_DVC_VAR *asc_dvc) | ||
10818 | { | ||
10819 | ushort warn_code; | ||
10820 | PortAddr iop_base; | ||
10821 | |||
10822 | iop_base = asc_dvc->iop_base; | ||
10823 | warn_code = 0; | ||
10824 | if ((asc_dvc->dvc_cntl & ASC_CNTL_RESET_SCSI) && | ||
10825 | !(asc_dvc->init_state & ASC_INIT_RESET_SCSI_DONE)) { | ||
10826 | AscResetChipAndScsiBus(asc_dvc); | ||
10827 | DvcSleepMilliSecond((ASC_DCNT) | ||
10828 | ((ushort)asc_dvc->scsi_reset_wait * 1000)); | ||
10829 | } | ||
10830 | asc_dvc->init_state |= ASC_INIT_STATE_BEG_LOAD_MC; | ||
10831 | if (asc_dvc->err_code != 0) | ||
10832 | return (UW_ERR); | ||
10833 | if (!AscFindSignature(asc_dvc->iop_base)) { | ||
10834 | asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; | ||
10835 | return (warn_code); | ||
10836 | } | ||
10837 | AscDisableInterrupt(iop_base); | ||
10838 | warn_code |= AscInitLram(asc_dvc); | ||
10839 | if (asc_dvc->err_code != 0) | ||
10840 | return (UW_ERR); | ||
10841 | ASC_DBG1(1, "AscInitAsc1000Driver: _asc_mcode_chksum 0x%lx\n", | ||
10842 | (ulong)_asc_mcode_chksum); | ||
10843 | if (AscLoadMicroCode(iop_base, 0, _asc_mcode_buf, | ||
10844 | _asc_mcode_size) != _asc_mcode_chksum) { | ||
10845 | asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; | ||
10846 | return (warn_code); | ||
10847 | } | ||
10848 | warn_code |= AscInitMicroCodeVar(asc_dvc); | ||
10849 | asc_dvc->init_state |= ASC_INIT_STATE_END_LOAD_MC; | ||
10850 | AscEnableInterrupt(iop_base); | ||
10851 | return (warn_code); | ||
10852 | } | ||
10853 | 11209 | ||
10854 | static ushort __init AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc) | 11210 | static ushort __devinit AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc) |
10855 | { | 11211 | { |
10856 | int i; | 11212 | int i; |
10857 | PortAddr iop_base; | 11213 | PortAddr iop_base; |
@@ -10882,7 +11238,7 @@ static ushort __init AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc) | |||
10882 | asc_dvc->queue_full_or_busy = 0; | 11238 | asc_dvc->queue_full_or_busy = 0; |
10883 | asc_dvc->redo_scam = 0; | 11239 | asc_dvc->redo_scam = 0; |
10884 | asc_dvc->res2 = 0; | 11240 | asc_dvc->res2 = 0; |
10885 | asc_dvc->host_init_sdtr_index = 0; | 11241 | asc_dvc->min_sdtr_index = 0; |
10886 | asc_dvc->cfg->can_tagged_qng = 0; | 11242 | asc_dvc->cfg->can_tagged_qng = 0; |
10887 | asc_dvc->cfg->cmd_qng_enabled = 0; | 11243 | asc_dvc->cfg->cmd_qng_enabled = 0; |
10888 | asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL; | 11244 | asc_dvc->dvc_cntl = ASC_DEF_DVC_CNTL; |
@@ -10894,39 +11250,14 @@ static ushort __init AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc) | |||
10894 | asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET; | 11250 | asc_dvc->cfg->sdtr_enable = ASC_SCSI_WIDTH_BIT_SET; |
10895 | asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET; | 11251 | asc_dvc->cfg->disc_enable = ASC_SCSI_WIDTH_BIT_SET; |
10896 | asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID; | 11252 | asc_dvc->cfg->chip_scsi_id = ASC_DEF_CHIP_SCSI_ID; |
10897 | asc_dvc->cfg->lib_serial_no = ASC_LIB_SERIAL_NUMBER; | ||
10898 | asc_dvc->cfg->lib_version = (ASC_LIB_VERSION_MAJOR << 8) | | ||
10899 | ASC_LIB_VERSION_MINOR; | ||
10900 | chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type); | 11253 | chip_version = AscGetChipVersion(iop_base, asc_dvc->bus_type); |
10901 | asc_dvc->cfg->chip_version = chip_version; | 11254 | asc_dvc->cfg->chip_version = chip_version; |
10902 | asc_dvc->sdtr_period_tbl[0] = SYN_XFER_NS_0; | 11255 | asc_dvc->sdtr_period_tbl = asc_syn_xfer_period; |
10903 | asc_dvc->sdtr_period_tbl[1] = SYN_XFER_NS_1; | ||
10904 | asc_dvc->sdtr_period_tbl[2] = SYN_XFER_NS_2; | ||
10905 | asc_dvc->sdtr_period_tbl[3] = SYN_XFER_NS_3; | ||
10906 | asc_dvc->sdtr_period_tbl[4] = SYN_XFER_NS_4; | ||
10907 | asc_dvc->sdtr_period_tbl[5] = SYN_XFER_NS_5; | ||
10908 | asc_dvc->sdtr_period_tbl[6] = SYN_XFER_NS_6; | ||
10909 | asc_dvc->sdtr_period_tbl[7] = SYN_XFER_NS_7; | ||
10910 | asc_dvc->max_sdtr_index = 7; | 11256 | asc_dvc->max_sdtr_index = 7; |
10911 | if ((asc_dvc->bus_type & ASC_IS_PCI) && | 11257 | if ((asc_dvc->bus_type & ASC_IS_PCI) && |
10912 | (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) { | 11258 | (chip_version >= ASC_CHIP_VER_PCI_ULTRA_3150)) { |
10913 | asc_dvc->bus_type = ASC_IS_PCI_ULTRA; | 11259 | asc_dvc->bus_type = ASC_IS_PCI_ULTRA; |
10914 | asc_dvc->sdtr_period_tbl[0] = SYN_ULTRA_XFER_NS_0; | 11260 | asc_dvc->sdtr_period_tbl = asc_syn_ultra_xfer_period; |
10915 | asc_dvc->sdtr_period_tbl[1] = SYN_ULTRA_XFER_NS_1; | ||
10916 | asc_dvc->sdtr_period_tbl[2] = SYN_ULTRA_XFER_NS_2; | ||
10917 | asc_dvc->sdtr_period_tbl[3] = SYN_ULTRA_XFER_NS_3; | ||
10918 | asc_dvc->sdtr_period_tbl[4] = SYN_ULTRA_XFER_NS_4; | ||
10919 | asc_dvc->sdtr_period_tbl[5] = SYN_ULTRA_XFER_NS_5; | ||
10920 | asc_dvc->sdtr_period_tbl[6] = SYN_ULTRA_XFER_NS_6; | ||
10921 | asc_dvc->sdtr_period_tbl[7] = SYN_ULTRA_XFER_NS_7; | ||
10922 | asc_dvc->sdtr_period_tbl[8] = SYN_ULTRA_XFER_NS_8; | ||
10923 | asc_dvc->sdtr_period_tbl[9] = SYN_ULTRA_XFER_NS_9; | ||
10924 | asc_dvc->sdtr_period_tbl[10] = SYN_ULTRA_XFER_NS_10; | ||
10925 | asc_dvc->sdtr_period_tbl[11] = SYN_ULTRA_XFER_NS_11; | ||
10926 | asc_dvc->sdtr_period_tbl[12] = SYN_ULTRA_XFER_NS_12; | ||
10927 | asc_dvc->sdtr_period_tbl[13] = SYN_ULTRA_XFER_NS_13; | ||
10928 | asc_dvc->sdtr_period_tbl[14] = SYN_ULTRA_XFER_NS_14; | ||
10929 | asc_dvc->sdtr_period_tbl[15] = SYN_ULTRA_XFER_NS_15; | ||
10930 | asc_dvc->max_sdtr_index = 15; | 11261 | asc_dvc->max_sdtr_index = 15; |
10931 | if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) { | 11262 | if (chip_version == ASC_CHIP_VER_PCI_ULTRA_3150) { |
10932 | AscSetExtraControl(iop_base, | 11263 | AscSetExtraControl(iop_base, |
@@ -10943,12 +11274,12 @@ static ushort __init AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc) | |||
10943 | } | 11274 | } |
10944 | 11275 | ||
10945 | asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED; | 11276 | asc_dvc->cfg->isa_dma_speed = ASC_DEF_ISA_DMA_SPEED; |
10946 | if (AscGetChipBusType(iop_base) == ASC_IS_ISAPNP) { | ||
10947 | AscSetChipIFC(iop_base, IFC_INIT_DEFAULT); | ||
10948 | asc_dvc->bus_type = ASC_IS_ISAPNP; | ||
10949 | } | ||
10950 | #ifdef CONFIG_ISA | 11277 | #ifdef CONFIG_ISA |
10951 | if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) { | 11278 | if ((asc_dvc->bus_type & ASC_IS_ISA) != 0) { |
11279 | if (chip_version >= ASC_CHIP_MIN_VER_ISA_PNP) { | ||
11280 | AscSetChipIFC(iop_base, IFC_INIT_DEFAULT); | ||
11281 | asc_dvc->bus_type = ASC_IS_ISAPNP; | ||
11282 | } | ||
10952 | asc_dvc->cfg->isa_dma_channel = | 11283 | asc_dvc->cfg->isa_dma_channel = |
10953 | (uchar)AscGetIsaDmaChannel(iop_base); | 11284 | (uchar)AscGetIsaDmaChannel(iop_base); |
10954 | } | 11285 | } |
@@ -10960,231 +11291,92 @@ static ushort __init AscInitAscDvcVar(ASC_DVC_VAR *asc_dvc) | |||
10960 | asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L; | 11291 | asc_dvc->scsiq_busy_tail[i] = (ASC_SCSI_Q *)0L; |
10961 | asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG; | 11292 | asc_dvc->cfg->max_tag_qng[i] = ASC_MAX_INRAM_TAG_QNG; |
10962 | } | 11293 | } |
10963 | return (warn_code); | 11294 | return warn_code; |
10964 | } | 11295 | } |
10965 | 11296 | ||
10966 | static ushort __init AscInitFromEEP(ASC_DVC_VAR *asc_dvc) | 11297 | static int __devinit AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg) |
10967 | { | 11298 | { |
10968 | ASCEEP_CONFIG eep_config_buf; | 11299 | int retry; |
10969 | ASCEEP_CONFIG *eep_config; | ||
10970 | PortAddr iop_base; | ||
10971 | ushort chksum; | ||
10972 | ushort warn_code; | ||
10973 | ushort cfg_msw, cfg_lsw; | ||
10974 | int i; | ||
10975 | int write_eep = 0; | ||
10976 | |||
10977 | iop_base = asc_dvc->iop_base; | ||
10978 | warn_code = 0; | ||
10979 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE); | ||
10980 | AscStopQueueExe(iop_base); | ||
10981 | if ((AscStopChip(iop_base) == FALSE) || | ||
10982 | (AscGetChipScsiCtrl(iop_base) != 0)) { | ||
10983 | asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE; | ||
10984 | AscResetChipAndScsiBus(asc_dvc); | ||
10985 | DvcSleepMilliSecond((ASC_DCNT) | ||
10986 | ((ushort)asc_dvc->scsi_reset_wait * 1000)); | ||
10987 | } | ||
10988 | if (AscIsChipHalted(iop_base) == FALSE) { | ||
10989 | asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP; | ||
10990 | return (warn_code); | ||
10991 | } | ||
10992 | AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR); | ||
10993 | if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) { | ||
10994 | asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR; | ||
10995 | return (warn_code); | ||
10996 | } | ||
10997 | eep_config = (ASCEEP_CONFIG *)&eep_config_buf; | ||
10998 | cfg_msw = AscGetChipCfgMsw(iop_base); | ||
10999 | cfg_lsw = AscGetChipCfgLsw(iop_base); | ||
11000 | if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) { | ||
11001 | cfg_msw &= (~(ASC_CFG_MSW_CLR_MASK)); | ||
11002 | warn_code |= ASC_WARN_CFG_MSW_RECOVER; | ||
11003 | AscSetChipCfgMsw(iop_base, cfg_msw); | ||
11004 | } | ||
11005 | chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type); | ||
11006 | ASC_DBG1(1, "AscInitFromEEP: chksum 0x%x\n", chksum); | ||
11007 | if (chksum == 0) { | ||
11008 | chksum = 0xaa55; | ||
11009 | } | ||
11010 | if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) { | ||
11011 | warn_code |= ASC_WARN_AUTO_CONFIG; | ||
11012 | if (asc_dvc->cfg->chip_version == 3) { | ||
11013 | if (eep_config->cfg_lsw != cfg_lsw) { | ||
11014 | warn_code |= ASC_WARN_EEPROM_RECOVER; | ||
11015 | eep_config->cfg_lsw = | ||
11016 | AscGetChipCfgLsw(iop_base); | ||
11017 | } | ||
11018 | if (eep_config->cfg_msw != cfg_msw) { | ||
11019 | warn_code |= ASC_WARN_EEPROM_RECOVER; | ||
11020 | eep_config->cfg_msw = | ||
11021 | AscGetChipCfgMsw(iop_base); | ||
11022 | } | ||
11023 | } | ||
11024 | } | ||
11025 | eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK; | ||
11026 | eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON; | ||
11027 | ASC_DBG1(1, "AscInitFromEEP: eep_config->chksum 0x%x\n", | ||
11028 | eep_config->chksum); | ||
11029 | if (chksum != eep_config->chksum) { | ||
11030 | if (AscGetChipVersion(iop_base, asc_dvc->bus_type) == | ||
11031 | ASC_CHIP_VER_PCI_ULTRA_3050) { | ||
11032 | ASC_DBG(1, | ||
11033 | "AscInitFromEEP: chksum error ignored; EEPROM-less board\n"); | ||
11034 | eep_config->init_sdtr = 0xFF; | ||
11035 | eep_config->disc_enable = 0xFF; | ||
11036 | eep_config->start_motor = 0xFF; | ||
11037 | eep_config->use_cmd_qng = 0; | ||
11038 | eep_config->max_total_qng = 0xF0; | ||
11039 | eep_config->max_tag_qng = 0x20; | ||
11040 | eep_config->cntl = 0xBFFF; | ||
11041 | ASC_EEP_SET_CHIP_ID(eep_config, 7); | ||
11042 | eep_config->no_scam = 0; | ||
11043 | eep_config->adapter_info[0] = 0; | ||
11044 | eep_config->adapter_info[1] = 0; | ||
11045 | eep_config->adapter_info[2] = 0; | ||
11046 | eep_config->adapter_info[3] = 0; | ||
11047 | eep_config->adapter_info[4] = 0; | ||
11048 | /* Indicate EEPROM-less board. */ | ||
11049 | eep_config->adapter_info[5] = 0xBB; | ||
11050 | } else { | ||
11051 | ASC_PRINT | ||
11052 | ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n"); | ||
11053 | write_eep = 1; | ||
11054 | warn_code |= ASC_WARN_EEPROM_CHKSUM; | ||
11055 | } | ||
11056 | } | ||
11057 | asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr; | ||
11058 | asc_dvc->cfg->disc_enable = eep_config->disc_enable; | ||
11059 | asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng; | ||
11060 | asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config); | ||
11061 | asc_dvc->start_motor = eep_config->start_motor; | ||
11062 | asc_dvc->dvc_cntl = eep_config->cntl; | ||
11063 | asc_dvc->no_scam = eep_config->no_scam; | ||
11064 | asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0]; | ||
11065 | asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1]; | ||
11066 | asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2]; | ||
11067 | asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3]; | ||
11068 | asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4]; | ||
11069 | asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5]; | ||
11070 | if (!AscTestExternalLram(asc_dvc)) { | ||
11071 | if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == | ||
11072 | ASC_IS_PCI_ULTRA)) { | ||
11073 | eep_config->max_total_qng = | ||
11074 | ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG; | ||
11075 | eep_config->max_tag_qng = | ||
11076 | ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG; | ||
11077 | } else { | ||
11078 | eep_config->cfg_msw |= 0x0800; | ||
11079 | cfg_msw |= 0x0800; | ||
11080 | AscSetChipCfgMsw(iop_base, cfg_msw); | ||
11081 | eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG; | ||
11082 | eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG; | ||
11083 | } | ||
11084 | } else { | ||
11085 | } | ||
11086 | if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) { | ||
11087 | eep_config->max_total_qng = ASC_MIN_TOTAL_QNG; | ||
11088 | } | ||
11089 | if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) { | ||
11090 | eep_config->max_total_qng = ASC_MAX_TOTAL_QNG; | ||
11091 | } | ||
11092 | if (eep_config->max_tag_qng > eep_config->max_total_qng) { | ||
11093 | eep_config->max_tag_qng = eep_config->max_total_qng; | ||
11094 | } | ||
11095 | if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) { | ||
11096 | eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC; | ||
11097 | } | ||
11098 | asc_dvc->max_total_qng = eep_config->max_total_qng; | ||
11099 | if ((eep_config->use_cmd_qng & eep_config->disc_enable) != | ||
11100 | eep_config->use_cmd_qng) { | ||
11101 | eep_config->disc_enable = eep_config->use_cmd_qng; | ||
11102 | warn_code |= ASC_WARN_CMD_QNG_CONFLICT; | ||
11103 | } | ||
11104 | if (asc_dvc->bus_type & (ASC_IS_ISA | ASC_IS_VL | ASC_IS_EISA)) { | ||
11105 | asc_dvc->irq_no = AscGetChipIRQ(iop_base, asc_dvc->bus_type); | ||
11106 | } | ||
11107 | ASC_EEP_SET_CHIP_ID(eep_config, | ||
11108 | ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID); | ||
11109 | asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config); | ||
11110 | if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) && | ||
11111 | !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) { | ||
11112 | asc_dvc->host_init_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX; | ||
11113 | } | ||
11114 | 11300 | ||
11115 | for (i = 0; i <= ASC_MAX_TID; i++) { | 11301 | for (retry = 0; retry < ASC_EEP_MAX_RETRY; retry++) { |
11116 | asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i]; | 11302 | unsigned char read_back; |
11117 | asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng; | 11303 | AscSetChipEEPCmd(iop_base, cmd_reg); |
11118 | asc_dvc->cfg->sdtr_period_offset[i] = | 11304 | mdelay(1); |
11119 | (uchar)(ASC_DEF_SDTR_OFFSET | | 11305 | read_back = AscGetChipEEPCmd(iop_base); |
11120 | (asc_dvc->host_init_sdtr_index << 4)); | 11306 | if (read_back == cmd_reg) |
11121 | } | 11307 | return 1; |
11122 | eep_config->cfg_msw = AscGetChipCfgMsw(iop_base); | ||
11123 | if (write_eep) { | ||
11124 | if ((i = | ||
11125 | AscSetEEPConfig(iop_base, eep_config, | ||
11126 | asc_dvc->bus_type)) != 0) { | ||
11127 | ASC_PRINT1 | ||
11128 | ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n", | ||
11129 | i); | ||
11130 | } else { | ||
11131 | ASC_PRINT | ||
11132 | ("AscInitFromEEP: Successfully re-wrote EEPROM.\n"); | ||
11133 | } | ||
11134 | } | 11308 | } |
11135 | return (warn_code); | 11309 | return 0; |
11136 | } | 11310 | } |
11137 | 11311 | ||
11138 | static ushort AscInitMicroCodeVar(ASC_DVC_VAR *asc_dvc) | 11312 | static void __devinit AscWaitEEPRead(void) |
11139 | { | 11313 | { |
11140 | int i; | 11314 | mdelay(1); |
11141 | ushort warn_code; | 11315 | } |
11142 | PortAddr iop_base; | ||
11143 | ASC_PADDR phy_addr; | ||
11144 | ASC_DCNT phy_size; | ||
11145 | |||
11146 | iop_base = asc_dvc->iop_base; | ||
11147 | warn_code = 0; | ||
11148 | for (i = 0; i <= ASC_MAX_TID; i++) { | ||
11149 | AscPutMCodeInitSDTRAtID(iop_base, i, | ||
11150 | asc_dvc->cfg->sdtr_period_offset[i] | ||
11151 | ); | ||
11152 | } | ||
11153 | 11316 | ||
11154 | AscInitQLinkVar(asc_dvc); | 11317 | static ushort __devinit AscReadEEPWord(PortAddr iop_base, uchar addr) |
11155 | AscWriteLramByte(iop_base, ASCV_DISC_ENABLE_B, | 11318 | { |
11156 | asc_dvc->cfg->disc_enable); | 11319 | ushort read_wval; |
11157 | AscWriteLramByte(iop_base, ASCV_HOSTSCSI_ID_B, | 11320 | uchar cmd_reg; |
11158 | ASC_TID_TO_TARGET_ID(asc_dvc->cfg->chip_scsi_id)); | ||
11159 | 11321 | ||
11160 | /* Align overrun buffer on an 8 byte boundary. */ | 11322 | AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE); |
11161 | phy_addr = virt_to_bus(asc_dvc->cfg->overrun_buf); | 11323 | AscWaitEEPRead(); |
11162 | phy_addr = cpu_to_le32((phy_addr + 7) & ~0x7); | 11324 | cmd_reg = addr | ASC_EEP_CMD_READ; |
11163 | AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_PADDR_D, | 11325 | AscWriteEEPCmdReg(iop_base, cmd_reg); |
11164 | (uchar *)&phy_addr, 1); | 11326 | AscWaitEEPRead(); |
11165 | phy_size = cpu_to_le32(ASC_OVERRUN_BSIZE - 8); | 11327 | read_wval = AscGetChipEEPData(iop_base); |
11166 | AscMemDWordCopyPtrToLram(iop_base, ASCV_OVERRUN_BSIZE_D, | 11328 | AscWaitEEPRead(); |
11167 | (uchar *)&phy_size, 1); | 11329 | return read_wval; |
11330 | } | ||
11168 | 11331 | ||
11169 | asc_dvc->cfg->mcode_date = | 11332 | static ushort __devinit |
11170 | AscReadLramWord(iop_base, (ushort)ASCV_MC_DATE_W); | 11333 | AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) |
11171 | asc_dvc->cfg->mcode_version = | 11334 | { |
11172 | AscReadLramWord(iop_base, (ushort)ASCV_MC_VER_W); | 11335 | ushort wval; |
11336 | ushort sum; | ||
11337 | ushort *wbuf; | ||
11338 | int cfg_beg; | ||
11339 | int cfg_end; | ||
11340 | int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2; | ||
11341 | int s_addr; | ||
11173 | 11342 | ||
11174 | AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR); | 11343 | wbuf = (ushort *)cfg_buf; |
11175 | if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) { | 11344 | sum = 0; |
11176 | asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR; | 11345 | /* Read two config words; Byte-swapping done by AscReadEEPWord(). */ |
11177 | return (warn_code); | 11346 | for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) { |
11347 | *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr); | ||
11348 | sum += *wbuf; | ||
11178 | } | 11349 | } |
11179 | if (AscStartChip(iop_base) != 1) { | 11350 | if (bus_type & ASC_IS_VL) { |
11180 | asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP; | 11351 | cfg_beg = ASC_EEP_DVC_CFG_BEG_VL; |
11181 | return (warn_code); | 11352 | cfg_end = ASC_EEP_MAX_DVC_ADDR_VL; |
11353 | } else { | ||
11354 | cfg_beg = ASC_EEP_DVC_CFG_BEG; | ||
11355 | cfg_end = ASC_EEP_MAX_DVC_ADDR; | ||
11182 | } | 11356 | } |
11183 | 11357 | for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) { | |
11184 | return (warn_code); | 11358 | wval = AscReadEEPWord(iop_base, (uchar)s_addr); |
11359 | if (s_addr <= uchar_end_in_config) { | ||
11360 | /* | ||
11361 | * Swap all char fields - must unswap bytes already swapped | ||
11362 | * by AscReadEEPWord(). | ||
11363 | */ | ||
11364 | *wbuf = le16_to_cpu(wval); | ||
11365 | } else { | ||
11366 | /* Don't swap word field at the end - cntl field. */ | ||
11367 | *wbuf = wval; | ||
11368 | } | ||
11369 | sum += wval; /* Checksum treats all EEPROM data as words. */ | ||
11370 | } | ||
11371 | /* | ||
11372 | * Read the checksum word which will be compared against 'sum' | ||
11373 | * by the caller. Word field already swapped. | ||
11374 | */ | ||
11375 | *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr); | ||
11376 | return sum; | ||
11185 | } | 11377 | } |
11186 | 11378 | ||
11187 | static int __init AscTestExternalLram(ASC_DVC_VAR *asc_dvc) | 11379 | static int __devinit AscTestExternalLram(ASC_DVC_VAR *asc_dvc) |
11188 | { | 11380 | { |
11189 | PortAddr iop_base; | 11381 | PortAddr iop_base; |
11190 | ushort q_addr; | 11382 | ushort q_addr; |
@@ -11197,7 +11389,7 @@ static int __init AscTestExternalLram(ASC_DVC_VAR *asc_dvc) | |||
11197 | saved_word = AscReadLramWord(iop_base, q_addr); | 11389 | saved_word = AscReadLramWord(iop_base, q_addr); |
11198 | AscSetChipLramAddr(iop_base, q_addr); | 11390 | AscSetChipLramAddr(iop_base, q_addr); |
11199 | AscSetChipLramData(iop_base, 0x55AA); | 11391 | AscSetChipLramData(iop_base, 0x55AA); |
11200 | DvcSleepMilliSecond(10); | 11392 | mdelay(10); |
11201 | AscSetChipLramAddr(iop_base, q_addr); | 11393 | AscSetChipLramAddr(iop_base, q_addr); |
11202 | if (AscGetChipLramData(iop_base) == 0x55AA) { | 11394 | if (AscGetChipLramData(iop_base) == 0x55AA) { |
11203 | sta = 1; | 11395 | sta = 1; |
@@ -11206,26 +11398,12 @@ static int __init AscTestExternalLram(ASC_DVC_VAR *asc_dvc) | |||
11206 | return (sta); | 11398 | return (sta); |
11207 | } | 11399 | } |
11208 | 11400 | ||
11209 | static int __init AscWriteEEPCmdReg(PortAddr iop_base, uchar cmd_reg) | 11401 | static void __devinit AscWaitEEPWrite(void) |
11210 | { | 11402 | { |
11211 | uchar read_back; | 11403 | mdelay(20); |
11212 | int retry; | ||
11213 | |||
11214 | retry = 0; | ||
11215 | while (TRUE) { | ||
11216 | AscSetChipEEPCmd(iop_base, cmd_reg); | ||
11217 | DvcSleepMilliSecond(1); | ||
11218 | read_back = AscGetChipEEPCmd(iop_base); | ||
11219 | if (read_back == cmd_reg) { | ||
11220 | return (1); | ||
11221 | } | ||
11222 | if (retry++ > ASC_EEP_MAX_RETRY) { | ||
11223 | return (0); | ||
11224 | } | ||
11225 | } | ||
11226 | } | 11404 | } |
11227 | 11405 | ||
11228 | static int __init AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg) | 11406 | static int __devinit AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg) |
11229 | { | 11407 | { |
11230 | ushort read_back; | 11408 | ushort read_back; |
11231 | int retry; | 11409 | int retry; |
@@ -11233,7 +11411,7 @@ static int __init AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg) | |||
11233 | retry = 0; | 11411 | retry = 0; |
11234 | while (TRUE) { | 11412 | while (TRUE) { |
11235 | AscSetChipEEPData(iop_base, data_reg); | 11413 | AscSetChipEEPData(iop_base, data_reg); |
11236 | DvcSleepMilliSecond(1); | 11414 | mdelay(1); |
11237 | read_back = AscGetChipEEPData(iop_base); | 11415 | read_back = AscGetChipEEPData(iop_base); |
11238 | if (read_back == data_reg) { | 11416 | if (read_back == data_reg) { |
11239 | return (1); | 11417 | return (1); |
@@ -11244,34 +11422,7 @@ static int __init AscWriteEEPDataReg(PortAddr iop_base, ushort data_reg) | |||
11244 | } | 11422 | } |
11245 | } | 11423 | } |
11246 | 11424 | ||
11247 | static void __init AscWaitEEPRead(void) | 11425 | static ushort __devinit |
11248 | { | ||
11249 | DvcSleepMilliSecond(1); | ||
11250 | return; | ||
11251 | } | ||
11252 | |||
11253 | static void __init AscWaitEEPWrite(void) | ||
11254 | { | ||
11255 | DvcSleepMilliSecond(20); | ||
11256 | return; | ||
11257 | } | ||
11258 | |||
11259 | static ushort __init AscReadEEPWord(PortAddr iop_base, uchar addr) | ||
11260 | { | ||
11261 | ushort read_wval; | ||
11262 | uchar cmd_reg; | ||
11263 | |||
11264 | AscWriteEEPCmdReg(iop_base, ASC_EEP_CMD_WRITE_DISABLE); | ||
11265 | AscWaitEEPRead(); | ||
11266 | cmd_reg = addr | ASC_EEP_CMD_READ; | ||
11267 | AscWriteEEPCmdReg(iop_base, cmd_reg); | ||
11268 | AscWaitEEPRead(); | ||
11269 | read_wval = AscGetChipEEPData(iop_base); | ||
11270 | AscWaitEEPRead(); | ||
11271 | return (read_wval); | ||
11272 | } | ||
11273 | |||
11274 | static ushort __init | ||
11275 | AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val) | 11426 | AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val) |
11276 | { | 11427 | { |
11277 | ushort read_wval; | 11428 | ushort read_wval; |
@@ -11292,54 +11443,7 @@ AscWriteEEPWord(PortAddr iop_base, uchar addr, ushort word_val) | |||
11292 | return (read_wval); | 11443 | return (read_wval); |
11293 | } | 11444 | } |
11294 | 11445 | ||
11295 | static ushort __init | 11446 | static int __devinit |
11296 | AscGetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) | ||
11297 | { | ||
11298 | ushort wval; | ||
11299 | ushort sum; | ||
11300 | ushort *wbuf; | ||
11301 | int cfg_beg; | ||
11302 | int cfg_end; | ||
11303 | int uchar_end_in_config = ASC_EEP_MAX_DVC_ADDR - 2; | ||
11304 | int s_addr; | ||
11305 | |||
11306 | wbuf = (ushort *)cfg_buf; | ||
11307 | sum = 0; | ||
11308 | /* Read two config words; Byte-swapping done by AscReadEEPWord(). */ | ||
11309 | for (s_addr = 0; s_addr < 2; s_addr++, wbuf++) { | ||
11310 | *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr); | ||
11311 | sum += *wbuf; | ||
11312 | } | ||
11313 | if (bus_type & ASC_IS_VL) { | ||
11314 | cfg_beg = ASC_EEP_DVC_CFG_BEG_VL; | ||
11315 | cfg_end = ASC_EEP_MAX_DVC_ADDR_VL; | ||
11316 | } else { | ||
11317 | cfg_beg = ASC_EEP_DVC_CFG_BEG; | ||
11318 | cfg_end = ASC_EEP_MAX_DVC_ADDR; | ||
11319 | } | ||
11320 | for (s_addr = cfg_beg; s_addr <= (cfg_end - 1); s_addr++, wbuf++) { | ||
11321 | wval = AscReadEEPWord(iop_base, (uchar)s_addr); | ||
11322 | if (s_addr <= uchar_end_in_config) { | ||
11323 | /* | ||
11324 | * Swap all char fields - must unswap bytes already swapped | ||
11325 | * by AscReadEEPWord(). | ||
11326 | */ | ||
11327 | *wbuf = le16_to_cpu(wval); | ||
11328 | } else { | ||
11329 | /* Don't swap word field at the end - cntl field. */ | ||
11330 | *wbuf = wval; | ||
11331 | } | ||
11332 | sum += wval; /* Checksum treats all EEPROM data as words. */ | ||
11333 | } | ||
11334 | /* | ||
11335 | * Read the checksum word which will be compared against 'sum' | ||
11336 | * by the caller. Word field already swapped. | ||
11337 | */ | ||
11338 | *wbuf = AscReadEEPWord(iop_base, (uchar)s_addr); | ||
11339 | return (sum); | ||
11340 | } | ||
11341 | |||
11342 | static int __init | ||
11343 | AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) | 11447 | AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) |
11344 | { | 11448 | { |
11345 | int n_error; | 11449 | int n_error; |
@@ -11432,10 +11536,10 @@ AscSetEEPConfigOnce(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) | |||
11432 | if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) { | 11536 | if (AscReadEEPWord(iop_base, (uchar)s_addr) != sum) { |
11433 | n_error++; | 11537 | n_error++; |
11434 | } | 11538 | } |
11435 | return (n_error); | 11539 | return n_error; |
11436 | } | 11540 | } |
11437 | 11541 | ||
11438 | static int __init | 11542 | static int __devinit |
11439 | AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) | 11543 | AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) |
11440 | { | 11544 | { |
11441 | int retry; | 11545 | int retry; |
@@ -11451,2386 +11555,326 @@ AscSetEEPConfig(PortAddr iop_base, ASCEEP_CONFIG *cfg_buf, ushort bus_type) | |||
11451 | break; | 11555 | break; |
11452 | } | 11556 | } |
11453 | } | 11557 | } |
11454 | return (n_error); | 11558 | return n_error; |
11455 | } | 11559 | } |
11456 | 11560 | ||
11457 | static void | 11561 | static ushort __devinit AscInitFromEEP(ASC_DVC_VAR *asc_dvc) |
11458 | AscAsyncFix(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq) | ||
11459 | { | 11562 | { |
11460 | uchar dvc_type; | 11563 | ASCEEP_CONFIG eep_config_buf; |
11461 | ASC_SCSI_BIT_ID_TYPE tid_bits; | 11564 | ASCEEP_CONFIG *eep_config; |
11462 | 11565 | PortAddr iop_base; | |
11463 | dvc_type = ASC_INQ_DVC_TYPE(inq); | 11566 | ushort chksum; |
11464 | tid_bits = ASC_TIX_TO_TARGET_ID(tid_no); | 11567 | ushort warn_code; |
11465 | 11568 | ushort cfg_msw, cfg_lsw; | |
11466 | if (asc_dvc->bug_fix_cntl & ASC_BUG_FIX_ASYN_USE_SYN) { | 11569 | int i; |
11467 | if (!(asc_dvc->init_sdtr & tid_bits)) { | 11570 | int write_eep = 0; |
11468 | if ((dvc_type == TYPE_ROM) && | ||
11469 | (AscCompareString((uchar *)inq->vendor_id, | ||
11470 | (uchar *)"HP ", 3) == 0)) { | ||
11471 | asc_dvc->pci_fix_asyn_xfer_always |= tid_bits; | ||
11472 | } | ||
11473 | asc_dvc->pci_fix_asyn_xfer |= tid_bits; | ||
11474 | if ((dvc_type == TYPE_PROCESSOR) || | ||
11475 | (dvc_type == TYPE_SCANNER) || | ||
11476 | (dvc_type == TYPE_ROM) || (dvc_type == TYPE_TAPE)) { | ||
11477 | asc_dvc->pci_fix_asyn_xfer &= ~tid_bits; | ||
11478 | } | ||
11479 | 11571 | ||
11480 | if (asc_dvc->pci_fix_asyn_xfer & tid_bits) { | 11572 | iop_base = asc_dvc->iop_base; |
11481 | AscSetRunChipSynRegAtID(asc_dvc->iop_base, | 11573 | warn_code = 0; |
11482 | tid_no, | 11574 | AscWriteLramWord(iop_base, ASCV_HALTCODE_W, 0x00FE); |
11483 | ASYN_SDTR_DATA_FIX_PCI_REV_AB); | 11575 | AscStopQueueExe(iop_base); |
11576 | if ((AscStopChip(iop_base) == FALSE) || | ||
11577 | (AscGetChipScsiCtrl(iop_base) != 0)) { | ||
11578 | asc_dvc->init_state |= ASC_INIT_RESET_SCSI_DONE; | ||
11579 | AscResetChipAndScsiBus(asc_dvc); | ||
11580 | mdelay(asc_dvc->scsi_reset_wait * 1000); /* XXX: msleep? */ | ||
11581 | } | ||
11582 | if (AscIsChipHalted(iop_base) == FALSE) { | ||
11583 | asc_dvc->err_code |= ASC_IERR_START_STOP_CHIP; | ||
11584 | return (warn_code); | ||
11585 | } | ||
11586 | AscSetPCAddr(iop_base, ASC_MCODE_START_ADDR); | ||
11587 | if (AscGetPCAddr(iop_base) != ASC_MCODE_START_ADDR) { | ||
11588 | asc_dvc->err_code |= ASC_IERR_SET_PC_ADDR; | ||
11589 | return (warn_code); | ||
11590 | } | ||
11591 | eep_config = (ASCEEP_CONFIG *)&eep_config_buf; | ||
11592 | cfg_msw = AscGetChipCfgMsw(iop_base); | ||
11593 | cfg_lsw = AscGetChipCfgLsw(iop_base); | ||
11594 | if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) { | ||
11595 | cfg_msw &= ~ASC_CFG_MSW_CLR_MASK; | ||
11596 | warn_code |= ASC_WARN_CFG_MSW_RECOVER; | ||
11597 | AscSetChipCfgMsw(iop_base, cfg_msw); | ||
11598 | } | ||
11599 | chksum = AscGetEEPConfig(iop_base, eep_config, asc_dvc->bus_type); | ||
11600 | ASC_DBG(1, "chksum 0x%x\n", chksum); | ||
11601 | if (chksum == 0) { | ||
11602 | chksum = 0xaa55; | ||
11603 | } | ||
11604 | if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) { | ||
11605 | warn_code |= ASC_WARN_AUTO_CONFIG; | ||
11606 | if (asc_dvc->cfg->chip_version == 3) { | ||
11607 | if (eep_config->cfg_lsw != cfg_lsw) { | ||
11608 | warn_code |= ASC_WARN_EEPROM_RECOVER; | ||
11609 | eep_config->cfg_lsw = | ||
11610 | AscGetChipCfgLsw(iop_base); | ||
11611 | } | ||
11612 | if (eep_config->cfg_msw != cfg_msw) { | ||
11613 | warn_code |= ASC_WARN_EEPROM_RECOVER; | ||
11614 | eep_config->cfg_msw = | ||
11615 | AscGetChipCfgMsw(iop_base); | ||
11484 | } | 11616 | } |
11485 | } | 11617 | } |
11486 | } | 11618 | } |
11487 | return; | 11619 | eep_config->cfg_msw &= ~ASC_CFG_MSW_CLR_MASK; |
11488 | } | 11620 | eep_config->cfg_lsw |= ASC_CFG0_HOST_INT_ON; |
11489 | 11621 | ASC_DBG(1, "eep_config->chksum 0x%x\n", eep_config->chksum); | |
11490 | static int AscTagQueuingSafe(ASC_SCSI_INQUIRY *inq) | 11622 | if (chksum != eep_config->chksum) { |
11491 | { | 11623 | if (AscGetChipVersion(iop_base, asc_dvc->bus_type) == |
11492 | if ((inq->add_len >= 32) && | 11624 | ASC_CHIP_VER_PCI_ULTRA_3050) { |
11493 | (AscCompareString((uchar *)inq->vendor_id, | 11625 | ASC_DBG(1, "chksum error ignored; EEPROM-less board\n"); |
11494 | (uchar *)"QUANTUM XP34301", 15) == 0) && | 11626 | eep_config->init_sdtr = 0xFF; |
11495 | (AscCompareString((uchar *)inq->product_rev_level, | 11627 | eep_config->disc_enable = 0xFF; |
11496 | (uchar *)"1071", 4) == 0)) { | 11628 | eep_config->start_motor = 0xFF; |
11497 | return 0; | 11629 | eep_config->use_cmd_qng = 0; |
11498 | } | 11630 | eep_config->max_total_qng = 0xF0; |
11499 | return 1; | 11631 | eep_config->max_tag_qng = 0x20; |
11500 | } | 11632 | eep_config->cntl = 0xBFFF; |
11501 | 11633 | ASC_EEP_SET_CHIP_ID(eep_config, 7); | |
11502 | static void | 11634 | eep_config->no_scam = 0; |
11503 | AscInquiryHandling(ASC_DVC_VAR *asc_dvc, uchar tid_no, ASC_SCSI_INQUIRY *inq) | 11635 | eep_config->adapter_info[0] = 0; |
11504 | { | 11636 | eep_config->adapter_info[1] = 0; |
11505 | ASC_SCSI_BIT_ID_TYPE tid_bit = ASC_TIX_TO_TARGET_ID(tid_no); | 11637 | eep_config->adapter_info[2] = 0; |
11506 | ASC_SCSI_BIT_ID_TYPE orig_init_sdtr, orig_use_tagged_qng; | 11638 | eep_config->adapter_info[3] = 0; |
11507 | 11639 | eep_config->adapter_info[4] = 0; | |
11508 | orig_init_sdtr = asc_dvc->init_sdtr; | 11640 | /* Indicate EEPROM-less board. */ |
11509 | orig_use_tagged_qng = asc_dvc->use_tagged_qng; | 11641 | eep_config->adapter_info[5] = 0xBB; |
11510 | 11642 | } else { | |
11511 | asc_dvc->init_sdtr &= ~tid_bit; | 11643 | ASC_PRINT |
11512 | asc_dvc->cfg->can_tagged_qng &= ~tid_bit; | 11644 | ("AscInitFromEEP: EEPROM checksum error; Will try to re-write EEPROM.\n"); |
11513 | asc_dvc->use_tagged_qng &= ~tid_bit; | 11645 | write_eep = 1; |
11514 | 11646 | warn_code |= ASC_WARN_EEPROM_CHKSUM; | |
11515 | if (ASC_INQ_RESPONSE_FMT(inq) >= 2 || ASC_INQ_ANSI_VER(inq) >= 2) { | ||
11516 | if ((asc_dvc->cfg->sdtr_enable & tid_bit) && ASC_INQ_SYNC(inq)) { | ||
11517 | asc_dvc->init_sdtr |= tid_bit; | ||
11518 | } | 11647 | } |
11519 | if ((asc_dvc->cfg->cmd_qng_enabled & tid_bit) && | 11648 | } |
11520 | ASC_INQ_CMD_QUEUE(inq)) { | 11649 | asc_dvc->cfg->sdtr_enable = eep_config->init_sdtr; |
11521 | if (AscTagQueuingSafe(inq)) { | 11650 | asc_dvc->cfg->disc_enable = eep_config->disc_enable; |
11522 | asc_dvc->use_tagged_qng |= tid_bit; | 11651 | asc_dvc->cfg->cmd_qng_enabled = eep_config->use_cmd_qng; |
11523 | asc_dvc->cfg->can_tagged_qng |= tid_bit; | 11652 | asc_dvc->cfg->isa_dma_speed = ASC_EEP_GET_DMA_SPD(eep_config); |
11524 | } | 11653 | asc_dvc->start_motor = eep_config->start_motor; |
11654 | asc_dvc->dvc_cntl = eep_config->cntl; | ||
11655 | asc_dvc->no_scam = eep_config->no_scam; | ||
11656 | asc_dvc->cfg->adapter_info[0] = eep_config->adapter_info[0]; | ||
11657 | asc_dvc->cfg->adapter_info[1] = eep_config->adapter_info[1]; | ||
11658 | asc_dvc->cfg->adapter_info[2] = eep_config->adapter_info[2]; | ||
11659 | asc_dvc->cfg->adapter_info[3] = eep_config->adapter_info[3]; | ||
11660 | asc_dvc->cfg->adapter_info[4] = eep_config->adapter_info[4]; | ||
11661 | asc_dvc->cfg->adapter_info[5] = eep_config->adapter_info[5]; | ||
11662 | if (!AscTestExternalLram(asc_dvc)) { | ||
11663 | if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == | ||
11664 | ASC_IS_PCI_ULTRA)) { | ||
11665 | eep_config->max_total_qng = | ||
11666 | ASC_MAX_PCI_ULTRA_INRAM_TOTAL_QNG; | ||
11667 | eep_config->max_tag_qng = | ||
11668 | ASC_MAX_PCI_ULTRA_INRAM_TAG_QNG; | ||
11669 | } else { | ||
11670 | eep_config->cfg_msw |= 0x0800; | ||
11671 | cfg_msw |= 0x0800; | ||
11672 | AscSetChipCfgMsw(iop_base, cfg_msw); | ||
11673 | eep_config->max_total_qng = ASC_MAX_PCI_INRAM_TOTAL_QNG; | ||
11674 | eep_config->max_tag_qng = ASC_MAX_INRAM_TAG_QNG; | ||
11525 | } | 11675 | } |
11676 | } else { | ||
11526 | } | 11677 | } |
11527 | if (orig_use_tagged_qng != asc_dvc->use_tagged_qng) { | 11678 | if (eep_config->max_total_qng < ASC_MIN_TOTAL_QNG) { |
11528 | AscWriteLramByte(asc_dvc->iop_base, ASCV_DISC_ENABLE_B, | 11679 | eep_config->max_total_qng = ASC_MIN_TOTAL_QNG; |
11529 | asc_dvc->cfg->disc_enable); | ||
11530 | AscWriteLramByte(asc_dvc->iop_base, ASCV_USE_TAGGED_QNG_B, | ||
11531 | asc_dvc->use_tagged_qng); | ||
11532 | AscWriteLramByte(asc_dvc->iop_base, ASCV_CAN_TAGGED_QNG_B, | ||
11533 | asc_dvc->cfg->can_tagged_qng); | ||
11534 | |||
11535 | asc_dvc->max_dvc_qng[tid_no] = | ||
11536 | asc_dvc->cfg->max_tag_qng[tid_no]; | ||
11537 | AscWriteLramByte(asc_dvc->iop_base, | ||
11538 | (ushort)(ASCV_MAX_DVC_QNG_BEG + tid_no), | ||
11539 | asc_dvc->max_dvc_qng[tid_no]); | ||
11540 | } | 11680 | } |
11541 | if (orig_init_sdtr != asc_dvc->init_sdtr) { | 11681 | if (eep_config->max_total_qng > ASC_MAX_TOTAL_QNG) { |
11542 | AscAsyncFix(asc_dvc, tid_no, inq); | 11682 | eep_config->max_total_qng = ASC_MAX_TOTAL_QNG; |
11543 | } | 11683 | } |
11544 | return; | 11684 | if (eep_config->max_tag_qng > eep_config->max_total_qng) { |
11545 | } | 11685 | eep_config->max_tag_qng = eep_config->max_total_qng; |
11546 | |||
11547 | static int AscCompareString(uchar *str1, uchar *str2, int len) | ||
11548 | { | ||
11549 | int i; | ||
11550 | int diff; | ||
11551 | |||
11552 | for (i = 0; i < len; i++) { | ||
11553 | diff = (int)(str1[i] - str2[i]); | ||
11554 | if (diff != 0) | ||
11555 | return (diff); | ||
11556 | } | 11686 | } |
11557 | return (0); | 11687 | if (eep_config->max_tag_qng < ASC_MIN_TAG_Q_PER_DVC) { |
11558 | } | 11688 | eep_config->max_tag_qng = ASC_MIN_TAG_Q_PER_DVC; |
11559 | 11689 | } | |
11560 | static uchar AscReadLramByte(PortAddr iop_base, ushort addr) | 11690 | asc_dvc->max_total_qng = eep_config->max_total_qng; |
11561 | { | 11691 | if ((eep_config->use_cmd_qng & eep_config->disc_enable) != |
11562 | uchar byte_data; | 11692 | eep_config->use_cmd_qng) { |
11563 | ushort word_data; | 11693 | eep_config->disc_enable = eep_config->use_cmd_qng; |
11564 | 11694 | warn_code |= ASC_WARN_CMD_QNG_CONFLICT; | |
11565 | if (isodd_word(addr)) { | 11695 | } |
11566 | AscSetChipLramAddr(iop_base, addr - 1); | 11696 | ASC_EEP_SET_CHIP_ID(eep_config, |
11567 | word_data = AscGetChipLramData(iop_base); | 11697 | ASC_EEP_GET_CHIP_ID(eep_config) & ASC_MAX_TID); |
11568 | byte_data = (uchar)((word_data >> 8) & 0xFF); | 11698 | asc_dvc->cfg->chip_scsi_id = ASC_EEP_GET_CHIP_ID(eep_config); |
11569 | } else { | 11699 | if (((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) && |
11570 | AscSetChipLramAddr(iop_base, addr); | 11700 | !(asc_dvc->dvc_cntl & ASC_CNTL_SDTR_ENABLE_ULTRA)) { |
11571 | word_data = AscGetChipLramData(iop_base); | 11701 | asc_dvc->min_sdtr_index = ASC_SDTR_ULTRA_PCI_10MB_INDEX; |
11572 | byte_data = (uchar)(word_data & 0xFF); | ||
11573 | } | 11702 | } |
11574 | return (byte_data); | ||
11575 | } | ||
11576 | |||
11577 | static ushort AscReadLramWord(PortAddr iop_base, ushort addr) | ||
11578 | { | ||
11579 | ushort word_data; | ||
11580 | |||
11581 | AscSetChipLramAddr(iop_base, addr); | ||
11582 | word_data = AscGetChipLramData(iop_base); | ||
11583 | return (word_data); | ||
11584 | } | ||
11585 | |||
11586 | #if CC_VERY_LONG_SG_LIST | ||
11587 | static ASC_DCNT AscReadLramDWord(PortAddr iop_base, ushort addr) | ||
11588 | { | ||
11589 | ushort val_low, val_high; | ||
11590 | ASC_DCNT dword_data; | ||
11591 | 11703 | ||
11592 | AscSetChipLramAddr(iop_base, addr); | 11704 | for (i = 0; i <= ASC_MAX_TID; i++) { |
11593 | val_low = AscGetChipLramData(iop_base); | 11705 | asc_dvc->dos_int13_table[i] = eep_config->dos_int13_table[i]; |
11594 | val_high = AscGetChipLramData(iop_base); | 11706 | asc_dvc->cfg->max_tag_qng[i] = eep_config->max_tag_qng; |
11595 | dword_data = ((ASC_DCNT) val_high << 16) | (ASC_DCNT) val_low; | 11707 | asc_dvc->cfg->sdtr_period_offset[i] = |
11596 | return (dword_data); | 11708 | (uchar)(ASC_DEF_SDTR_OFFSET | |
11709 | (asc_dvc->min_sdtr_index << 4)); | ||
11710 | } | ||
11711 | eep_config->cfg_msw = AscGetChipCfgMsw(iop_base); | ||
11712 | if (write_eep) { | ||
11713 | if ((i = AscSetEEPConfig(iop_base, eep_config, | ||
11714 | asc_dvc->bus_type)) != 0) { | ||
11715 | ASC_PRINT1 | ||
11716 | ("AscInitFromEEP: Failed to re-write EEPROM with %d errors.\n", | ||
11717 | i); | ||
11718 | } else { | ||
11719 | ASC_PRINT | ||
11720 | ("AscInitFromEEP: Successfully re-wrote EEPROM.\n"); | ||
11721 | } | ||
11722 | } | ||
11723 | return (warn_code); | ||
11597 | } | 11724 | } |
11598 | #endif /* CC_VERY_LONG_SG_LIST */ | ||
11599 | 11725 | ||
11600 | static void AscWriteLramWord(PortAddr iop_base, ushort addr, ushort word_val) | 11726 | static int __devinit AscInitGetConfig(struct Scsi_Host *shost) |
11601 | { | 11727 | { |
11602 | AscSetChipLramAddr(iop_base, addr); | 11728 | struct asc_board *board = shost_priv(shost); |
11603 | AscSetChipLramData(iop_base, word_val); | 11729 | ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var; |
11604 | return; | 11730 | unsigned short warn_code = 0; |
11605 | } | ||
11606 | 11731 | ||
11607 | static void AscWriteLramByte(PortAddr iop_base, ushort addr, uchar byte_val) | 11732 | asc_dvc->init_state = ASC_INIT_STATE_BEG_GET_CFG; |
11608 | { | 11733 | if (asc_dvc->err_code != 0) |
11609 | ushort word_data; | 11734 | return asc_dvc->err_code; |
11610 | 11735 | ||
11611 | if (isodd_word(addr)) { | 11736 | if (AscFindSignature(asc_dvc->iop_base)) { |
11612 | addr--; | 11737 | warn_code |= AscInitAscDvcVar(asc_dvc); |
11613 | word_data = AscReadLramWord(iop_base, addr); | 11738 | warn_code |= AscInitFromEEP(asc_dvc); |
11614 | word_data &= 0x00FF; | 11739 | asc_dvc->init_state |= ASC_INIT_STATE_END_GET_CFG; |
11615 | word_data |= (((ushort)byte_val << 8) & 0xFF00); | 11740 | if (asc_dvc->scsi_reset_wait > ASC_MAX_SCSI_RESET_WAIT) |
11741 | asc_dvc->scsi_reset_wait = ASC_MAX_SCSI_RESET_WAIT; | ||
11616 | } else { | 11742 | } else { |
11617 | word_data = AscReadLramWord(iop_base, addr); | 11743 | asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; |
11618 | word_data &= 0xFF00; | ||
11619 | word_data |= ((ushort)byte_val & 0x00FF); | ||
11620 | } | 11744 | } |
11621 | AscWriteLramWord(iop_base, addr, word_data); | ||
11622 | return; | ||
11623 | } | ||
11624 | 11745 | ||
11625 | /* | 11746 | switch (warn_code) { |
11626 | * Copy 2 bytes to LRAM. | 11747 | case 0: /* No error */ |
11627 | * | 11748 | break; |
11628 | * The source data is assumed to be in little-endian order in memory | 11749 | case ASC_WARN_IO_PORT_ROTATE: |
11629 | * and is maintained in little-endian order when written to LRAM. | 11750 | shost_printk(KERN_WARNING, shost, "I/O port address " |
11630 | */ | 11751 | "modified\n"); |
11631 | static void | 11752 | break; |
11632 | AscMemWordCopyPtrToLram(PortAddr iop_base, | 11753 | case ASC_WARN_AUTO_CONFIG: |
11633 | ushort s_addr, uchar *s_buffer, int words) | 11754 | shost_printk(KERN_WARNING, shost, "I/O port increment switch " |
11634 | { | 11755 | "enabled\n"); |
11635 | int i; | 11756 | break; |
11636 | 11757 | case ASC_WARN_EEPROM_CHKSUM: | |
11637 | AscSetChipLramAddr(iop_base, s_addr); | 11758 | shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n"); |
11638 | for (i = 0; i < 2 * words; i += 2) { | 11759 | break; |
11639 | /* | 11760 | case ASC_WARN_IRQ_MODIFIED: |
11640 | * On a little-endian system the second argument below | 11761 | shost_printk(KERN_WARNING, shost, "IRQ modified\n"); |
11641 | * produces a little-endian ushort which is written to | 11762 | break; |
11642 | * LRAM in little-endian order. On a big-endian system | 11763 | case ASC_WARN_CMD_QNG_CONFLICT: |
11643 | * the second argument produces a big-endian ushort which | 11764 | shost_printk(KERN_WARNING, shost, "tag queuing enabled w/o " |
11644 | * is "transparently" byte-swapped by outpw() and written | 11765 | "disconnects\n"); |
11645 | * in little-endian order to LRAM. | 11766 | break; |
11646 | */ | 11767 | default: |
11647 | outpw(iop_base + IOP_RAM_DATA, | 11768 | shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n", |
11648 | ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); | 11769 | warn_code); |
11770 | break; | ||
11649 | } | 11771 | } |
11650 | return; | ||
11651 | } | ||
11652 | 11772 | ||
11653 | /* | 11773 | if (asc_dvc->err_code != 0) |
11654 | * Copy 4 bytes to LRAM. | 11774 | shost_printk(KERN_ERR, shost, "error 0x%x at init_state " |
11655 | * | 11775 | "0x%x\n", asc_dvc->err_code, asc_dvc->init_state); |
11656 | * The source data is assumed to be in little-endian order in memory | ||
11657 | * and is maintained in little-endian order when writen to LRAM. | ||
11658 | */ | ||
11659 | static void | ||
11660 | AscMemDWordCopyPtrToLram(PortAddr iop_base, | ||
11661 | ushort s_addr, uchar *s_buffer, int dwords) | ||
11662 | { | ||
11663 | int i; | ||
11664 | 11776 | ||
11665 | AscSetChipLramAddr(iop_base, s_addr); | 11777 | return asc_dvc->err_code; |
11666 | for (i = 0; i < 4 * dwords; i += 4) { | ||
11667 | outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 1] << 8) | s_buffer[i]); /* LSW */ | ||
11668 | outpw(iop_base + IOP_RAM_DATA, ((ushort)s_buffer[i + 3] << 8) | s_buffer[i + 2]); /* MSW */ | ||
11669 | } | ||
11670 | return; | ||
11671 | } | 11778 | } |
11672 | 11779 | ||
11673 | /* | 11780 | static int __devinit AscInitSetConfig(struct pci_dev *pdev, struct Scsi_Host *shost) |
11674 | * Copy 2 bytes from LRAM. | ||
11675 | * | ||
11676 | * The source data is assumed to be in little-endian order in LRAM | ||
11677 | * and is maintained in little-endian order when written to memory. | ||
11678 | */ | ||
11679 | static void | ||
11680 | AscMemWordCopyPtrFromLram(PortAddr iop_base, | ||
11681 | ushort s_addr, uchar *d_buffer, int words) | ||
11682 | { | 11781 | { |
11683 | int i; | 11782 | struct asc_board *board = shost_priv(shost); |
11684 | ushort word; | 11783 | ASC_DVC_VAR *asc_dvc = &board->dvc_var.asc_dvc_var; |
11784 | PortAddr iop_base = asc_dvc->iop_base; | ||
11785 | unsigned short cfg_msw; | ||
11786 | unsigned short warn_code = 0; | ||
11685 | 11787 | ||
11686 | AscSetChipLramAddr(iop_base, s_addr); | 11788 | asc_dvc->init_state |= ASC_INIT_STATE_BEG_SET_CFG; |
11687 | for (i = 0; i < 2 * words; i += 2) { | 11789 | if (asc_dvc->err_code != 0) |
11688 | word = inpw(iop_base + IOP_RAM_DATA); | 11790 | return asc_dvc->err_code; |
11689 | d_buffer[i] = word & 0xff; | 11791 | if (!AscFindSignature(asc_dvc->iop_base)) { |
11690 | d_buffer[i + 1] = (word >> 8) & 0xff; | 11792 | asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; |
11793 | return asc_dvc->err_code; | ||
11691 | } | 11794 | } |
11692 | return; | ||
11693 | } | ||
11694 | |||
11695 | static ASC_DCNT AscMemSumLramWord(PortAddr iop_base, ushort s_addr, int words) | ||
11696 | { | ||
11697 | ASC_DCNT sum; | ||
11698 | int i; | ||
11699 | 11795 | ||
11700 | sum = 0L; | 11796 | cfg_msw = AscGetChipCfgMsw(iop_base); |
11701 | for (i = 0; i < words; i++, s_addr += 2) { | 11797 | if ((cfg_msw & ASC_CFG_MSW_CLR_MASK) != 0) { |
11702 | sum += AscReadLramWord(iop_base, s_addr); | 11798 | cfg_msw &= ~ASC_CFG_MSW_CLR_MASK; |
11799 | warn_code |= ASC_WARN_CFG_MSW_RECOVER; | ||
11800 | AscSetChipCfgMsw(iop_base, cfg_msw); | ||
11703 | } | 11801 | } |
11704 | return (sum); | 11802 | if ((asc_dvc->cfg->cmd_qng_enabled & asc_dvc->cfg->disc_enable) != |
11705 | } | 11803 | asc_dvc->cfg->cmd_qng_enabled) { |
11706 | 11804 | asc_dvc->cfg->disc_enable = asc_dvc->cfg->cmd_qng_enabled; | |
11707 | static void | 11805 | warn_code |= ASC_WARN_CMD_QNG_CONFLICT; |
11708 | AscMemWordSetLram(PortAddr iop_base, ushort s_addr, ushort set_wval, int words) | ||
11709 | { | ||
11710 | int i; | ||
11711 | |||
11712 | AscSetChipLramAddr(iop_base, s_addr); | ||
11713 | for (i = 0; i < words; i++) { | ||
11714 | AscSetChipLramData(iop_base, set_wval); | ||
11715 | } | 11806 | } |
11716 | return; | 11807 | if (AscGetChipStatus(iop_base) & CSW_AUTO_CONFIG) { |
11717 | } | 11808 | warn_code |= ASC_WARN_AUTO_CONFIG; |
11718 | 11809 | } | |
11719 | /* | 11810 | #ifdef CONFIG_PCI |
11720 | * --- Adv Library Functions | 11811 | if (asc_dvc->bus_type & ASC_IS_PCI) { |
11721 | */ | 11812 | cfg_msw &= 0xFFC0; |
11722 | 11813 | AscSetChipCfgMsw(iop_base, cfg_msw); | |
11723 | /* a_mcode.h */ | 11814 | if ((asc_dvc->bus_type & ASC_IS_PCI_ULTRA) == ASC_IS_PCI_ULTRA) { |
11724 | 11815 | } else { | |
11725 | /* Microcode buffer is kept after initialization for error recovery. */ | 11816 | if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) || |
11726 | static unsigned char _adv_asc3550_buf[] = { | 11817 | (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) { |
11727 | 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0x16, 0x18, 0xe4, 0x00, 0xfc, | 11818 | asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_IF_NOT_DWB; |
11728 | 0x01, 0x00, 0x48, 0xe4, | 11819 | asc_dvc->bug_fix_cntl |= |
11729 | 0xbe, 0x18, 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0x00, 0xfa, 0xff, 0xff, | 11820 | ASC_BUG_FIX_ASYN_USE_SYN; |
11730 | 0x28, 0x0e, 0x9e, 0xe7, | 11821 | } |
11731 | 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x00, 0xf6, 0x01, 0xe6, 0x09, 0xe7, | 11822 | } |
11732 | 0x55, 0xf0, 0x01, 0xf6, | 11823 | } else |
11733 | 0x01, 0xfa, 0x08, 0x00, 0x03, 0x00, 0x04, 0x00, 0x18, 0xf4, 0x10, 0x00, | 11824 | #endif /* CONFIG_PCI */ |
11734 | 0x00, 0xec, 0x85, 0xf0, | 11825 | if (asc_dvc->bus_type == ASC_IS_ISAPNP) { |
11735 | 0xbc, 0x00, 0xd5, 0xf0, 0x8e, 0x0c, 0x38, 0x54, 0x00, 0xe6, 0x1e, 0xf0, | 11826 | if (AscGetChipVersion(iop_base, asc_dvc->bus_type) |
11736 | 0x86, 0xf0, 0xb4, 0x00, | 11827 | == ASC_CHIP_VER_ASYN_BUG) { |
11737 | 0x98, 0x57, 0xd0, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, 0x0c, 0x00, 0xbb, 0x00, | 11828 | asc_dvc->bug_fix_cntl |= ASC_BUG_FIX_ASYN_USE_SYN; |
11738 | 0xaa, 0x18, 0x02, 0x80, | 11829 | } |
11739 | 0x32, 0xf0, 0x01, 0xfc, 0x88, 0x0c, 0xc6, 0x12, 0x02, 0x13, 0x18, 0x40, | 11830 | } |
11740 | 0x00, 0x57, 0x01, 0xea, | 11831 | if (AscSetChipScsiID(iop_base, asc_dvc->cfg->chip_scsi_id) != |
11741 | 0x3c, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, 0x3e, 0x57, 0x00, 0x80, | 11832 | asc_dvc->cfg->chip_scsi_id) { |
11742 | 0x03, 0xe6, 0xb6, 0x00, | 11833 | asc_dvc->err_code |= ASC_IERR_SET_SCSI_ID; |
11743 | 0xc0, 0x00, 0x01, 0x01, 0x3e, 0x01, 0xda, 0x0f, 0x22, 0x10, 0x08, 0x12, | 11834 | } |
11744 | 0x02, 0x4a, 0xb9, 0x54, | 11835 | #ifdef CONFIG_ISA |
11745 | 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, 0x20, 0x00, 0x32, 0x00, | 11836 | if (asc_dvc->bus_type & ASC_IS_ISA) { |
11746 | 0x3e, 0x00, 0x80, 0x00, | 11837 | AscSetIsaDmaChannel(iop_base, asc_dvc->cfg->isa_dma_channel); |
11747 | 0x24, 0x01, 0x3c, 0x01, 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, | 11838 | AscSetIsaDmaSpeed(iop_base, asc_dvc->cfg->isa_dma_speed); |
11748 | 0x74, 0x01, 0x76, 0x01, | 11839 | } |
11749 | 0x78, 0x01, 0x62, 0x0a, 0x92, 0x0c, 0x2c, 0x10, 0x2e, 0x10, 0x06, 0x13, | 11840 | #endif /* CONFIG_ISA */ |
11750 | 0x4c, 0x1c, 0xbb, 0x55, | ||
11751 | 0x3c, 0x56, 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0xb1, 0xf0, | ||
11752 | 0x03, 0xf7, 0x06, 0xf7, | ||
11753 | 0x03, 0xfc, 0x0f, 0x00, 0x40, 0x00, 0xbe, 0x00, 0x00, 0x01, 0xb0, 0x08, | ||
11754 | 0x30, 0x13, 0x64, 0x15, | ||
11755 | 0x32, 0x1c, 0x38, 0x1c, 0x4e, 0x1c, 0x10, 0x44, 0x02, 0x48, 0x00, 0x4c, | ||
11756 | 0x04, 0xea, 0x5d, 0xf0, | ||
11757 | 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x34, 0x00, 0x36, 0x00, 0x98, 0x00, | ||
11758 | 0xcc, 0x00, 0x20, 0x01, | ||
11759 | 0x4e, 0x01, 0x4e, 0x0b, 0x1e, 0x0e, 0x0c, 0x10, 0x0a, 0x12, 0x04, 0x13, | ||
11760 | 0x40, 0x13, 0x30, 0x1c, | ||
11761 | 0x00, 0x4e, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, | ||
11762 | 0x59, 0xf0, 0xa7, 0xf0, | ||
11763 | 0xb8, 0xf0, 0x0e, 0xf7, 0x06, 0x00, 0x19, 0x00, 0x33, 0x00, 0x9b, 0x00, | ||
11764 | 0xa4, 0x00, 0xb5, 0x00, | ||
11765 | 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, 0xe7, 0x00, 0xde, 0x03, 0x56, 0x0a, | ||
11766 | 0x14, 0x0e, 0x02, 0x10, | ||
11767 | 0x04, 0x10, 0x0a, 0x10, 0x36, 0x10, 0x0a, 0x13, 0x12, 0x13, 0x52, 0x13, | ||
11768 | 0x10, 0x15, 0x14, 0x15, | ||
11769 | 0xac, 0x16, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, 0x08, 0x44, 0x38, 0x44, | ||
11770 | 0x91, 0x44, 0x0a, 0x45, | ||
11771 | 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, 0x83, 0x55, 0xb0, 0x57, 0x01, 0x58, | ||
11772 | 0x83, 0x59, 0x05, 0xe6, | ||
11773 | 0x0b, 0xf0, 0x0c, 0xf0, 0x5c, 0xf0, 0x4b, 0xf4, 0x04, 0xf8, 0x05, 0xf8, | ||
11774 | 0x02, 0xfa, 0x03, 0xfa, | ||
11775 | 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, 0x0a, 0x00, 0x0d, 0x00, 0x1c, 0x00, | ||
11776 | 0x9e, 0x00, 0xa8, 0x00, | ||
11777 | 0xaa, 0x00, 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, | ||
11778 | 0x7a, 0x01, 0xc0, 0x01, | ||
11779 | 0xc2, 0x01, 0x7c, 0x02, 0x5a, 0x03, 0xea, 0x04, 0xe8, 0x07, 0x68, 0x08, | ||
11780 | 0x69, 0x08, 0xba, 0x08, | ||
11781 | 0xe9, 0x09, 0x06, 0x0b, 0x3a, 0x0e, 0x00, 0x10, 0x1a, 0x10, 0xed, 0x10, | ||
11782 | 0xf1, 0x10, 0x06, 0x12, | ||
11783 | 0x0c, 0x13, 0x16, 0x13, 0x1e, 0x13, 0x82, 0x13, 0x42, 0x14, 0xd6, 0x14, | ||
11784 | 0x8a, 0x15, 0xc6, 0x17, | ||
11785 | 0xd2, 0x17, 0x6b, 0x18, 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, | ||
11786 | 0x0e, 0x47, 0x48, 0x47, | ||
11787 | 0x41, 0x48, 0x89, 0x48, 0x80, 0x4c, 0x00, 0x54, 0x44, 0x55, 0xe5, 0x55, | ||
11788 | 0x14, 0x56, 0x77, 0x57, | ||
11789 | 0xbf, 0x57, 0x40, 0x5c, 0x06, 0x80, 0x08, 0x90, 0x03, 0xa1, 0xfe, 0x9c, | ||
11790 | 0xf0, 0x29, 0x02, 0xfe, | ||
11791 | 0xb8, 0x0c, 0xff, 0x10, 0x00, 0x00, 0xd0, 0xfe, 0xcc, 0x18, 0x00, 0xcf, | ||
11792 | 0xfe, 0x80, 0x01, 0xff, | ||
11793 | 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, | ||
11794 | 0x00, 0xfe, 0x57, 0x24, | ||
11795 | 0x00, 0xfe, 0x48, 0x00, 0x4f, 0xff, 0x04, 0x00, 0x00, 0x10, 0xff, 0x09, | ||
11796 | 0x00, 0x00, 0xff, 0x08, | ||
11797 | 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, | ||
11798 | 0xff, 0xff, 0xff, 0x0f, | ||
11799 | 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, | ||
11800 | 0xfe, 0x04, 0xf7, 0xcf, | ||
11801 | 0x2a, 0x67, 0x0b, 0x01, 0xfe, 0xce, 0x0e, 0xfe, 0x04, 0xf7, 0xcf, 0x67, | ||
11802 | 0x0b, 0x3c, 0x2a, 0xfe, | ||
11803 | 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x91, 0xf0, | ||
11804 | 0xfe, 0xf0, 0x01, 0xfe, | ||
11805 | 0x90, 0xf0, 0xfe, 0xf0, 0x01, 0xfe, 0x8f, 0xf0, 0x9c, 0x05, 0x51, 0x3b, | ||
11806 | 0x02, 0xfe, 0xd4, 0x0c, | ||
11807 | 0x01, 0xfe, 0x44, 0x0d, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28, | ||
11808 | 0x1c, 0x05, 0xfe, 0xa6, | ||
11809 | 0x00, 0xfe, 0xd3, 0x12, 0x47, 0x18, 0xfe, 0xa6, 0x00, 0xb5, 0xfe, 0x48, | ||
11810 | 0xf0, 0xfe, 0x86, 0x02, | ||
11811 | 0xfe, 0x49, 0xf0, 0xfe, 0xa0, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xbe, 0x02, | ||
11812 | 0xfe, 0x46, 0xf0, 0xfe, | ||
11813 | 0x50, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x56, 0x02, 0xfe, 0x43, 0xf0, 0xfe, | ||
11814 | 0x44, 0x02, 0xfe, 0x44, | ||
11815 | 0xf0, 0xfe, 0x48, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x4c, 0x02, 0x17, 0x0b, | ||
11816 | 0xa0, 0x17, 0x06, 0x18, | ||
11817 | 0x96, 0x02, 0x29, 0xfe, 0x00, 0x1c, 0xde, 0xfe, 0x02, 0x1c, 0xdd, 0xfe, | ||
11818 | 0x1e, 0x1c, 0xfe, 0xe9, | ||
11819 | 0x10, 0x01, 0xfe, 0x20, 0x17, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xc7, | ||
11820 | 0x0a, 0x6b, 0x01, 0x9e, | ||
11821 | 0x02, 0x29, 0x14, 0x4d, 0x37, 0x97, 0x01, 0xfe, 0x64, 0x0f, 0x0a, 0x6b, | ||
11822 | 0x01, 0x82, 0xfe, 0xbd, | ||
11823 | 0x10, 0x0a, 0x6b, 0x01, 0x82, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, | ||
11824 | 0x58, 0x1c, 0x17, 0x06, | ||
11825 | 0x18, 0x96, 0x2a, 0x25, 0x29, 0xfe, 0x3d, 0xf0, 0xfe, 0x02, 0x02, 0x21, | ||
11826 | 0xfe, 0x94, 0x02, 0xfe, | ||
11827 | 0x5a, 0x1c, 0xea, 0xfe, 0x14, 0x1c, 0x14, 0xfe, 0x30, 0x00, 0x37, 0x97, | ||
11828 | 0x01, 0xfe, 0x54, 0x0f, | ||
11829 | 0x17, 0x06, 0x18, 0x96, 0x02, 0xd0, 0x1e, 0x20, 0x07, 0x10, 0x34, 0xfe, | ||
11830 | 0x69, 0x10, 0x17, 0x06, | ||
11831 | 0x18, 0x96, 0xfe, 0x04, 0xec, 0x20, 0x46, 0x3d, 0x12, 0x20, 0xfe, 0x05, | ||
11832 | 0xf6, 0xc7, 0x01, 0xfe, | ||
11833 | 0x52, 0x16, 0x09, 0x4a, 0x4c, 0x35, 0x11, 0x2d, 0x3c, 0x8a, 0x01, 0xe6, | ||
11834 | 0x02, 0x29, 0x0a, 0x40, | ||
11835 | 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x01, 0x6f, 0xfe, 0x18, 0x10, 0xfe, 0x41, | ||
11836 | 0x58, 0x0a, 0x99, 0x01, | ||
11837 | 0x0e, 0xfe, 0xc8, 0x54, 0x64, 0xfe, 0x0c, 0x03, 0x01, 0xe6, 0x02, 0x29, | ||
11838 | 0x2a, 0x46, 0xfe, 0x02, | ||
11839 | 0xe8, 0x27, 0xf8, 0xfe, 0x9e, 0x43, 0xf7, 0xfe, 0x27, 0xf0, 0xfe, 0xdc, | ||
11840 | 0x01, 0xfe, 0x07, 0x4b, | ||
11841 | 0xfe, 0x20, 0xf0, 0x9c, 0xfe, 0x40, 0x1c, 0x25, 0xd2, 0xfe, 0x26, 0xf0, | ||
11842 | 0xfe, 0x56, 0x03, 0xfe, | ||
11843 | 0xa0, 0xf0, 0xfe, 0x44, 0x03, 0xfe, 0x11, 0xf0, 0x9c, 0xfe, 0xef, 0x10, | ||
11844 | 0xfe, 0x9f, 0xf0, 0xfe, | ||
11845 | 0x64, 0x03, 0xeb, 0x0f, 0xfe, 0x11, 0x00, 0x02, 0x5a, 0x2a, 0xfe, 0x48, | ||
11846 | 0x1c, 0xeb, 0x09, 0x04, | ||
11847 | 0x1d, 0xfe, 0x18, 0x13, 0x23, 0x1e, 0x98, 0xac, 0x12, 0x98, 0x0a, 0x40, | ||
11848 | 0x01, 0x0e, 0xac, 0x75, | ||
11849 | 0x01, 0xfe, 0xbc, 0x15, 0x11, 0xca, 0x25, 0xd2, 0xfe, 0x01, 0xf0, 0xd2, | ||
11850 | 0xfe, 0x82, 0xf0, 0xfe, | ||
11851 | 0x92, 0x03, 0xec, 0x11, 0xfe, 0xe4, 0x00, 0x65, 0xfe, 0xa4, 0x03, 0x25, | ||
11852 | 0x32, 0x1f, 0xfe, 0xb4, | ||
11853 | 0x03, 0x01, 0x43, 0xfe, 0x06, 0xf0, 0xfe, 0xc4, 0x03, 0x8d, 0x81, 0xfe, | ||
11854 | 0x0a, 0xf0, 0xfe, 0x7a, | ||
11855 | 0x06, 0x02, 0x22, 0x05, 0x6b, 0x28, 0x16, 0xfe, 0xf6, 0x04, 0x14, 0x2c, | ||
11856 | 0x01, 0x33, 0x8f, 0xfe, | ||
11857 | 0x66, 0x02, 0x02, 0xd1, 0xeb, 0x2a, 0x67, 0x1a, 0xfe, 0x67, 0x1b, 0xf8, | ||
11858 | 0xf7, 0xfe, 0x48, 0x1c, | ||
11859 | 0x70, 0x01, 0x6e, 0x87, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x16, 0xd3, | ||
11860 | 0x0a, 0xca, 0x01, 0x0e, | ||
11861 | 0x74, 0x60, 0x59, 0x76, 0x27, 0x05, 0x6b, 0x28, 0xfe, 0x10, 0x12, 0x14, | ||
11862 | 0x2c, 0x01, 0x33, 0x8f, | ||
11863 | 0xfe, 0x66, 0x02, 0x02, 0xd1, 0xbc, 0x7d, 0xbd, 0x7f, 0x25, 0x22, 0x65, | ||
11864 | 0xfe, 0x3c, 0x04, 0x1f, | ||
11865 | 0xfe, 0x38, 0x04, 0x68, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, | ||
11866 | 0x12, 0x2b, 0xff, 0x02, | ||
11867 | 0x00, 0x10, 0x01, 0x08, 0x1f, 0xfe, 0xe0, 0x04, 0x2b, 0x01, 0x08, 0x1f, | ||
11868 | 0x22, 0x30, 0x2e, 0xd5, | ||
11869 | 0xfe, 0x4c, 0x44, 0xfe, 0x4c, 0x12, 0x60, 0xfe, 0x44, 0x48, 0x13, 0x2c, | ||
11870 | 0xfe, 0x4c, 0x54, 0x64, | ||
11871 | 0xd3, 0x46, 0x76, 0x27, 0xfa, 0xef, 0xfe, 0x62, 0x13, 0x09, 0x04, 0x1d, | ||
11872 | 0xfe, 0x2a, 0x13, 0x2f, | ||
11873 | 0x07, 0x7e, 0xa5, 0xfe, 0x20, 0x10, 0x13, 0x2c, 0xfe, 0x4c, 0x54, 0x64, | ||
11874 | 0xd3, 0xfa, 0xef, 0x86, | ||
11875 | 0x09, 0x04, 0x1d, 0xfe, 0x08, 0x13, 0x2f, 0x07, 0x7e, 0x6e, 0x09, 0x04, | ||
11876 | 0x1d, 0xfe, 0x1c, 0x12, | ||
11877 | 0x14, 0x92, 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, | ||
11878 | 0x70, 0x0c, 0x02, 0x22, | ||
11879 | 0x2b, 0x11, 0xfe, 0xe6, 0x00, 0xfe, 0x1c, 0x90, 0xf9, 0x03, 0x14, 0x92, | ||
11880 | 0x01, 0x33, 0x02, 0x29, | ||
11881 | 0xfe, 0x42, 0x5b, 0x67, 0x1a, 0xfe, 0x46, 0x59, 0xf8, 0xf7, 0xfe, 0x87, | ||
11882 | 0x80, 0xfe, 0x31, 0xe4, | ||
11883 | 0x4f, 0x09, 0x04, 0x0b, 0xfe, 0x78, 0x13, 0xfe, 0x20, 0x80, 0x07, 0x1a, | ||
11884 | 0xfe, 0x70, 0x12, 0x49, | ||
11885 | 0x04, 0x06, 0xfe, 0x60, 0x13, 0x05, 0xfe, 0xa2, 0x00, 0x28, 0x16, 0xfe, | ||
11886 | 0x80, 0x05, 0xfe, 0x31, | ||
11887 | 0xe4, 0x6a, 0x49, 0x04, 0x0b, 0xfe, 0x4a, 0x13, 0x05, 0xfe, 0xa0, 0x00, | ||
11888 | 0x28, 0xfe, 0x42, 0x12, | ||
11889 | 0x5e, 0x01, 0x08, 0x25, 0x32, 0xf1, 0x01, 0x08, 0x26, 0xfe, 0x98, 0x05, | ||
11890 | 0x11, 0xfe, 0xe3, 0x00, | ||
11891 | 0x23, 0x49, 0xfe, 0x4a, 0xf0, 0xfe, 0x6a, 0x05, 0xfe, 0x49, 0xf0, 0xfe, | ||
11892 | 0x64, 0x05, 0x83, 0x24, | ||
11893 | 0xfe, 0x21, 0x00, 0xa1, 0x24, 0xfe, 0x22, 0x00, 0xa0, 0x24, 0x4c, 0xfe, | ||
11894 | 0x09, 0x48, 0x01, 0x08, | ||
11895 | 0x26, 0xfe, 0x98, 0x05, 0xfe, 0xe2, 0x08, 0x49, 0x04, 0xc5, 0x3b, 0x01, | ||
11896 | 0x86, 0x24, 0x06, 0x12, | ||
11897 | 0xcc, 0x37, 0xfe, 0x27, 0x01, 0x09, 0x04, 0x1d, 0xfe, 0x22, 0x12, 0x47, | ||
11898 | 0x01, 0xa7, 0x14, 0x92, | ||
11899 | 0x09, 0x04, 0x06, 0x3b, 0x14, 0xc4, 0x01, 0x33, 0x8f, 0xfe, 0x70, 0x0c, | ||
11900 | 0x02, 0x22, 0x05, 0xfe, | ||
11901 | 0x9c, 0x00, 0x28, 0xfe, 0x3e, 0x12, 0x05, 0x50, 0x28, 0xfe, 0x36, 0x13, | ||
11902 | 0x47, 0x01, 0xa7, 0x26, | ||
11903 | 0xfe, 0x08, 0x06, 0x0a, 0x06, 0x49, 0x04, 0x19, 0xfe, 0x02, 0x12, 0x5f, | ||
11904 | 0x01, 0xfe, 0xaa, 0x14, | ||
11905 | 0x1f, 0xfe, 0xfe, 0x05, 0x11, 0x9a, 0x01, 0x43, 0x11, 0xfe, 0xe5, 0x00, | ||
11906 | 0x05, 0x50, 0xb4, 0x0c, | ||
11907 | 0x50, 0x05, 0xc6, 0x28, 0xfe, 0x62, 0x12, 0x05, 0x3f, 0x28, 0xfe, 0x5a, | ||
11908 | 0x13, 0x01, 0xfe, 0x14, | ||
11909 | 0x18, 0x01, 0xfe, 0x66, 0x18, 0xfe, 0x43, 0x48, 0xb7, 0x19, 0x13, 0x6c, | ||
11910 | 0xff, 0x02, 0x00, 0x57, | ||
11911 | 0x48, 0x8b, 0x1c, 0x3d, 0x85, 0xb7, 0x69, 0x47, 0x01, 0xa7, 0x26, 0xfe, | ||
11912 | 0x72, 0x06, 0x49, 0x04, | ||
11913 | 0x1b, 0xdf, 0x89, 0x0a, 0x4d, 0x01, 0xfe, 0xd8, 0x14, 0x1f, 0xfe, 0x68, | ||
11914 | 0x06, 0x11, 0x9a, 0x01, | ||
11915 | 0x43, 0x11, 0xfe, 0xe5, 0x00, 0x05, 0x3f, 0xb4, 0x0c, 0x3f, 0x17, 0x06, | ||
11916 | 0x01, 0xa7, 0xec, 0x72, | ||
11917 | 0x70, 0x01, 0x6e, 0x87, 0x11, 0xfe, 0xe2, 0x00, 0x01, 0x08, 0x25, 0x32, | ||
11918 | 0xfe, 0x0a, 0xf0, 0xfe, | ||
11919 | 0xa6, 0x06, 0x8c, 0xfe, 0x5c, 0x07, 0xfe, 0x06, 0xf0, 0xfe, 0x64, 0x07, | ||
11920 | 0x8d, 0x81, 0x02, 0x22, | ||
11921 | 0x09, 0x04, 0x0b, 0xfe, 0x2e, 0x12, 0x15, 0x1a, 0x01, 0x08, 0x15, 0x00, | ||
11922 | 0x01, 0x08, 0x15, 0x00, | ||
11923 | 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, 0x15, | ||
11924 | 0x00, 0x02, 0xfe, 0x32, | ||
11925 | 0x08, 0x61, 0x04, 0x1b, 0xfe, 0x38, 0x12, 0x09, 0x04, 0x1b, 0x6e, 0x15, | ||
11926 | 0xfe, 0x1b, 0x00, 0x01, | ||
11927 | 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, 0x08, 0x15, 0x00, 0x01, | ||
11928 | 0x08, 0x15, 0x06, 0x01, | ||
11929 | 0x08, 0x15, 0x00, 0x02, 0xd9, 0x66, 0x4c, 0xfe, 0x3a, 0x55, 0x5f, 0xfe, | ||
11930 | 0x9a, 0x81, 0x4b, 0x1d, | ||
11931 | 0xba, 0xfe, 0x32, 0x07, 0x0a, 0x1d, 0xfe, 0x09, 0x6f, 0xaf, 0xfe, 0xca, | ||
11932 | 0x45, 0xfe, 0x32, 0x12, | ||
11933 | 0x62, 0x2c, 0x85, 0x66, 0x7b, 0x01, 0x08, 0x25, 0x32, 0xfe, 0x0a, 0xf0, | ||
11934 | 0xfe, 0x32, 0x07, 0x8d, | ||
11935 | 0x81, 0x8c, 0xfe, 0x5c, 0x07, 0x02, 0x22, 0x01, 0x43, 0x02, 0xfe, 0x8a, | ||
11936 | 0x06, 0x15, 0x19, 0x02, | ||
11937 | 0xfe, 0x8a, 0x06, 0xfe, 0x9c, 0xf7, 0xd4, 0xfe, 0x2c, 0x90, 0xfe, 0xae, | ||
11938 | 0x90, 0x77, 0xfe, 0xca, | ||
11939 | 0x07, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x4a, 0x6a, 0x35, 0x1e, 0x20, 0x07, | ||
11940 | 0x10, 0xfe, 0x0e, 0x12, | ||
11941 | 0x74, 0xfe, 0x80, 0x80, 0x37, 0x20, 0x63, 0x27, 0xfe, 0x06, 0x10, 0xfe, | ||
11942 | 0x83, 0xe7, 0xc4, 0xa1, | ||
11943 | 0xfe, 0x03, 0x40, 0x09, 0x4a, 0x4f, 0x35, 0x01, 0xa8, 0xad, 0xfe, 0x1f, | ||
11944 | 0x40, 0x12, 0x58, 0x01, | ||
11945 | 0xa5, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, | ||
11946 | 0x51, 0x83, 0xfb, 0xfe, | ||
11947 | 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x0c, 0x90, 0xfe, 0x8e, 0x90, | ||
11948 | 0xfe, 0x40, 0x50, 0xfe, | ||
11949 | 0xc2, 0x50, 0x0c, 0x39, 0x18, 0x3a, 0xfe, 0x4a, 0x10, 0x09, 0x04, 0x6a, | ||
11950 | 0xfe, 0x2a, 0x12, 0xfe, | ||
11951 | 0x2c, 0x90, 0xfe, 0xae, 0x90, 0x0c, 0x54, 0x18, 0x55, 0x09, 0x04, 0x4f, | ||
11952 | 0x85, 0x01, 0xa8, 0xfe, | ||
11953 | 0x1f, 0x80, 0x12, 0x58, 0xfe, 0x44, 0x90, 0xfe, 0xc6, 0x90, 0x0c, 0x56, | ||
11954 | 0x18, 0x57, 0xfb, 0xfe, | ||
11955 | 0x8a, 0x90, 0x0c, 0x52, 0x18, 0x53, 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, | ||
11956 | 0x0c, 0x39, 0x18, 0x3a, | ||
11957 | 0x0c, 0x38, 0x18, 0x4e, 0x09, 0x4a, 0x19, 0x35, 0x2a, 0x13, 0xfe, 0x4e, | ||
11958 | 0x11, 0x65, 0xfe, 0x48, | ||
11959 | 0x08, 0xfe, 0x9e, 0xf0, 0xfe, 0x5c, 0x08, 0xb1, 0x16, 0x32, 0x2a, 0x73, | ||
11960 | 0xdd, 0xb8, 0xfe, 0x80, | ||
11961 | 0x08, 0xb9, 0xfe, 0x9e, 0x08, 0x8c, 0xfe, 0x74, 0x08, 0xfe, 0x06, 0xf0, | ||
11962 | 0xfe, 0x7a, 0x08, 0x8d, | ||
11963 | 0x81, 0x02, 0x22, 0x01, 0x43, 0xfe, 0xc9, 0x10, 0x15, 0x19, 0xfe, 0xc9, | ||
11964 | 0x10, 0x61, 0x04, 0x06, | ||
11965 | 0xfe, 0x10, 0x12, 0x61, 0x04, 0x0b, 0x45, 0x09, 0x04, 0x0b, 0xfe, 0x68, | ||
11966 | 0x12, 0xfe, 0x2e, 0x1c, | ||
11967 | 0x02, 0xfe, 0x24, 0x0a, 0x61, 0x04, 0x06, 0x45, 0x61, 0x04, 0x0b, 0xfe, | ||
11968 | 0x52, 0x12, 0xfe, 0x2c, | ||
11969 | 0x1c, 0xfe, 0xaa, 0xf0, 0xfe, 0x1e, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0xbe, | ||
11970 | 0x08, 0xfe, 0x8a, 0x10, | ||
11971 | 0xaa, 0xfe, 0xf3, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0xca, 0x08, 0x02, 0xfe, | ||
11972 | 0x24, 0x0a, 0xab, 0xfe, | ||
11973 | 0xe7, 0x10, 0xfe, 0x2b, 0xf0, 0x9d, 0xe9, 0x1c, 0xfe, 0x00, 0xfe, 0xfe, | ||
11974 | 0x1c, 0x12, 0xb5, 0xfe, | ||
11975 | 0xd2, 0xf0, 0x9d, 0xfe, 0x76, 0x18, 0x1c, 0x1a, 0x16, 0x9d, 0x05, 0xcb, | ||
11976 | 0x1c, 0x06, 0x16, 0x9d, | ||
11977 | 0xb8, 0x6d, 0xb9, 0x6d, 0xaa, 0xab, 0xfe, 0xb1, 0x10, 0x70, 0x5e, 0x2b, | ||
11978 | 0x14, 0x92, 0x01, 0x33, | ||
11979 | 0x0f, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x5a, 0x0f, 0x7c, 0x02, 0x5a, | ||
11980 | 0xfe, 0x74, 0x18, 0x1c, | ||
11981 | 0xfe, 0x00, 0xf8, 0x16, 0x6d, 0x67, 0x1b, 0x01, 0xfe, 0x44, 0x0d, 0x3b, | ||
11982 | 0x01, 0xe6, 0x1e, 0x27, | ||
11983 | 0x74, 0x67, 0x1a, 0x02, 0x6d, 0x09, 0x04, 0x0b, 0x21, 0xfe, 0x06, 0x0a, | ||
11984 | 0x09, 0x04, 0x6a, 0xfe, | ||
11985 | 0x82, 0x12, 0x09, 0x04, 0x19, 0xfe, 0x66, 0x13, 0x1e, 0x58, 0xac, 0xfc, | ||
11986 | 0xfe, 0x83, 0x80, 0xfe, | ||
11987 | 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, 0xfe, 0x86, 0x91, 0x63, | ||
11988 | 0x27, 0xfe, 0x40, 0x59, | ||
11989 | 0xfe, 0xc1, 0x59, 0x77, 0xd7, 0x05, 0x54, 0x31, 0x55, 0x0c, 0x7b, 0x18, | ||
11990 | 0x7c, 0xbe, 0x54, 0xbf, | ||
11991 | 0x55, 0x01, 0xa8, 0xad, 0x63, 0x27, 0x12, 0x58, 0xc0, 0x38, 0xc1, 0x4e, | ||
11992 | 0x79, 0x56, 0x68, 0x57, | ||
11993 | 0xf4, 0xf5, 0xfe, 0x04, 0xfa, 0x38, 0xfe, 0x05, 0xfa, 0x4e, 0x01, 0xa5, | ||
11994 | 0xa2, 0x23, 0x0c, 0x7b, | ||
11995 | 0x0c, 0x7c, 0x79, 0x56, 0x68, 0x57, 0xfe, 0x12, 0x10, 0x09, 0x04, 0x19, | ||
11996 | 0x16, 0xd7, 0x79, 0x39, | ||
11997 | 0x68, 0x3a, 0x09, 0x04, 0xfe, 0xf7, 0x00, 0x35, 0x05, 0x52, 0x31, 0x53, | ||
11998 | 0xfe, 0x10, 0x58, 0xfe, | ||
11999 | 0x91, 0x58, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x02, 0x6d, 0x09, 0x04, | ||
12000 | 0x19, 0x16, 0xd7, 0x09, | ||
12001 | 0x04, 0xfe, 0xf7, 0x00, 0x35, 0xfe, 0x3a, 0x55, 0xfe, 0x19, 0x81, 0x5f, | ||
12002 | 0xfe, 0x10, 0x90, 0xfe, | ||
12003 | 0x92, 0x90, 0xfe, 0xd7, 0x10, 0x2f, 0x07, 0x9b, 0x16, 0xfe, 0xc6, 0x08, | ||
12004 | 0x11, 0x9b, 0x09, 0x04, | ||
12005 | 0x0b, 0xfe, 0x14, 0x13, 0x05, 0x39, 0x31, 0x3a, 0x77, 0xfe, 0xc6, 0x08, | ||
12006 | 0xfe, 0x0c, 0x58, 0xfe, | ||
12007 | 0x8d, 0x58, 0x02, 0x6d, 0x23, 0x47, 0xfe, 0x19, 0x80, 0xde, 0x09, 0x04, | ||
12008 | 0x0b, 0xfe, 0x1a, 0x12, | ||
12009 | 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xe9, 0xb5, 0xfe, 0xd1, 0xf0, 0xd9, | ||
12010 | 0x14, 0x7a, 0x01, 0x33, | ||
12011 | 0x0f, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, 0xbe, 0x39, | ||
12012 | 0xfe, 0xed, 0x19, 0xbf, | ||
12013 | 0x3a, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xe9, 0x1c, 0xfe, 0x00, 0xff, | ||
12014 | 0x34, 0xfe, 0x74, 0x10, | ||
12015 | 0xb5, 0xfe, 0xd2, 0xf0, 0xfe, 0xb2, 0x0a, 0xfe, 0x76, 0x18, 0x1c, 0x1a, | ||
12016 | 0x84, 0x05, 0xcb, 0x1c, | ||
12017 | 0x06, 0xfe, 0x08, 0x13, 0x0f, 0xfe, 0x16, 0x00, 0x02, 0x5a, 0xfe, 0xd1, | ||
12018 | 0xf0, 0xfe, 0xc4, 0x0a, | ||
12019 | 0x14, 0x7a, 0x01, 0x33, 0x0f, 0xfe, 0x17, 0x00, 0xfe, 0x42, 0x10, 0xfe, | ||
12020 | 0xce, 0xf0, 0xfe, 0xca, | ||
12021 | 0x0a, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xd6, 0x0a, 0x0f, 0xfe, | ||
12022 | 0x22, 0x00, 0x02, 0x5a, | ||
12023 | 0xfe, 0xcb, 0xf0, 0xfe, 0xe2, 0x0a, 0x0f, 0xfe, 0x24, 0x00, 0x02, 0x5a, | ||
12024 | 0xfe, 0xd0, 0xf0, 0xfe, | ||
12025 | 0xec, 0x0a, 0x0f, 0x93, 0xdc, 0xfe, 0xcf, 0xf0, 0xfe, 0xf6, 0x0a, 0x0f, | ||
12026 | 0x4c, 0xfe, 0x10, 0x10, | ||
12027 | 0xfe, 0xcc, 0xf0, 0xd9, 0x61, 0x04, 0x19, 0x3b, 0x0f, 0xfe, 0x12, 0x00, | ||
12028 | 0x2a, 0x13, 0xfe, 0x4e, | ||
12029 | 0x11, 0x65, 0xfe, 0x0c, 0x0b, 0xfe, 0x9e, 0xf0, 0xfe, 0x20, 0x0b, 0xb1, | ||
12030 | 0x16, 0x32, 0x2a, 0x73, | ||
12031 | 0xdd, 0xb8, 0x22, 0xb9, 0x22, 0x2a, 0xec, 0x65, 0xfe, 0x2c, 0x0b, 0x25, | ||
12032 | 0x32, 0x8c, 0xfe, 0x48, | ||
12033 | 0x0b, 0x8d, 0x81, 0xb8, 0xd4, 0xb9, 0xd4, 0x02, 0x22, 0x01, 0x43, 0xfe, | ||
12034 | 0xdb, 0x10, 0x11, 0xfe, | ||
12035 | 0xe8, 0x00, 0xaa, 0xab, 0x70, 0xbc, 0x7d, 0xbd, 0x7f, 0xfe, 0x89, 0xf0, | ||
12036 | 0x22, 0x30, 0x2e, 0xd8, | ||
12037 | 0xbc, 0x7d, 0xbd, 0x7f, 0x01, 0x08, 0x1f, 0x22, 0x30, 0x2e, 0xd6, 0xb1, | ||
12038 | 0x45, 0x0f, 0xfe, 0x42, | ||
12039 | 0x00, 0x02, 0x5a, 0x78, 0x06, 0xfe, 0x81, 0x49, 0x16, 0xfe, 0x38, 0x0c, | ||
12040 | 0x09, 0x04, 0x0b, 0xfe, | ||
12041 | 0x44, 0x13, 0x0f, 0x00, 0x4b, 0x0b, 0xfe, 0x54, 0x12, 0x4b, 0xfe, 0x28, | ||
12042 | 0x00, 0x21, 0xfe, 0xa6, | ||
12043 | 0x0c, 0x0a, 0x40, 0x01, 0x0e, 0x07, 0x00, 0x5d, 0x3e, 0xfe, 0x28, 0x00, | ||
12044 | 0xfe, 0xe2, 0x10, 0x01, | ||
12045 | 0xe7, 0x01, 0xe8, 0x0a, 0x99, 0x01, 0xfe, 0x32, 0x0e, 0x59, 0x11, 0x2d, | ||
12046 | 0x01, 0x6f, 0x02, 0x29, | ||
12047 | 0x0f, 0xfe, 0x44, 0x00, 0x4b, 0x0b, 0xdf, 0x3e, 0x0b, 0xfe, 0xb4, 0x10, | ||
12048 | 0x01, 0x86, 0x3e, 0x0b, | ||
12049 | 0xfe, 0xaa, 0x10, 0x01, 0x86, 0xfe, 0x19, 0x82, 0xfe, 0x34, 0x46, 0xa3, | ||
12050 | 0x3e, 0x0b, 0x0f, 0xfe, | ||
12051 | 0x43, 0x00, 0xfe, 0x96, 0x10, 0x09, 0x4a, 0x0b, 0x35, 0x01, 0xe7, 0x01, | ||
12052 | 0xe8, 0x59, 0x11, 0x2d, | ||
12053 | 0x01, 0x6f, 0x67, 0x0b, 0x59, 0x3c, 0x8a, 0x02, 0xfe, 0x2a, 0x03, 0x09, | ||
12054 | 0x04, 0x0b, 0x84, 0x3e, | ||
12055 | 0x0b, 0x0f, 0x00, 0xfe, 0x5c, 0x10, 0x61, 0x04, 0x1b, 0xfe, 0x58, 0x12, | ||
12056 | 0x09, 0x04, 0x1b, 0xfe, | ||
12057 | 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x5c, 0x0c, 0xfe, | ||
12058 | 0x1c, 0x1c, 0xfe, 0x9d, | ||
12059 | 0xf0, 0xfe, 0x62, 0x0c, 0x09, 0x4a, 0x1b, 0x35, 0xfe, 0xa9, 0x10, 0x0f, | ||
12060 | 0xfe, 0x15, 0x00, 0xfe, | ||
12061 | 0x04, 0xe6, 0x0b, 0x5f, 0x5c, 0x0f, 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, | ||
12062 | 0x0f, 0xfe, 0x47, 0x00, | ||
12063 | 0xa1, 0x0f, 0xfe, 0x41, 0x00, 0xa0, 0x0f, 0xfe, 0x24, 0x00, 0x87, 0xaa, | ||
12064 | 0xab, 0x70, 0x05, 0x6b, | ||
12065 | 0x28, 0x21, 0xd1, 0x5f, 0xfe, 0x04, 0xe6, 0x1b, 0xfe, 0x9d, 0x41, 0xfe, | ||
12066 | 0x1c, 0x42, 0x59, 0x01, | ||
12067 | 0xda, 0x02, 0x29, 0xea, 0x14, 0x0b, 0x37, 0x95, 0xa9, 0x14, 0xfe, 0x31, | ||
12068 | 0x00, 0x37, 0x97, 0x01, | ||
12069 | 0xfe, 0x54, 0x0f, 0x02, 0xd0, 0x3c, 0xfe, 0x06, 0xec, 0xc9, 0xee, 0x3e, | ||
12070 | 0x1d, 0xfe, 0xce, 0x45, | ||
12071 | 0x34, 0x3c, 0xfe, 0x06, 0xea, 0xc9, 0xfe, 0x47, 0x4b, 0x89, 0xfe, 0x75, | ||
12072 | 0x57, 0x05, 0x51, 0xfe, | ||
12073 | 0x98, 0x56, 0xfe, 0x38, 0x12, 0x0a, 0x42, 0x01, 0x0e, 0xfe, 0x44, 0x48, | ||
12074 | 0x46, 0x09, 0x04, 0x1d, | ||
12075 | 0xfe, 0x1a, 0x13, 0x0a, 0x40, 0x01, 0x0e, 0x47, 0xfe, 0x41, 0x58, 0x0a, | ||
12076 | 0x99, 0x01, 0x0e, 0xfe, | ||
12077 | 0x49, 0x54, 0x8e, 0xfe, 0x2a, 0x0d, 0x02, 0xfe, 0x2a, 0x03, 0x0a, 0x51, | ||
12078 | 0xfe, 0xee, 0x14, 0xee, | ||
12079 | 0x3e, 0x1d, 0xfe, 0xce, 0x45, 0x34, 0x3c, 0xfe, 0xce, 0x47, 0xfe, 0xad, | ||
12080 | 0x13, 0x02, 0x29, 0x1e, | ||
12081 | 0x20, 0x07, 0x10, 0xfe, 0x9e, 0x12, 0x23, 0x12, 0x4d, 0x12, 0x94, 0x12, | ||
12082 | 0xce, 0x1e, 0x2d, 0x47, | ||
12083 | 0x37, 0x2d, 0xb1, 0xe0, 0xfe, 0xbc, 0xf0, 0xfe, 0xec, 0x0d, 0x13, 0x06, | ||
12084 | 0x12, 0x4d, 0x01, 0xfe, | ||
12085 | 0xe2, 0x15, 0x05, 0xfe, 0x38, 0x01, 0x31, 0xfe, 0x3a, 0x01, 0x77, 0xfe, | ||
12086 | 0xf0, 0x0d, 0xfe, 0x02, | ||
12087 | 0xec, 0xce, 0x62, 0x00, 0x5d, 0xfe, 0x04, 0xec, 0x20, 0x46, 0xfe, 0x05, | ||
12088 | 0xf6, 0xfe, 0x34, 0x01, | ||
12089 | 0x01, 0xfe, 0x52, 0x16, 0xfb, 0xfe, 0x48, 0xf4, 0x0d, 0xfe, 0x18, 0x13, | ||
12090 | 0xaf, 0xfe, 0x02, 0xea, | ||
12091 | 0xce, 0x62, 0x7a, 0xfe, 0xc5, 0x13, 0x14, 0x1b, 0x37, 0x95, 0xa9, 0x5c, | ||
12092 | 0x05, 0xfe, 0x38, 0x01, | ||
12093 | 0x1c, 0xfe, 0xf0, 0xff, 0x0c, 0xfe, 0x60, 0x01, 0x05, 0xfe, 0x3a, 0x01, | ||
12094 | 0x0c, 0xfe, 0x62, 0x01, | ||
12095 | 0x3d, 0x12, 0x20, 0x24, 0x06, 0x12, 0x2d, 0x11, 0x2d, 0x8a, 0x13, 0x06, | ||
12096 | 0x03, 0x23, 0x03, 0x1e, | ||
12097 | 0x4d, 0xfe, 0xf7, 0x12, 0x1e, 0x94, 0xac, 0x12, 0x94, 0x07, 0x7a, 0xfe, | ||
12098 | 0x71, 0x13, 0xfe, 0x24, | ||
12099 | 0x1c, 0x14, 0x1a, 0x37, 0x95, 0xa9, 0xfe, 0xd9, 0x10, 0xb6, 0xfe, 0x03, | ||
12100 | 0xdc, 0xfe, 0x73, 0x57, | ||
12101 | 0xfe, 0x80, 0x5d, 0x03, 0xb6, 0xfe, 0x03, 0xdc, 0xfe, 0x5b, 0x57, 0xfe, | ||
12102 | 0x80, 0x5d, 0x03, 0xfe, | ||
12103 | 0x03, 0x57, 0xb6, 0x23, 0xfe, 0x00, 0xcc, 0x03, 0xfe, 0x03, 0x57, 0xb6, | ||
12104 | 0x75, 0x03, 0x09, 0x04, | ||
12105 | 0x4c, 0xfe, 0x22, 0x13, 0xfe, 0x1c, 0x80, 0x07, 0x06, 0xfe, 0x1a, 0x13, | ||
12106 | 0xfe, 0x1e, 0x80, 0xe1, | ||
12107 | 0xfe, 0x1d, 0x80, 0xa4, 0xfe, 0x0c, 0x90, 0xfe, 0x0e, 0x13, 0xfe, 0x0e, | ||
12108 | 0x90, 0xa3, 0xfe, 0x3c, | ||
12109 | 0x90, 0xfe, 0x30, 0xf4, 0x0b, 0xfe, 0x3c, 0x50, 0xa0, 0x01, 0xfe, 0x82, | ||
12110 | 0x16, 0x2f, 0x07, 0x2d, | ||
12111 | 0xe0, 0x01, 0xfe, 0xbc, 0x15, 0x09, 0x04, 0x1d, 0x45, 0x01, 0xe7, 0x01, | ||
12112 | 0xe8, 0x11, 0xfe, 0xe9, | ||
12113 | 0x00, 0x09, 0x04, 0x4c, 0xfe, 0x2c, 0x13, 0x01, 0xfe, 0x14, 0x16, 0xfe, | ||
12114 | 0x1e, 0x1c, 0xfe, 0x14, | ||
12115 | 0x90, 0xfe, 0x96, 0x90, 0x0c, 0xfe, 0x64, 0x01, 0x18, 0xfe, 0x66, 0x01, | ||
12116 | 0x09, 0x04, 0x4f, 0xfe, | ||
12117 | 0x12, 0x12, 0xfe, 0x03, 0x80, 0x74, 0xfe, 0x01, 0xec, 0x20, 0xfe, 0x80, | ||
12118 | 0x40, 0x12, 0x20, 0x63, | ||
12119 | 0x27, 0x11, 0xc8, 0x59, 0x1e, 0x20, 0xed, 0x76, 0x20, 0x03, 0xfe, 0x08, | ||
12120 | 0x1c, 0x05, 0xfe, 0xac, | ||
12121 | 0x00, 0xfe, 0x06, 0x58, 0x05, 0xfe, 0xae, 0x00, 0xfe, 0x07, 0x58, 0x05, | ||
12122 | 0xfe, 0xb0, 0x00, 0xfe, | ||
12123 | 0x08, 0x58, 0x05, 0xfe, 0xb2, 0x00, 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, | ||
12124 | 0x24, 0x69, 0x12, 0xc9, | ||
12125 | 0x23, 0x0c, 0x50, 0x0c, 0x3f, 0x13, 0x40, 0x48, 0x5f, 0x17, 0x1d, 0xfe, | ||
12126 | 0x90, 0x4d, 0xfe, 0x91, | ||
12127 | 0x54, 0x21, 0xfe, 0x08, 0x0f, 0x3e, 0x10, 0x13, 0x42, 0x48, 0x17, 0x4c, | ||
12128 | 0xfe, 0x90, 0x4d, 0xfe, | ||
12129 | 0x91, 0x54, 0x21, 0xfe, 0x1e, 0x0f, 0x24, 0x10, 0x12, 0x20, 0x78, 0x2c, | ||
12130 | 0x46, 0x1e, 0x20, 0xed, | ||
12131 | 0x76, 0x20, 0x11, 0xc8, 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x32, 0x0f, 0xea, | ||
12132 | 0x70, 0xfe, 0x14, 0x1c, | ||
12133 | 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x03, 0x3c, 0xfe, 0x0c, 0x14, 0xee, | ||
12134 | 0xfe, 0x07, 0xe6, 0x1d, | ||
12135 | 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x03, 0x01, 0x86, 0x78, 0x2c, 0x46, | ||
12136 | 0xfa, 0xef, 0xfe, 0x42, | ||
12137 | 0x13, 0x2f, 0x07, 0x2d, 0xfe, 0x34, 0x13, 0x0a, 0x42, 0x01, 0x0e, 0xb0, | ||
12138 | 0xfe, 0x36, 0x12, 0xf0, | ||
12139 | 0xfe, 0x45, 0x48, 0x01, 0xe3, 0xfe, 0x00, 0xcc, 0xb0, 0xfe, 0xf3, 0x13, | ||
12140 | 0x3d, 0x75, 0x07, 0x10, | ||
12141 | 0xa3, 0x0a, 0x80, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x6f, 0xfe, 0x0e, | ||
12142 | 0x10, 0x07, 0x7e, 0x45, | ||
12143 | 0xf6, 0xfe, 0xd6, 0xf0, 0xfe, 0x6c, 0x0f, 0x03, 0xfe, 0x44, 0x58, 0x74, | ||
12144 | 0xfe, 0x01, 0xec, 0x97, | ||
12145 | 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1b, 0x76, | ||
12146 | 0x27, 0x01, 0xda, 0xfe, | ||
12147 | 0xdd, 0x10, 0x2a, 0xbc, 0x7d, 0xbd, 0x7f, 0x30, 0x2e, 0xd5, 0x07, 0x1b, | ||
12148 | 0xfe, 0x48, 0x12, 0x07, | ||
12149 | 0x0b, 0xfe, 0x56, 0x12, 0x07, 0x1a, 0xfe, 0x30, 0x12, 0x07, 0xc2, 0x16, | ||
12150 | 0xfe, 0x3e, 0x11, 0x07, | ||
12151 | 0xfe, 0x23, 0x00, 0x16, 0xfe, 0x4a, 0x11, 0x07, 0x06, 0x16, 0xfe, 0xa8, | ||
12152 | 0x11, 0x07, 0x19, 0xfe, | ||
12153 | 0x12, 0x12, 0x07, 0x00, 0x16, 0x22, 0x14, 0xc2, 0x01, 0x33, 0x9f, 0x2b, | ||
12154 | 0x01, 0x08, 0x8c, 0x43, | ||
12155 | 0x03, 0x2b, 0xfe, 0x62, 0x08, 0x0a, 0xca, 0x01, 0xfe, 0x32, 0x0e, 0x11, | ||
12156 | 0x7e, 0x02, 0x29, 0x2b, | ||
12157 | 0x2f, 0x07, 0x9b, 0xfe, 0xd9, 0x13, 0x79, 0x39, 0x68, 0x3a, 0x77, 0xfe, | ||
12158 | 0xfc, 0x10, 0x09, 0x04, | ||
12159 | 0x6a, 0xfe, 0x72, 0x12, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x8e, 0xfe, | ||
12160 | 0xc6, 0x10, 0x1e, 0x58, | ||
12161 | 0xfe, 0x26, 0x13, 0x05, 0x7b, 0x31, 0x7c, 0x77, 0xfe, 0x82, 0x0c, 0x0c, | ||
12162 | 0x54, 0x18, 0x55, 0x23, | ||
12163 | 0x0c, 0x7b, 0x0c, 0x7c, 0x01, 0xa8, 0x24, 0x69, 0x73, 0x12, 0x58, 0x01, | ||
12164 | 0xa5, 0xc0, 0x38, 0xc1, | ||
12165 | 0x4e, 0xfe, 0x04, 0x55, 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x38, 0xfe, | ||
12166 | 0x05, 0xfa, 0x4e, 0xfe, | ||
12167 | 0x91, 0x10, 0x05, 0x56, 0x31, 0x57, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, | ||
12168 | 0x0c, 0x56, 0x18, 0x57, | ||
12169 | 0x83, 0xc0, 0x38, 0xc1, 0x4e, 0xf4, 0xf5, 0x05, 0x52, 0x31, 0x53, 0xfe, | ||
12170 | 0x00, 0x56, 0xfe, 0xa1, | ||
12171 | 0x56, 0x0c, 0x52, 0x18, 0x53, 0x09, 0x04, 0x6a, 0xfe, 0x1e, 0x12, 0x1e, | ||
12172 | 0x58, 0xfe, 0x1f, 0x40, | ||
12173 | 0x05, 0x54, 0x31, 0x55, 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x05, 0x56, | ||
12174 | 0x31, 0x57, 0xfe, 0x44, | ||
12175 | 0x50, 0xfe, 0xc6, 0x50, 0x05, 0x52, 0x31, 0x53, 0xfe, 0x08, 0x50, 0xfe, | ||
12176 | 0x8a, 0x50, 0x05, 0x39, | ||
12177 | 0x31, 0x3a, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x5c, 0x24, 0x06, | ||
12178 | 0x12, 0xcd, 0x02, 0x5b, | ||
12179 | 0x2b, 0x01, 0x08, 0x1f, 0x44, 0x30, 0x2e, 0xd5, 0x07, 0x06, 0x21, 0x44, | ||
12180 | 0x2f, 0x07, 0x9b, 0x21, | ||
12181 | 0x5b, 0x01, 0x6e, 0x1c, 0x3d, 0x16, 0x44, 0x09, 0x04, 0x0b, 0xe2, 0x79, | ||
12182 | 0x39, 0x68, 0x3a, 0xfe, | ||
12183 | 0x0a, 0x55, 0x34, 0xfe, 0x8b, 0x55, 0xbe, 0x39, 0xbf, 0x3a, 0xfe, 0x0c, | ||
12184 | 0x51, 0xfe, 0x8e, 0x51, | ||
12185 | 0x02, 0x5b, 0xfe, 0x19, 0x81, 0xaf, 0xfe, 0x19, 0x41, 0x02, 0x5b, 0x2b, | ||
12186 | 0x01, 0x08, 0x25, 0x32, | ||
12187 | 0x1f, 0xa2, 0x30, 0x2e, 0xd8, 0x4b, 0x1a, 0xfe, 0xa6, 0x12, 0x4b, 0x0b, | ||
12188 | 0x3b, 0x02, 0x44, 0x01, | ||
12189 | 0x08, 0x25, 0x32, 0x1f, 0xa2, 0x30, 0x2e, 0xd6, 0x07, 0x1a, 0x21, 0x44, | ||
12190 | 0x01, 0x08, 0x1f, 0xa2, | ||
12191 | 0x30, 0x2e, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x60, 0x05, 0xfe, 0x9c, | ||
12192 | 0x00, 0x28, 0x84, 0x49, | ||
12193 | 0x04, 0x19, 0x34, 0x9f, 0xfe, 0xbb, 0x45, 0x4b, 0x00, 0x45, 0x3e, 0x06, | ||
12194 | 0x78, 0x3d, 0xfe, 0xda, | ||
12195 | 0x14, 0x01, 0x6e, 0x87, 0xfe, 0x4b, 0x45, 0xe2, 0x2f, 0x07, 0x9a, 0xe1, | ||
12196 | 0x05, 0xc6, 0x28, 0x84, | ||
12197 | 0x05, 0x3f, 0x28, 0x34, 0x5e, 0x02, 0x5b, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, | ||
12198 | 0x14, 0xfe, 0x03, 0x17, | ||
12199 | 0x05, 0x50, 0xb4, 0x0c, 0x50, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, | ||
12200 | 0xfe, 0xaa, 0x14, 0x02, | ||
12201 | 0x5c, 0x01, 0x08, 0x25, 0x32, 0x1f, 0x44, 0x30, 0x2e, 0xd6, 0x07, 0x06, | ||
12202 | 0x21, 0x44, 0x01, 0xfe, | ||
12203 | 0x8e, 0x13, 0xfe, 0x42, 0x58, 0xfe, 0x82, 0x14, 0xfe, 0xa4, 0x14, 0x87, | ||
12204 | 0xfe, 0x4a, 0xf4, 0x0b, | ||
12205 | 0x16, 0x44, 0xfe, 0x4a, 0xf4, 0x06, 0xfe, 0x0c, 0x12, 0x2f, 0x07, 0x9a, | ||
12206 | 0x85, 0x02, 0x5b, 0x05, | ||
12207 | 0x3f, 0xb4, 0x0c, 0x3f, 0x5e, 0x2b, 0x01, 0x08, 0x26, 0x5c, 0x01, 0xfe, | ||
12208 | 0xd8, 0x14, 0x02, 0x5c, | ||
12209 | 0x13, 0x06, 0x65, 0xfe, 0xca, 0x12, 0x26, 0xfe, 0xe0, 0x12, 0x72, 0xf1, | ||
12210 | 0x01, 0x08, 0x23, 0x72, | ||
12211 | 0x03, 0x8f, 0xfe, 0xdc, 0x12, 0x25, 0xfe, 0xdc, 0x12, 0x1f, 0xfe, 0xca, | ||
12212 | 0x12, 0x5e, 0x2b, 0x01, | ||
12213 | 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, | ||
12214 | 0x1c, 0xfe, 0xff, 0x7f, | ||
12215 | 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, | ||
12216 | 0x57, 0x48, 0x8b, 0x1c, | ||
12217 | 0x3d, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x03, 0x13, 0x6c, 0xff, 0x02, | ||
12218 | 0x00, 0x57, 0x48, 0x8b, | ||
12219 | 0x03, 0x13, 0x6c, 0xff, 0x02, 0x00, 0x57, 0x48, 0x8b, 0xfe, 0x0b, 0x58, | ||
12220 | 0x03, 0x0a, 0x50, 0x01, | ||
12221 | 0x82, 0x0a, 0x3f, 0x01, 0x82, 0x03, 0xfc, 0x1c, 0x10, 0xff, 0x03, 0x00, | ||
12222 | 0x54, 0xfe, 0x00, 0xf4, | ||
12223 | 0x19, 0x48, 0xfe, 0x00, 0x7d, 0xfe, 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, | ||
12224 | 0x03, 0x7c, 0x63, 0x27, | ||
12225 | 0x0c, 0x52, 0x18, 0x53, 0xbe, 0x56, 0xbf, 0x57, 0x03, 0xfe, 0x62, 0x08, | ||
12226 | 0xfe, 0x82, 0x4a, 0xfe, | ||
12227 | 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x74, 0x03, 0x01, 0xfe, 0x14, 0x18, 0xfe, | ||
12228 | 0x42, 0x48, 0x5f, 0x60, | ||
12229 | 0x89, 0x01, 0x08, 0x1f, 0xfe, 0xa2, 0x14, 0x30, 0x2e, 0xd8, 0x01, 0x08, | ||
12230 | 0x1f, 0xfe, 0xa2, 0x14, | ||
12231 | 0x30, 0x2e, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, 0x05, 0xc6, 0x28, 0xfe, | ||
12232 | 0xcc, 0x12, 0x49, 0x04, | ||
12233 | 0x1b, 0xfe, 0xc4, 0x13, 0x23, 0x62, 0x1b, 0xe2, 0x4b, 0xc3, 0x64, 0xfe, | ||
12234 | 0xe8, 0x13, 0x3b, 0x13, | ||
12235 | 0x06, 0x17, 0xc3, 0x78, 0xdb, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, | ||
12236 | 0xa1, 0xff, 0x02, 0x83, | ||
12237 | 0x55, 0x62, 0x1a, 0xa4, 0xbb, 0xfe, 0x30, 0x00, 0x8e, 0xe4, 0x17, 0x2c, | ||
12238 | 0x13, 0x06, 0xfe, 0x56, | ||
12239 | 0x10, 0x62, 0x0b, 0xe1, 0xbb, 0xfe, 0x64, 0x00, 0x8e, 0xe4, 0x0a, 0xfe, | ||
12240 | 0x64, 0x00, 0x17, 0x93, | ||
12241 | 0x13, 0x06, 0xfe, 0x28, 0x10, 0x62, 0x06, 0xfe, 0x60, 0x13, 0xbb, 0xfe, | ||
12242 | 0xc8, 0x00, 0x8e, 0xe4, | ||
12243 | 0x0a, 0xfe, 0xc8, 0x00, 0x17, 0x4d, 0x13, 0x06, 0x83, 0xbb, 0xfe, 0x90, | ||
12244 | 0x01, 0xba, 0xfe, 0x4e, | ||
12245 | 0x14, 0x89, 0xfe, 0x12, 0x10, 0xfe, 0x43, 0xf4, 0x94, 0xfe, 0x56, 0xf0, | ||
12246 | 0xfe, 0x60, 0x14, 0xfe, | ||
12247 | 0x04, 0xf4, 0x6c, 0xfe, 0x43, 0xf4, 0x93, 0xfe, 0xf3, 0x10, 0xf9, 0x01, | ||
12248 | 0xfe, 0x22, 0x13, 0x1c, | ||
12249 | 0x3d, 0xfe, 0x10, 0x13, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x69, 0xba, | ||
12250 | 0xfe, 0x9c, 0x14, 0xb7, | ||
12251 | 0x69, 0xfe, 0x1c, 0x10, 0xfe, 0x00, 0x17, 0xfe, 0x4d, 0xe4, 0x19, 0xba, | ||
12252 | 0xfe, 0x9c, 0x14, 0xb7, | ||
12253 | 0x19, 0x83, 0x60, 0x23, 0xfe, 0x4d, 0xf4, 0x00, 0xdf, 0x89, 0x13, 0x06, | ||
12254 | 0xfe, 0xb4, 0x56, 0xfe, | ||
12255 | 0xc3, 0x58, 0x03, 0x60, 0x13, 0x0b, 0x03, 0x15, 0x06, 0x01, 0x08, 0x26, | ||
12256 | 0xe5, 0x15, 0x0b, 0x01, | ||
12257 | 0x08, 0x26, 0xe5, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xe5, 0x72, 0xfe, 0x89, | ||
12258 | 0x49, 0x01, 0x08, 0x03, | ||
12259 | 0x15, 0x06, 0x01, 0x08, 0x26, 0xa6, 0x15, 0x1a, 0x01, 0x08, 0x26, 0xa6, | ||
12260 | 0x15, 0x06, 0x01, 0x08, | ||
12261 | 0x26, 0xa6, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x26, 0xa6, 0x72, 0xfe, 0x89, | ||
12262 | 0x4a, 0x01, 0x08, 0x03, | ||
12263 | 0x60, 0x03, 0x1e, 0xcc, 0x07, 0x06, 0xfe, 0x44, 0x13, 0xad, 0x12, 0xcc, | ||
12264 | 0xfe, 0x49, 0xf4, 0x00, | ||
12265 | 0x3b, 0x72, 0x9f, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xf1, 0x01, | ||
12266 | 0x08, 0x2f, 0x07, 0xfe, | ||
12267 | 0xe3, 0x00, 0xfe, 0x20, 0x13, 0x1f, 0xfe, 0x5a, 0x15, 0x23, 0x12, 0xcd, | ||
12268 | 0x01, 0x43, 0x1e, 0xcd, | ||
12269 | 0x07, 0x06, 0x45, 0x09, 0x4a, 0x06, 0x35, 0x03, 0x0a, 0x42, 0x01, 0x0e, | ||
12270 | 0xed, 0x88, 0x07, 0x10, | ||
12271 | 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, | ||
12272 | 0x80, 0x01, 0x0e, 0x88, | ||
12273 | 0xfe, 0x80, 0xe7, 0x10, 0x07, 0x10, 0x84, 0xfe, 0x45, 0x58, 0x01, 0xe3, | ||
12274 | 0x88, 0x03, 0x0a, 0x42, | ||
12275 | 0x01, 0x0e, 0x88, 0x0a, 0x51, 0x01, 0x9e, 0x03, 0x0a, 0x42, 0x01, 0x0e, | ||
12276 | 0xfe, 0x80, 0x80, 0xf2, | ||
12277 | 0xfe, 0x49, 0xe4, 0x10, 0xa4, 0x0a, 0x80, 0x01, 0x0e, 0xf2, 0x0a, 0x51, | ||
12278 | 0x01, 0x82, 0x03, 0x17, | ||
12279 | 0x10, 0x71, 0x66, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, | ||
12280 | 0xfe, 0x24, 0x1c, 0xfe, | ||
12281 | 0x1d, 0xf7, 0x1d, 0x90, 0xfe, 0xf6, 0x15, 0x01, 0xfe, 0xfc, 0x16, 0xe0, | ||
12282 | 0x91, 0x1d, 0x66, 0xfe, | ||
12283 | 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x03, 0xae, 0x21, 0xfe, 0xe6, 0x15, 0xfe, | ||
12284 | 0xda, 0x10, 0x17, 0x10, | ||
12285 | 0x71, 0x05, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x19, 0xfe, 0x18, 0x58, | ||
12286 | 0x05, 0xfe, 0x66, 0x01, | ||
12287 | 0xfe, 0x19, 0x58, 0x91, 0x19, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, 0x06, | ||
12288 | 0xfe, 0x3c, 0x50, 0x66, | ||
12289 | 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x19, 0x90, 0xfe, | ||
12290 | 0x40, 0x16, 0xfe, 0xb6, | ||
12291 | 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x18, 0x16, 0xfe, 0x9c, 0x10, 0x17, | ||
12292 | 0x10, 0x71, 0xfe, 0x83, | ||
12293 | 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, 0x38, 0x90, | ||
12294 | 0xfe, 0x62, 0x16, 0xfe, | ||
12295 | 0x94, 0x14, 0xfe, 0x10, 0x13, 0x91, 0x38, 0x66, 0x1b, 0xfe, 0xaf, 0x19, | ||
12296 | 0xfe, 0x98, 0xe7, 0x00, | ||
12297 | 0x03, 0xae, 0x21, 0xfe, 0x56, 0x16, 0xfe, 0x6c, 0x10, 0x17, 0x10, 0x71, | ||
12298 | 0xfe, 0x30, 0xbc, 0xfe, | ||
12299 | 0xb2, 0xbc, 0x91, 0xc5, 0x66, 0x1b, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, | ||
12300 | 0xc5, 0x90, 0xfe, 0x9a, | ||
12301 | 0x16, 0xfe, 0x5c, 0x14, 0x34, 0x03, 0xae, 0x21, 0xfe, 0x86, 0x16, 0xfe, | ||
12302 | 0x42, 0x10, 0xfe, 0x02, | ||
12303 | 0xf6, 0x10, 0x71, 0xfe, 0x18, 0xfe, 0x54, 0xfe, 0x19, 0xfe, 0x55, 0xfc, | ||
12304 | 0xfe, 0x1d, 0xf7, 0x4f, | ||
12305 | 0x90, 0xfe, 0xc0, 0x16, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, 0x91, 0x4f, | ||
12306 | 0x47, 0xfe, 0x83, 0x58, | ||
12307 | 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x10, 0xfe, 0x81, 0xe7, 0x10, 0x11, | ||
12308 | 0xfe, 0xdd, 0x00, 0x63, | ||
12309 | 0x27, 0x03, 0x63, 0x27, 0xfe, 0x12, 0x45, 0x21, 0xfe, 0xb0, 0x16, 0x14, | ||
12310 | 0x06, 0x37, 0x95, 0xa9, | ||
12311 | 0x02, 0x29, 0xfe, 0x39, 0xf0, 0xfe, 0x04, 0x17, 0x23, 0x03, 0xfe, 0x7e, | ||
12312 | 0x18, 0x1c, 0x1a, 0x5d, | ||
12313 | 0x13, 0x0d, 0x03, 0x71, 0x05, 0xcb, 0x1c, 0x06, 0xfe, 0xef, 0x12, 0xfe, | ||
12314 | 0xe1, 0x10, 0x78, 0x2c, | ||
12315 | 0x46, 0x2f, 0x07, 0x2d, 0xfe, 0x3c, 0x13, 0xfe, 0x82, 0x14, 0xfe, 0x42, | ||
12316 | 0x13, 0x3c, 0x8a, 0x0a, | ||
12317 | 0x42, 0x01, 0x0e, 0xb0, 0xfe, 0x3e, 0x12, 0xf0, 0xfe, 0x45, 0x48, 0x01, | ||
12318 | 0xe3, 0xfe, 0x00, 0xcc, | ||
12319 | 0xb0, 0xfe, 0xf3, 0x13, 0x3d, 0x75, 0x07, 0x10, 0xa3, 0x0a, 0x80, 0x01, | ||
12320 | 0x0e, 0xf2, 0x01, 0x6f, | ||
12321 | 0xfe, 0x16, 0x10, 0x07, 0x7e, 0x85, 0xfe, 0x40, 0x14, 0xfe, 0x24, 0x12, | ||
12322 | 0xf6, 0xfe, 0xd6, 0xf0, | ||
12323 | 0xfe, 0x24, 0x17, 0x17, 0x0b, 0x03, 0xfe, 0x9c, 0xe7, 0x0b, 0x0f, 0xfe, | ||
12324 | 0x15, 0x00, 0x59, 0x76, | ||
12325 | 0x27, 0x01, 0xda, 0x17, 0x06, 0x03, 0x3c, 0x8a, 0x09, 0x4a, 0x1d, 0x35, | ||
12326 | 0x11, 0x2d, 0x01, 0x6f, | ||
12327 | 0x17, 0x06, 0x03, 0xfe, 0x38, 0x90, 0xfe, 0xba, 0x90, 0x79, 0xc7, 0x68, | ||
12328 | 0xc8, 0xfe, 0x48, 0x55, | ||
12329 | 0x34, 0xfe, 0xc9, 0x55, 0x03, 0x1e, 0x98, 0x73, 0x12, 0x98, 0x03, 0x0a, | ||
12330 | 0x99, 0x01, 0x0e, 0xf0, | ||
12331 | 0x0a, 0x40, 0x01, 0x0e, 0xfe, 0x49, 0x44, 0x16, 0xfe, 0xf0, 0x17, 0x73, | ||
12332 | 0x75, 0x03, 0x0a, 0x42, | ||
12333 | 0x01, 0x0e, 0x07, 0x10, 0x45, 0x0a, 0x51, 0x01, 0x9e, 0x0a, 0x40, 0x01, | ||
12334 | 0x0e, 0x73, 0x75, 0x03, | ||
12335 | 0xfe, 0x4e, 0xe4, 0x1a, 0x64, 0xfe, 0x24, 0x18, 0x05, 0xfe, 0x90, 0x00, | ||
12336 | 0xfe, 0x3a, 0x45, 0x5b, | ||
12337 | 0xfe, 0x4e, 0xe4, 0xc2, 0x64, 0xfe, 0x36, 0x18, 0x05, 0xfe, 0x92, 0x00, | ||
12338 | 0xfe, 0x02, 0xe6, 0x1b, | ||
12339 | 0xdc, 0xfe, 0x4e, 0xe4, 0xfe, 0x0b, 0x00, 0x64, 0xfe, 0x48, 0x18, 0x05, | ||
12340 | 0xfe, 0x94, 0x00, 0xfe, | ||
12341 | 0x02, 0xe6, 0x19, 0xfe, 0x08, 0x10, 0x05, 0xfe, 0x96, 0x00, 0xfe, 0x02, | ||
12342 | 0xe6, 0x2c, 0xfe, 0x4e, | ||
12343 | 0x45, 0xfe, 0x0c, 0x12, 0xaf, 0xff, 0x04, 0x68, 0x54, 0xde, 0x1c, 0x69, | ||
12344 | 0x03, 0x07, 0x7a, 0xfe, | ||
12345 | 0x5a, 0xf0, 0xfe, 0x74, 0x18, 0x24, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10, | ||
12346 | 0x07, 0x1b, 0xfe, 0x5a, | ||
12347 | 0xf0, 0xfe, 0x82, 0x18, 0x24, 0xc3, 0xfe, 0x26, 0x10, 0x07, 0x1a, 0x5d, | ||
12348 | 0x24, 0x2c, 0xdc, 0x07, | ||
12349 | 0x0b, 0x5d, 0x24, 0x93, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x5d, 0x24, 0x4d, | ||
12350 | 0x9f, 0xad, 0x03, 0x14, | ||
12351 | 0xfe, 0x09, 0x00, 0x01, 0x33, 0xfe, 0x04, 0xfe, 0x7d, 0x05, 0x7f, 0xf9, | ||
12352 | 0x03, 0x25, 0xfe, 0xca, | ||
12353 | 0x18, 0xfe, 0x14, 0xf0, 0x08, 0x65, 0xfe, 0xc6, 0x18, 0x03, 0xff, 0x1a, | ||
12354 | 0x00, 0x00, | ||
12355 | }; | ||
12356 | |||
12357 | static unsigned short _adv_asc3550_size = sizeof(_adv_asc3550_buf); /* 0x13AD */ | ||
12358 | static ADV_DCNT _adv_asc3550_chksum = 0x04D52DDDUL; /* Expanded little-endian checksum. */ | ||
12359 | |||
12360 | /* Microcode buffer is kept after initialization for error recovery. */ | ||
12361 | static unsigned char _adv_asc38C0800_buf[] = { | ||
12362 | 0x00, 0x00, 0x00, 0xf2, 0x00, 0xf0, 0x00, 0xfc, 0x00, 0x16, 0x18, 0xe4, | ||
12363 | 0x01, 0x00, 0x48, 0xe4, | ||
12364 | 0x18, 0x80, 0x03, 0xf6, 0x02, 0x00, 0xce, 0x19, 0x00, 0xfa, 0xff, 0xff, | ||
12365 | 0x1c, 0x0f, 0x00, 0xf6, | ||
12366 | 0x9e, 0xe7, 0xff, 0x00, 0x82, 0xe7, 0x00, 0xea, 0x01, 0xfa, 0x01, 0xe6, | ||
12367 | 0x09, 0xe7, 0x55, 0xf0, | ||
12368 | 0x01, 0xf6, 0x03, 0x00, 0x04, 0x00, 0x10, 0x00, 0x1e, 0xf0, 0x85, 0xf0, | ||
12369 | 0x18, 0xf4, 0x08, 0x00, | ||
12370 | 0xbc, 0x00, 0x38, 0x54, 0x00, 0xec, 0xd5, 0xf0, 0x82, 0x0d, 0x00, 0xe6, | ||
12371 | 0x86, 0xf0, 0xb1, 0xf0, | ||
12372 | 0x98, 0x57, 0x01, 0xfc, 0xb4, 0x00, 0xd4, 0x01, 0x0c, 0x1c, 0x3e, 0x1c, | ||
12373 | 0x3c, 0x00, 0xbb, 0x00, | ||
12374 | 0x00, 0x10, 0xba, 0x19, 0x02, 0x80, 0x32, 0xf0, 0x7c, 0x0d, 0x02, 0x13, | ||
12375 | 0xba, 0x13, 0x18, 0x40, | ||
12376 | 0x00, 0x57, 0x01, 0xea, 0x02, 0xfc, 0x03, 0xfc, 0x3e, 0x00, 0x6c, 0x01, | ||
12377 | 0x6e, 0x01, 0x74, 0x01, | ||
12378 | 0x76, 0x01, 0xb9, 0x54, 0x3e, 0x57, 0x00, 0x80, 0x03, 0xe6, 0xb6, 0x00, | ||
12379 | 0xc0, 0x00, 0x01, 0x01, | ||
12380 | 0x3e, 0x01, 0x7a, 0x01, 0xca, 0x08, 0xce, 0x10, 0x16, 0x11, 0x04, 0x12, | ||
12381 | 0x08, 0x12, 0x02, 0x4a, | ||
12382 | 0xbb, 0x55, 0x3c, 0x56, 0x03, 0x58, 0x1b, 0x80, 0x30, 0xe4, 0x4b, 0xe4, | ||
12383 | 0x5d, 0xf0, 0x02, 0xfa, | ||
12384 | 0x20, 0x00, 0x32, 0x00, 0x40, 0x00, 0x80, 0x00, 0x24, 0x01, 0x3c, 0x01, | ||
12385 | 0x68, 0x01, 0x6a, 0x01, | ||
12386 | 0x70, 0x01, 0x72, 0x01, 0x78, 0x01, 0x7c, 0x01, 0x62, 0x0a, 0x86, 0x0d, | ||
12387 | 0x06, 0x13, 0x4c, 0x1c, | ||
12388 | 0x04, 0x80, 0x4a, 0xe4, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x0c, 0x00, | ||
12389 | 0x0f, 0x00, 0x47, 0x00, | ||
12390 | 0xbe, 0x00, 0x00, 0x01, 0x20, 0x11, 0x5c, 0x16, 0x32, 0x1c, 0x38, 0x1c, | ||
12391 | 0x4e, 0x1c, 0x10, 0x44, | ||
12392 | 0x00, 0x4c, 0x04, 0xea, 0x5c, 0xf0, 0xa7, 0xf0, 0x04, 0xf6, 0x03, 0xfa, | ||
12393 | 0x05, 0x00, 0x34, 0x00, | ||
12394 | 0x36, 0x00, 0x98, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, 0x4a, 0x0b, | ||
12395 | 0x42, 0x0c, 0x12, 0x0f, | ||
12396 | 0x0c, 0x10, 0x22, 0x11, 0x0a, 0x12, 0x04, 0x13, 0x30, 0x1c, 0x02, 0x48, | ||
12397 | 0x00, 0x4e, 0x42, 0x54, | ||
12398 | 0x44, 0x55, 0xbd, 0x56, 0x06, 0x83, 0x00, 0xdc, 0x05, 0xf0, 0x09, 0xf0, | ||
12399 | 0x59, 0xf0, 0xb8, 0xf0, | ||
12400 | 0x4b, 0xf4, 0x06, 0xf7, 0x0e, 0xf7, 0x04, 0xfc, 0x05, 0xfc, 0x06, 0x00, | ||
12401 | 0x19, 0x00, 0x33, 0x00, | ||
12402 | 0x9b, 0x00, 0xa4, 0x00, 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe1, 0x00, | ||
12403 | 0xe7, 0x00, 0xe2, 0x03, | ||
12404 | 0x08, 0x0f, 0x02, 0x10, 0x04, 0x10, 0x0a, 0x10, 0x0a, 0x13, 0x0c, 0x13, | ||
12405 | 0x12, 0x13, 0x24, 0x14, | ||
12406 | 0x34, 0x14, 0x04, 0x16, 0x08, 0x16, 0xa4, 0x17, 0x20, 0x1c, 0x34, 0x1c, | ||
12407 | 0x36, 0x1c, 0x08, 0x44, | ||
12408 | 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x01, 0x48, 0x68, 0x54, | ||
12409 | 0x3a, 0x55, 0x83, 0x55, | ||
12410 | 0xe5, 0x55, 0xb0, 0x57, 0x01, 0x58, 0x83, 0x59, 0x05, 0xe6, 0x0b, 0xf0, | ||
12411 | 0x0c, 0xf0, 0x04, 0xf8, | ||
12412 | 0x05, 0xf8, 0x07, 0x00, 0x0a, 0x00, 0x1c, 0x00, 0x1e, 0x00, 0x9e, 0x00, | ||
12413 | 0xa8, 0x00, 0xaa, 0x00, | ||
12414 | 0xb9, 0x00, 0xe0, 0x00, 0x22, 0x01, 0x26, 0x01, 0x79, 0x01, 0x7e, 0x01, | ||
12415 | 0xc4, 0x01, 0xc6, 0x01, | ||
12416 | 0x80, 0x02, 0x5e, 0x03, 0xee, 0x04, 0x9a, 0x06, 0xf8, 0x07, 0x62, 0x08, | ||
12417 | 0x68, 0x08, 0x69, 0x08, | ||
12418 | 0xd6, 0x08, 0xe9, 0x09, 0xfa, 0x0b, 0x2e, 0x0f, 0x12, 0x10, 0x1a, 0x10, | ||
12419 | 0xed, 0x10, 0xf1, 0x10, | ||
12420 | 0x2a, 0x11, 0x06, 0x12, 0x0c, 0x12, 0x3e, 0x12, 0x10, 0x13, 0x16, 0x13, | ||
12421 | 0x1e, 0x13, 0x46, 0x14, | ||
12422 | 0x76, 0x14, 0x82, 0x14, 0x36, 0x15, 0xca, 0x15, 0x6b, 0x18, 0xbe, 0x18, | ||
12423 | 0xca, 0x18, 0xe6, 0x19, | ||
12424 | 0x12, 0x1c, 0x46, 0x1c, 0x9c, 0x32, 0x00, 0x40, 0x0e, 0x47, 0xfe, 0x9c, | ||
12425 | 0xf0, 0x2b, 0x02, 0xfe, | ||
12426 | 0xac, 0x0d, 0xff, 0x10, 0x00, 0x00, 0xd7, 0xfe, 0xe8, 0x19, 0x00, 0xd6, | ||
12427 | 0xfe, 0x84, 0x01, 0xff, | ||
12428 | 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, | ||
12429 | 0x00, 0xfe, 0x57, 0x24, | ||
12430 | 0x00, 0xfe, 0x4c, 0x00, 0x5b, 0xff, 0x04, 0x00, 0x00, 0x11, 0xff, 0x09, | ||
12431 | 0x00, 0x00, 0xff, 0x08, | ||
12432 | 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, | ||
12433 | 0xff, 0xff, 0xff, 0x11, | ||
12434 | 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, | ||
12435 | 0xfe, 0x04, 0xf7, 0xd6, | ||
12436 | 0x2c, 0x99, 0x0a, 0x01, 0xfe, 0xc2, 0x0f, 0xfe, 0x04, 0xf7, 0xd6, 0x99, | ||
12437 | 0x0a, 0x42, 0x2c, 0xfe, | ||
12438 | 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0xfe, 0x20, 0xf0, 0xa7, 0xfe, 0x91, 0xf0, | ||
12439 | 0xfe, 0xf4, 0x01, 0xfe, | ||
12440 | 0x90, 0xf0, 0xfe, 0xf4, 0x01, 0xfe, 0x8f, 0xf0, 0xa7, 0x03, 0x5d, 0x4d, | ||
12441 | 0x02, 0xfe, 0xc8, 0x0d, | ||
12442 | 0x01, 0xfe, 0x38, 0x0e, 0xfe, 0xdd, 0x12, 0xfe, 0xfc, 0x10, 0xfe, 0x28, | ||
12443 | 0x1c, 0x03, 0xfe, 0xa6, | ||
12444 | 0x00, 0xfe, 0xd3, 0x12, 0x41, 0x14, 0xfe, 0xa6, 0x00, 0xc2, 0xfe, 0x48, | ||
12445 | 0xf0, 0xfe, 0x8a, 0x02, | ||
12446 | 0xfe, 0x49, 0xf0, 0xfe, 0xa4, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc2, 0x02, | ||
12447 | 0xfe, 0x46, 0xf0, 0xfe, | ||
12448 | 0x54, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x5a, 0x02, 0xfe, 0x43, 0xf0, 0xfe, | ||
12449 | 0x48, 0x02, 0xfe, 0x44, | ||
12450 | 0xf0, 0xfe, 0x4c, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x50, 0x02, 0x18, 0x0a, | ||
12451 | 0xaa, 0x18, 0x06, 0x14, | ||
12452 | 0xa1, 0x02, 0x2b, 0xfe, 0x00, 0x1c, 0xe7, 0xfe, 0x02, 0x1c, 0xe6, 0xfe, | ||
12453 | 0x1e, 0x1c, 0xfe, 0xe9, | ||
12454 | 0x10, 0x01, 0xfe, 0x18, 0x18, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, 0xce, | ||
12455 | 0x09, 0x70, 0x01, 0xa8, | ||
12456 | 0x02, 0x2b, 0x15, 0x59, 0x39, 0xa2, 0x01, 0xfe, 0x58, 0x10, 0x09, 0x70, | ||
12457 | 0x01, 0x87, 0xfe, 0xbd, | ||
12458 | 0x10, 0x09, 0x70, 0x01, 0x87, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, 0xfe, | ||
12459 | 0x58, 0x1c, 0x18, 0x06, | ||
12460 | 0x14, 0xa1, 0x2c, 0x1c, 0x2b, 0xfe, 0x3d, 0xf0, 0xfe, 0x06, 0x02, 0x23, | ||
12461 | 0xfe, 0x98, 0x02, 0xfe, | ||
12462 | 0x5a, 0x1c, 0xf8, 0xfe, 0x14, 0x1c, 0x15, 0xfe, 0x30, 0x00, 0x39, 0xa2, | ||
12463 | 0x01, 0xfe, 0x48, 0x10, | ||
12464 | 0x18, 0x06, 0x14, 0xa1, 0x02, 0xd7, 0x22, 0x20, 0x07, 0x11, 0x35, 0xfe, | ||
12465 | 0x69, 0x10, 0x18, 0x06, | ||
12466 | 0x14, 0xa1, 0xfe, 0x04, 0xec, 0x20, 0x4f, 0x43, 0x13, 0x20, 0xfe, 0x05, | ||
12467 | 0xf6, 0xce, 0x01, 0xfe, | ||
12468 | 0x4a, 0x17, 0x08, 0x54, 0x58, 0x37, 0x12, 0x2f, 0x42, 0x92, 0x01, 0xfe, | ||
12469 | 0x82, 0x16, 0x02, 0x2b, | ||
12470 | 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, 0x01, 0x73, 0xfe, 0x18, 0x10, | ||
12471 | 0xfe, 0x41, 0x58, 0x09, | ||
12472 | 0xa4, 0x01, 0x0e, 0xfe, 0xc8, 0x54, 0x6b, 0xfe, 0x10, 0x03, 0x01, 0xfe, | ||
12473 | 0x82, 0x16, 0x02, 0x2b, | ||
12474 | 0x2c, 0x4f, 0xfe, 0x02, 0xe8, 0x2a, 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, | ||
12475 | 0xfe, 0x77, 0x57, 0xfe, | ||
12476 | 0x27, 0xf0, 0xfe, 0xe0, 0x01, 0xfe, 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xa7, | ||
12477 | 0xfe, 0x40, 0x1c, 0x1c, | ||
12478 | 0xd9, 0xfe, 0x26, 0xf0, 0xfe, 0x5a, 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x48, | ||
12479 | 0x03, 0xfe, 0x11, 0xf0, | ||
12480 | 0xa7, 0xfe, 0xef, 0x10, 0xfe, 0x9f, 0xf0, 0xfe, 0x68, 0x03, 0xf9, 0x10, | ||
12481 | 0xfe, 0x11, 0x00, 0x02, | ||
12482 | 0x65, 0x2c, 0xfe, 0x48, 0x1c, 0xf9, 0x08, 0x05, 0x1b, 0xfe, 0x18, 0x13, | ||
12483 | 0x21, 0x22, 0xa3, 0xb7, | ||
12484 | 0x13, 0xa3, 0x09, 0x46, 0x01, 0x0e, 0xb7, 0x78, 0x01, 0xfe, 0xb4, 0x16, | ||
12485 | 0x12, 0xd1, 0x1c, 0xd9, | ||
12486 | 0xfe, 0x01, 0xf0, 0xd9, 0xfe, 0x82, 0xf0, 0xfe, 0x96, 0x03, 0xfa, 0x12, | ||
12487 | 0xfe, 0xe4, 0x00, 0x27, | ||
12488 | 0xfe, 0xa8, 0x03, 0x1c, 0x34, 0x1d, 0xfe, 0xb8, 0x03, 0x01, 0x4b, 0xfe, | ||
12489 | 0x06, 0xf0, 0xfe, 0xc8, | ||
12490 | 0x03, 0x95, 0x86, 0xfe, 0x0a, 0xf0, 0xfe, 0x8a, 0x06, 0x02, 0x24, 0x03, | ||
12491 | 0x70, 0x28, 0x17, 0xfe, | ||
12492 | 0xfa, 0x04, 0x15, 0x6d, 0x01, 0x36, 0x7b, 0xfe, 0x6a, 0x02, 0x02, 0xd8, | ||
12493 | 0xf9, 0x2c, 0x99, 0x19, | ||
12494 | 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0xfe, 0x48, 0x1c, | ||
12495 | 0x74, 0x01, 0xaf, 0x8c, | ||
12496 | 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x17, 0xda, 0x09, 0xd1, 0x01, 0x0e, | ||
12497 | 0x8d, 0x51, 0x64, 0x79, | ||
12498 | 0x2a, 0x03, 0x70, 0x28, 0xfe, 0x10, 0x12, 0x15, 0x6d, 0x01, 0x36, 0x7b, | ||
12499 | 0xfe, 0x6a, 0x02, 0x02, | ||
12500 | 0xd8, 0xc7, 0x81, 0xc8, 0x83, 0x1c, 0x24, 0x27, 0xfe, 0x40, 0x04, 0x1d, | ||
12501 | 0xfe, 0x3c, 0x04, 0x3b, | ||
12502 | 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x4e, 0x12, 0x2d, 0xff, 0x02, | ||
12503 | 0x00, 0x10, 0x01, 0x0b, | ||
12504 | 0x1d, 0xfe, 0xe4, 0x04, 0x2d, 0x01, 0x0b, 0x1d, 0x24, 0x33, 0x31, 0xde, | ||
12505 | 0xfe, 0x4c, 0x44, 0xfe, | ||
12506 | 0x4c, 0x12, 0x51, 0xfe, 0x44, 0x48, 0x0f, 0x6f, 0xfe, 0x4c, 0x54, 0x6b, | ||
12507 | 0xda, 0x4f, 0x79, 0x2a, | ||
12508 | 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x62, 0x13, 0x08, 0x05, 0x1b, | ||
12509 | 0xfe, 0x2a, 0x13, 0x32, | ||
12510 | 0x07, 0x82, 0xfe, 0x52, 0x13, 0xfe, 0x20, 0x10, 0x0f, 0x6f, 0xfe, 0x4c, | ||
12511 | 0x54, 0x6b, 0xda, 0xfe, | ||
12512 | 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x40, 0x13, 0x08, 0x05, 0x1b, 0xfe, | ||
12513 | 0x08, 0x13, 0x32, 0x07, | ||
12514 | 0x82, 0xfe, 0x30, 0x13, 0x08, 0x05, 0x1b, 0xfe, 0x1c, 0x12, 0x15, 0x9d, | ||
12515 | 0x08, 0x05, 0x06, 0x4d, | ||
12516 | 0x15, 0xfe, 0x0d, 0x00, 0x01, 0x36, 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, | ||
12517 | 0x2d, 0x12, 0xfe, 0xe6, | ||
12518 | 0x00, 0xfe, 0x1c, 0x90, 0xfe, 0x40, 0x5c, 0x04, 0x15, 0x9d, 0x01, 0x36, | ||
12519 | 0x02, 0x2b, 0xfe, 0x42, | ||
12520 | 0x5b, 0x99, 0x19, 0xfe, 0x46, 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, | ||
12521 | 0xfe, 0x87, 0x80, 0xfe, | ||
12522 | 0x31, 0xe4, 0x5b, 0x08, 0x05, 0x0a, 0xfe, 0x84, 0x13, 0xfe, 0x20, 0x80, | ||
12523 | 0x07, 0x19, 0xfe, 0x7c, | ||
12524 | 0x12, 0x53, 0x05, 0x06, 0xfe, 0x6c, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x28, | ||
12525 | 0x17, 0xfe, 0x90, 0x05, | ||
12526 | 0xfe, 0x31, 0xe4, 0x5a, 0x53, 0x05, 0x0a, 0xfe, 0x56, 0x13, 0x03, 0xfe, | ||
12527 | 0xa0, 0x00, 0x28, 0xfe, | ||
12528 | 0x4e, 0x12, 0x67, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x48, 0x05, 0x1c, | ||
12529 | 0x34, 0xfe, 0x89, 0x48, | ||
12530 | 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x56, 0x05, 0x26, 0xfe, 0xa8, 0x05, | ||
12531 | 0x12, 0xfe, 0xe3, 0x00, | ||
12532 | 0x21, 0x53, 0xfe, 0x4a, 0xf0, 0xfe, 0x76, 0x05, 0xfe, 0x49, 0xf0, 0xfe, | ||
12533 | 0x70, 0x05, 0x88, 0x25, | ||
12534 | 0xfe, 0x21, 0x00, 0xab, 0x25, 0xfe, 0x22, 0x00, 0xaa, 0x25, 0x58, 0xfe, | ||
12535 | 0x09, 0x48, 0xff, 0x02, | ||
12536 | 0x00, 0x10, 0x27, 0xfe, 0x86, 0x05, 0x26, 0xfe, 0xa8, 0x05, 0xfe, 0xe2, | ||
12537 | 0x08, 0x53, 0x05, 0xcb, | ||
12538 | 0x4d, 0x01, 0xb0, 0x25, 0x06, 0x13, 0xd3, 0x39, 0xfe, 0x27, 0x01, 0x08, | ||
12539 | 0x05, 0x1b, 0xfe, 0x22, | ||
12540 | 0x12, 0x41, 0x01, 0xb2, 0x15, 0x9d, 0x08, 0x05, 0x06, 0x4d, 0x15, 0xfe, | ||
12541 | 0x0d, 0x00, 0x01, 0x36, | ||
12542 | 0x7b, 0xfe, 0x64, 0x0d, 0x02, 0x24, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0xeb, | ||
12543 | 0x03, 0x5c, 0x28, 0xfe, | ||
12544 | 0x36, 0x13, 0x41, 0x01, 0xb2, 0x26, 0xfe, 0x18, 0x06, 0x09, 0x06, 0x53, | ||
12545 | 0x05, 0x1f, 0xfe, 0x02, | ||
12546 | 0x12, 0x50, 0x01, 0xfe, 0x9e, 0x15, 0x1d, 0xfe, 0x0e, 0x06, 0x12, 0xa5, | ||
12547 | 0x01, 0x4b, 0x12, 0xfe, | ||
12548 | 0xe5, 0x00, 0x03, 0x5c, 0xc1, 0x0c, 0x5c, 0x03, 0xcd, 0x28, 0xfe, 0x62, | ||
12549 | 0x12, 0x03, 0x45, 0x28, | ||
12550 | 0xfe, 0x5a, 0x13, 0x01, 0xfe, 0x0c, 0x19, 0x01, 0xfe, 0x76, 0x19, 0xfe, | ||
12551 | 0x43, 0x48, 0xc4, 0xcc, | ||
12552 | 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0x8b, 0xc4, | ||
12553 | 0x6e, 0x41, 0x01, 0xb2, | ||
12554 | 0x26, 0xfe, 0x82, 0x06, 0x53, 0x05, 0x1a, 0xe9, 0x91, 0x09, 0x59, 0x01, | ||
12555 | 0xfe, 0xcc, 0x15, 0x1d, | ||
12556 | 0xfe, 0x78, 0x06, 0x12, 0xa5, 0x01, 0x4b, 0x12, 0xfe, 0xe5, 0x00, 0x03, | ||
12557 | 0x45, 0xc1, 0x0c, 0x45, | ||
12558 | 0x18, 0x06, 0x01, 0xb2, 0xfa, 0x76, 0x74, 0x01, 0xaf, 0x8c, 0x12, 0xfe, | ||
12559 | 0xe2, 0x00, 0x27, 0xdb, | ||
12560 | 0x1c, 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0xb6, 0x06, 0x94, 0xfe, 0x6c, 0x07, | ||
12561 | 0xfe, 0x06, 0xf0, 0xfe, | ||
12562 | 0x74, 0x07, 0x95, 0x86, 0x02, 0x24, 0x08, 0x05, 0x0a, 0xfe, 0x2e, 0x12, | ||
12563 | 0x16, 0x19, 0x01, 0x0b, | ||
12564 | 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, 0x0b, | ||
12565 | 0xfe, 0x99, 0xa4, 0x01, | ||
12566 | 0x0b, 0x16, 0x00, 0x02, 0xfe, 0x42, 0x08, 0x68, 0x05, 0x1a, 0xfe, 0x38, | ||
12567 | 0x12, 0x08, 0x05, 0x1a, | ||
12568 | 0xfe, 0x30, 0x13, 0x16, 0xfe, 0x1b, 0x00, 0x01, 0x0b, 0x16, 0x00, 0x01, | ||
12569 | 0x0b, 0x16, 0x00, 0x01, | ||
12570 | 0x0b, 0x16, 0x00, 0x01, 0x0b, 0x16, 0x06, 0x01, 0x0b, 0x16, 0x00, 0x02, | ||
12571 | 0xe2, 0x6c, 0x58, 0xbe, | ||
12572 | 0x50, 0xfe, 0x9a, 0x81, 0x55, 0x1b, 0x7a, 0xfe, 0x42, 0x07, 0x09, 0x1b, | ||
12573 | 0xfe, 0x09, 0x6f, 0xba, | ||
12574 | 0xfe, 0xca, 0x45, 0xfe, 0x32, 0x12, 0x69, 0x6d, 0x8b, 0x6c, 0x7f, 0x27, | ||
12575 | 0xfe, 0x54, 0x07, 0x1c, | ||
12576 | 0x34, 0xfe, 0x0a, 0xf0, 0xfe, 0x42, 0x07, 0x95, 0x86, 0x94, 0xfe, 0x6c, | ||
12577 | 0x07, 0x02, 0x24, 0x01, | ||
12578 | 0x4b, 0x02, 0xdb, 0x16, 0x1f, 0x02, 0xdb, 0xfe, 0x9c, 0xf7, 0xdc, 0xfe, | ||
12579 | 0x2c, 0x90, 0xfe, 0xae, | ||
12580 | 0x90, 0x56, 0xfe, 0xda, 0x07, 0x0c, 0x60, 0x14, 0x61, 0x08, 0x54, 0x5a, | ||
12581 | 0x37, 0x22, 0x20, 0x07, | ||
12582 | 0x11, 0xfe, 0x0e, 0x12, 0x8d, 0xfe, 0x80, 0x80, 0x39, 0x20, 0x6a, 0x2a, | ||
12583 | 0xfe, 0x06, 0x10, 0xfe, | ||
12584 | 0x83, 0xe7, 0xfe, 0x48, 0x00, 0xab, 0xfe, 0x03, 0x40, 0x08, 0x54, 0x5b, | ||
12585 | 0x37, 0x01, 0xb3, 0xb8, | ||
12586 | 0xfe, 0x1f, 0x40, 0x13, 0x62, 0x01, 0xef, 0xfe, 0x08, 0x50, 0xfe, 0x8a, | ||
12587 | 0x50, 0xfe, 0x44, 0x51, | ||
12588 | 0xfe, 0xc6, 0x51, 0x88, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, 0x0c, 0x5e, | ||
12589 | 0x14, 0x5f, 0xfe, 0x0c, | ||
12590 | 0x90, 0xfe, 0x8e, 0x90, 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x0c, 0x3d, | ||
12591 | 0x14, 0x3e, 0xfe, 0x4a, | ||
12592 | 0x10, 0x08, 0x05, 0x5a, 0xfe, 0x2a, 0x12, 0xfe, 0x2c, 0x90, 0xfe, 0xae, | ||
12593 | 0x90, 0x0c, 0x60, 0x14, | ||
12594 | 0x61, 0x08, 0x05, 0x5b, 0x8b, 0x01, 0xb3, 0xfe, 0x1f, 0x80, 0x13, 0x62, | ||
12595 | 0xfe, 0x44, 0x90, 0xfe, | ||
12596 | 0xc6, 0x90, 0x0c, 0x3f, 0x14, 0x40, 0xfe, 0x08, 0x90, 0xfe, 0x8a, 0x90, | ||
12597 | 0x0c, 0x5e, 0x14, 0x5f, | ||
12598 | 0xfe, 0x40, 0x90, 0xfe, 0xc2, 0x90, 0x0c, 0x3d, 0x14, 0x3e, 0x0c, 0x2e, | ||
12599 | 0x14, 0x3c, 0x21, 0x0c, | ||
12600 | 0x49, 0x0c, 0x63, 0x08, 0x54, 0x1f, 0x37, 0x2c, 0x0f, 0xfe, 0x4e, 0x11, | ||
12601 | 0x27, 0xdd, 0xfe, 0x9e, | ||
12602 | 0xf0, 0xfe, 0x76, 0x08, 0xbc, 0x17, 0x34, 0x2c, 0x77, 0xe6, 0xc5, 0xfe, | ||
12603 | 0x9a, 0x08, 0xc6, 0xfe, | ||
12604 | 0xb8, 0x08, 0x94, 0xfe, 0x8e, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x94, 0x08, | ||
12605 | 0x95, 0x86, 0x02, 0x24, | ||
12606 | 0x01, 0x4b, 0xfe, 0xc9, 0x10, 0x16, 0x1f, 0xfe, 0xc9, 0x10, 0x68, 0x05, | ||
12607 | 0x06, 0xfe, 0x10, 0x12, | ||
12608 | 0x68, 0x05, 0x0a, 0x4e, 0x08, 0x05, 0x0a, 0xfe, 0x90, 0x12, 0xfe, 0x2e, | ||
12609 | 0x1c, 0x02, 0xfe, 0x18, | ||
12610 | 0x0b, 0x68, 0x05, 0x06, 0x4e, 0x68, 0x05, 0x0a, 0xfe, 0x7a, 0x12, 0xfe, | ||
12611 | 0x2c, 0x1c, 0xfe, 0xaa, | ||
12612 | 0xf0, 0xfe, 0xd2, 0x09, 0xfe, 0xac, 0xf0, 0xfe, 0x00, 0x09, 0x02, 0xfe, | ||
12613 | 0xde, 0x09, 0xfe, 0xb7, | ||
12614 | 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0x02, 0xf6, 0x1a, 0x50, 0xfe, 0x70, 0x18, | ||
12615 | 0xfe, 0xf1, 0x18, 0xfe, | ||
12616 | 0x40, 0x55, 0xfe, 0xe1, 0x55, 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0xfe, | ||
12617 | 0x14, 0x59, 0xfe, 0x95, | ||
12618 | 0x59, 0x1c, 0x85, 0xfe, 0x8c, 0xf0, 0xfe, 0xfc, 0x08, 0xfe, 0xac, 0xf0, | ||
12619 | 0xfe, 0xf0, 0x08, 0xb5, | ||
12620 | 0xfe, 0xcb, 0x10, 0xfe, 0xad, 0xf0, 0xfe, 0x0c, 0x09, 0x02, 0xfe, 0x18, | ||
12621 | 0x0b, 0xb6, 0xfe, 0xbf, | ||
12622 | 0x10, 0xfe, 0x2b, 0xf0, 0x85, 0xf4, 0x1e, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, | ||
12623 | 0x12, 0xc2, 0xfe, 0xd2, | ||
12624 | 0xf0, 0x85, 0xfe, 0x76, 0x18, 0x1e, 0x19, 0x17, 0x85, 0x03, 0xd2, 0x1e, | ||
12625 | 0x06, 0x17, 0x85, 0xc5, | ||
12626 | 0x4a, 0xc6, 0x4a, 0xb5, 0xb6, 0xfe, 0x89, 0x10, 0x74, 0x67, 0x2d, 0x15, | ||
12627 | 0x9d, 0x01, 0x36, 0x10, | ||
12628 | 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x65, 0x10, 0x80, 0x02, 0x65, 0xfe, | ||
12629 | 0x98, 0x80, 0xfe, 0x19, | ||
12630 | 0xe4, 0x0a, 0xfe, 0x1a, 0x12, 0x51, 0xfe, 0x19, 0x82, 0xfe, 0x6c, 0x18, | ||
12631 | 0xfe, 0x44, 0x54, 0xbe, | ||
12632 | 0xfe, 0x19, 0x81, 0xfe, 0x74, 0x18, 0x8f, 0x90, 0x17, 0xfe, 0xce, 0x08, | ||
12633 | 0x02, 0x4a, 0x08, 0x05, | ||
12634 | 0x5a, 0xec, 0x03, 0x2e, 0x29, 0x3c, 0x0c, 0x3f, 0x14, 0x40, 0x9b, 0x2e, | ||
12635 | 0x9c, 0x3c, 0xfe, 0x6c, | ||
12636 | 0x18, 0xfe, 0xed, 0x18, 0xfe, 0x44, 0x54, 0xfe, 0xe5, 0x54, 0x3a, 0x3f, | ||
12637 | 0x3b, 0x40, 0x03, 0x49, | ||
12638 | 0x29, 0x63, 0x8f, 0xfe, 0xe3, 0x54, 0xfe, 0x74, 0x18, 0xfe, 0xf5, 0x18, | ||
12639 | 0x8f, 0xfe, 0xe3, 0x54, | ||
12640 | 0x90, 0xc0, 0x56, 0xfe, 0xce, 0x08, 0x02, 0x4a, 0xfe, 0x37, 0xf0, 0xfe, | ||
12641 | 0xda, 0x09, 0xfe, 0x8b, | ||
12642 | 0xf0, 0xfe, 0x60, 0x09, 0x02, 0x4a, 0x08, 0x05, 0x0a, 0x23, 0xfe, 0xfa, | ||
12643 | 0x0a, 0x3a, 0x49, 0x3b, | ||
12644 | 0x63, 0x56, 0xfe, 0x3e, 0x0a, 0x0f, 0xfe, 0xc0, 0x07, 0x41, 0x98, 0x00, | ||
12645 | 0xad, 0xfe, 0x01, 0x59, | ||
12646 | 0xfe, 0x52, 0xf0, 0xfe, 0x0c, 0x0a, 0x8f, 0x7a, 0xfe, 0x24, 0x0a, 0x3a, | ||
12647 | 0x49, 0x8f, 0xfe, 0xe3, | ||
12648 | 0x54, 0x57, 0x49, 0x7d, 0x63, 0xfe, 0x14, 0x58, 0xfe, 0x95, 0x58, 0x02, | ||
12649 | 0x4a, 0x3a, 0x49, 0x3b, | ||
12650 | 0x63, 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0xbe, 0x57, 0x49, 0x57, 0x63, | ||
12651 | 0x02, 0x4a, 0x08, 0x05, | ||
12652 | 0x5a, 0xfe, 0x82, 0x12, 0x08, 0x05, 0x1f, 0xfe, 0x66, 0x13, 0x22, 0x62, | ||
12653 | 0xb7, 0xfe, 0x03, 0xa1, | ||
12654 | 0xfe, 0x83, 0x80, 0xfe, 0xc8, 0x44, 0xfe, 0x2e, 0x13, 0xfe, 0x04, 0x91, | ||
12655 | 0xfe, 0x86, 0x91, 0x6a, | ||
12656 | 0x2a, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x56, 0xe0, 0x03, 0x60, 0x29, | ||
12657 | 0x61, 0x0c, 0x7f, 0x14, | ||
12658 | 0x80, 0x57, 0x60, 0x7d, 0x61, 0x01, 0xb3, 0xb8, 0x6a, 0x2a, 0x13, 0x62, | ||
12659 | 0x9b, 0x2e, 0x9c, 0x3c, | ||
12660 | 0x3a, 0x3f, 0x3b, 0x40, 0x90, 0xc0, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, | ||
12661 | 0xfa, 0x3c, 0x01, 0xef, | ||
12662 | 0xfe, 0x36, 0x10, 0x21, 0x0c, 0x7f, 0x0c, 0x80, 0x3a, 0x3f, 0x3b, 0x40, | ||
12663 | 0xe4, 0x08, 0x05, 0x1f, | ||
12664 | 0x17, 0xe0, 0x3a, 0x3d, 0x3b, 0x3e, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, | ||
12665 | 0x03, 0x5e, 0x29, 0x5f, | ||
12666 | 0xfe, 0x10, 0x58, 0xfe, 0x91, 0x58, 0x57, 0x49, 0x7d, 0x63, 0x02, 0xfe, | ||
12667 | 0xf4, 0x09, 0x08, 0x05, | ||
12668 | 0x1f, 0x17, 0xe0, 0x08, 0x05, 0xfe, 0xf7, 0x00, 0x37, 0xbe, 0xfe, 0x19, | ||
12669 | 0x81, 0x50, 0xfe, 0x10, | ||
12670 | 0x90, 0xfe, 0x92, 0x90, 0xfe, 0xd3, 0x10, 0x32, 0x07, 0xa6, 0x17, 0xfe, | ||
12671 | 0x08, 0x09, 0x12, 0xa6, | ||
12672 | 0x08, 0x05, 0x0a, 0xfe, 0x14, 0x13, 0x03, 0x3d, 0x29, 0x3e, 0x56, 0xfe, | ||
12673 | 0x08, 0x09, 0xfe, 0x0c, | ||
12674 | 0x58, 0xfe, 0x8d, 0x58, 0x02, 0x4a, 0x21, 0x41, 0xfe, 0x19, 0x80, 0xe7, | ||
12675 | 0x08, 0x05, 0x0a, 0xfe, | ||
12676 | 0x1a, 0x12, 0xfe, 0x6c, 0x19, 0xfe, 0x19, 0x41, 0xf4, 0xc2, 0xfe, 0xd1, | ||
12677 | 0xf0, 0xe2, 0x15, 0x7e, | ||
12678 | 0x01, 0x36, 0x10, 0xfe, 0x44, 0x00, 0xfe, 0x8e, 0x10, 0xfe, 0x6c, 0x19, | ||
12679 | 0x57, 0x3d, 0xfe, 0xed, | ||
12680 | 0x19, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, 0xf4, 0x1e, 0xfe, | ||
12681 | 0x00, 0xff, 0x35, 0xfe, | ||
12682 | 0x74, 0x10, 0xc2, 0xfe, 0xd2, 0xf0, 0xfe, 0xa6, 0x0b, 0xfe, 0x76, 0x18, | ||
12683 | 0x1e, 0x19, 0x8a, 0x03, | ||
12684 | 0xd2, 0x1e, 0x06, 0xfe, 0x08, 0x13, 0x10, 0xfe, 0x16, 0x00, 0x02, 0x65, | ||
12685 | 0xfe, 0xd1, 0xf0, 0xfe, | ||
12686 | 0xb8, 0x0b, 0x15, 0x7e, 0x01, 0x36, 0x10, 0xfe, 0x17, 0x00, 0xfe, 0x42, | ||
12687 | 0x10, 0xfe, 0xce, 0xf0, | ||
12688 | 0xfe, 0xbe, 0x0b, 0xfe, 0x3c, 0x10, 0xfe, 0xcd, 0xf0, 0xfe, 0xca, 0x0b, | ||
12689 | 0x10, 0xfe, 0x22, 0x00, | ||
12690 | 0x02, 0x65, 0xfe, 0xcb, 0xf0, 0xfe, 0xd6, 0x0b, 0x10, 0xfe, 0x24, 0x00, | ||
12691 | 0x02, 0x65, 0xfe, 0xd0, | ||
12692 | 0xf0, 0xfe, 0xe0, 0x0b, 0x10, 0x9e, 0xe5, 0xfe, 0xcf, 0xf0, 0xfe, 0xea, | ||
12693 | 0x0b, 0x10, 0x58, 0xfe, | ||
12694 | 0x10, 0x10, 0xfe, 0xcc, 0xf0, 0xe2, 0x68, 0x05, 0x1f, 0x4d, 0x10, 0xfe, | ||
12695 | 0x12, 0x00, 0x2c, 0x0f, | ||
12696 | 0xfe, 0x4e, 0x11, 0x27, 0xfe, 0x00, 0x0c, 0xfe, 0x9e, 0xf0, 0xfe, 0x14, | ||
12697 | 0x0c, 0xbc, 0x17, 0x34, | ||
12698 | 0x2c, 0x77, 0xe6, 0xc5, 0x24, 0xc6, 0x24, 0x2c, 0xfa, 0x27, 0xfe, 0x20, | ||
12699 | 0x0c, 0x1c, 0x34, 0x94, | ||
12700 | 0xfe, 0x3c, 0x0c, 0x95, 0x86, 0xc5, 0xdc, 0xc6, 0xdc, 0x02, 0x24, 0x01, | ||
12701 | 0x4b, 0xfe, 0xdb, 0x10, | ||
12702 | 0x12, 0xfe, 0xe8, 0x00, 0xb5, 0xb6, 0x74, 0xc7, 0x81, 0xc8, 0x83, 0xfe, | ||
12703 | 0x89, 0xf0, 0x24, 0x33, | ||
12704 | 0x31, 0xe1, 0xc7, 0x81, 0xc8, 0x83, 0x27, 0xfe, 0x66, 0x0c, 0x1d, 0x24, | ||
12705 | 0x33, 0x31, 0xdf, 0xbc, | ||
12706 | 0x4e, 0x10, 0xfe, 0x42, 0x00, 0x02, 0x65, 0x7c, 0x06, 0xfe, 0x81, 0x49, | ||
12707 | 0x17, 0xfe, 0x2c, 0x0d, | ||
12708 | 0x08, 0x05, 0x0a, 0xfe, 0x44, 0x13, 0x10, 0x00, 0x55, 0x0a, 0xfe, 0x54, | ||
12709 | 0x12, 0x55, 0xfe, 0x28, | ||
12710 | 0x00, 0x23, 0xfe, 0x9a, 0x0d, 0x09, 0x46, 0x01, 0x0e, 0x07, 0x00, 0x66, | ||
12711 | 0x44, 0xfe, 0x28, 0x00, | ||
12712 | 0xfe, 0xe2, 0x10, 0x01, 0xf5, 0x01, 0xf6, 0x09, 0xa4, 0x01, 0xfe, 0x26, | ||
12713 | 0x0f, 0x64, 0x12, 0x2f, | ||
12714 | 0x01, 0x73, 0x02, 0x2b, 0x10, 0xfe, 0x44, 0x00, 0x55, 0x0a, 0xe9, 0x44, | ||
12715 | 0x0a, 0xfe, 0xb4, 0x10, | ||
12716 | 0x01, 0xb0, 0x44, 0x0a, 0xfe, 0xaa, 0x10, 0x01, 0xb0, 0xfe, 0x19, 0x82, | ||
12717 | 0xfe, 0x34, 0x46, 0xac, | ||
12718 | 0x44, 0x0a, 0x10, 0xfe, 0x43, 0x00, 0xfe, 0x96, 0x10, 0x08, 0x54, 0x0a, | ||
12719 | 0x37, 0x01, 0xf5, 0x01, | ||
12720 | 0xf6, 0x64, 0x12, 0x2f, 0x01, 0x73, 0x99, 0x0a, 0x64, 0x42, 0x92, 0x02, | ||
12721 | 0xfe, 0x2e, 0x03, 0x08, | ||
12722 | 0x05, 0x0a, 0x8a, 0x44, 0x0a, 0x10, 0x00, 0xfe, 0x5c, 0x10, 0x68, 0x05, | ||
12723 | 0x1a, 0xfe, 0x58, 0x12, | ||
12724 | 0x08, 0x05, 0x1a, 0xfe, 0x50, 0x13, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, | ||
12725 | 0xfe, 0x50, 0x0d, 0xfe, | ||
12726 | 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x56, 0x0d, 0x08, 0x54, 0x1a, 0x37, | ||
12727 | 0xfe, 0xa9, 0x10, 0x10, | ||
12728 | 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0a, 0x50, 0xfe, 0x2e, 0x10, 0x10, | ||
12729 | 0xfe, 0x13, 0x00, 0xfe, | ||
12730 | 0x10, 0x10, 0x10, 0x6f, 0xab, 0x10, 0xfe, 0x41, 0x00, 0xaa, 0x10, 0xfe, | ||
12731 | 0x24, 0x00, 0x8c, 0xb5, | ||
12732 | 0xb6, 0x74, 0x03, 0x70, 0x28, 0x23, 0xd8, 0x50, 0xfe, 0x04, 0xe6, 0x1a, | ||
12733 | 0xfe, 0x9d, 0x41, 0xfe, | ||
12734 | 0x1c, 0x42, 0x64, 0x01, 0xe3, 0x02, 0x2b, 0xf8, 0x15, 0x0a, 0x39, 0xa0, | ||
12735 | 0xb4, 0x15, 0xfe, 0x31, | ||
12736 | 0x00, 0x39, 0xa2, 0x01, 0xfe, 0x48, 0x10, 0x02, 0xd7, 0x42, 0xfe, 0x06, | ||
12737 | 0xec, 0xd0, 0xfc, 0x44, | ||
12738 | 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, 0x06, 0xea, 0xd0, 0xfe, 0x47, | ||
12739 | 0x4b, 0x91, 0xfe, 0x75, | ||
12740 | 0x57, 0x03, 0x5d, 0xfe, 0x98, 0x56, 0xfe, 0x38, 0x12, 0x09, 0x48, 0x01, | ||
12741 | 0x0e, 0xfe, 0x44, 0x48, | ||
12742 | 0x4f, 0x08, 0x05, 0x1b, 0xfe, 0x1a, 0x13, 0x09, 0x46, 0x01, 0x0e, 0x41, | ||
12743 | 0xfe, 0x41, 0x58, 0x09, | ||
12744 | 0xa4, 0x01, 0x0e, 0xfe, 0x49, 0x54, 0x96, 0xfe, 0x1e, 0x0e, 0x02, 0xfe, | ||
12745 | 0x2e, 0x03, 0x09, 0x5d, | ||
12746 | 0xfe, 0xee, 0x14, 0xfc, 0x44, 0x1b, 0xfe, 0xce, 0x45, 0x35, 0x42, 0xfe, | ||
12747 | 0xce, 0x47, 0xfe, 0xad, | ||
12748 | 0x13, 0x02, 0x2b, 0x22, 0x20, 0x07, 0x11, 0xfe, 0x9e, 0x12, 0x21, 0x13, | ||
12749 | 0x59, 0x13, 0x9f, 0x13, | ||
12750 | 0xd5, 0x22, 0x2f, 0x41, 0x39, 0x2f, 0xbc, 0xad, 0xfe, 0xbc, 0xf0, 0xfe, | ||
12751 | 0xe0, 0x0e, 0x0f, 0x06, | ||
12752 | 0x13, 0x59, 0x01, 0xfe, 0xda, 0x16, 0x03, 0xfe, 0x38, 0x01, 0x29, 0xfe, | ||
12753 | 0x3a, 0x01, 0x56, 0xfe, | ||
12754 | 0xe4, 0x0e, 0xfe, 0x02, 0xec, 0xd5, 0x69, 0x00, 0x66, 0xfe, 0x04, 0xec, | ||
12755 | 0x20, 0x4f, 0xfe, 0x05, | ||
12756 | 0xf6, 0xfe, 0x34, 0x01, 0x01, 0xfe, 0x4a, 0x17, 0xfe, 0x08, 0x90, 0xfe, | ||
12757 | 0x48, 0xf4, 0x0d, 0xfe, | ||
12758 | 0x18, 0x13, 0xba, 0xfe, 0x02, 0xea, 0xd5, 0x69, 0x7e, 0xfe, 0xc5, 0x13, | ||
12759 | 0x15, 0x1a, 0x39, 0xa0, | ||
12760 | 0xb4, 0xfe, 0x2e, 0x10, 0x03, 0xfe, 0x38, 0x01, 0x1e, 0xfe, 0xf0, 0xff, | ||
12761 | 0x0c, 0xfe, 0x60, 0x01, | ||
12762 | 0x03, 0xfe, 0x3a, 0x01, 0x0c, 0xfe, 0x62, 0x01, 0x43, 0x13, 0x20, 0x25, | ||
12763 | 0x06, 0x13, 0x2f, 0x12, | ||
12764 | 0x2f, 0x92, 0x0f, 0x06, 0x04, 0x21, 0x04, 0x22, 0x59, 0xfe, 0xf7, 0x12, | ||
12765 | 0x22, 0x9f, 0xb7, 0x13, | ||
12766 | 0x9f, 0x07, 0x7e, 0xfe, 0x71, 0x13, 0xfe, 0x24, 0x1c, 0x15, 0x19, 0x39, | ||
12767 | 0xa0, 0xb4, 0xfe, 0xd9, | ||
12768 | 0x10, 0xc3, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x04, | ||
12769 | 0xc3, 0xfe, 0x03, 0xdc, | ||
12770 | 0xfe, 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x04, 0xfe, 0x03, 0x57, 0xc3, 0x21, | ||
12771 | 0xfe, 0x00, 0xcc, 0x04, | ||
12772 | 0xfe, 0x03, 0x57, 0xc3, 0x78, 0x04, 0x08, 0x05, 0x58, 0xfe, 0x22, 0x13, | ||
12773 | 0xfe, 0x1c, 0x80, 0x07, | ||
12774 | 0x06, 0xfe, 0x1a, 0x13, 0xfe, 0x1e, 0x80, 0xed, 0xfe, 0x1d, 0x80, 0xae, | ||
12775 | 0xfe, 0x0c, 0x90, 0xfe, | ||
12776 | 0x0e, 0x13, 0xfe, 0x0e, 0x90, 0xac, 0xfe, 0x3c, 0x90, 0xfe, 0x30, 0xf4, | ||
12777 | 0x0a, 0xfe, 0x3c, 0x50, | ||
12778 | 0xaa, 0x01, 0xfe, 0x7a, 0x17, 0x32, 0x07, 0x2f, 0xad, 0x01, 0xfe, 0xb4, | ||
12779 | 0x16, 0x08, 0x05, 0x1b, | ||
12780 | 0x4e, 0x01, 0xf5, 0x01, 0xf6, 0x12, 0xfe, 0xe9, 0x00, 0x08, 0x05, 0x58, | ||
12781 | 0xfe, 0x2c, 0x13, 0x01, | ||
12782 | 0xfe, 0x0c, 0x17, 0xfe, 0x1e, 0x1c, 0xfe, 0x14, 0x90, 0xfe, 0x96, 0x90, | ||
12783 | 0x0c, 0xfe, 0x64, 0x01, | ||
12784 | 0x14, 0xfe, 0x66, 0x01, 0x08, 0x05, 0x5b, 0xfe, 0x12, 0x12, 0xfe, 0x03, | ||
12785 | 0x80, 0x8d, 0xfe, 0x01, | ||
12786 | 0xec, 0x20, 0xfe, 0x80, 0x40, 0x13, 0x20, 0x6a, 0x2a, 0x12, 0xcf, 0x64, | ||
12787 | 0x22, 0x20, 0xfb, 0x79, | ||
12788 | 0x20, 0x04, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, 0x06, 0x58, | ||
12789 | 0x03, 0xfe, 0xae, 0x00, | ||
12790 | 11841 | ||
12791 | 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, 0x03, 0xfe, | 11842 | asc_dvc->init_state |= ASC_INIT_STATE_END_SET_CFG; |
12792 | 0xb2, 0x00, 0xfe, 0x09, | ||
12793 | 0x58, 0xfe, 0x0a, 0x1c, 0x25, 0x6e, 0x13, 0xd0, 0x21, 0x0c, 0x5c, 0x0c, | ||
12794 | 0x45, 0x0f, 0x46, 0x52, | ||
12795 | 0x50, 0x18, 0x1b, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xfe, 0xfc, | ||
12796 | 0x0f, 0x44, 0x11, 0x0f, | ||
12797 | 0x48, 0x52, 0x18, 0x58, 0xfe, 0x90, 0x4d, 0xfe, 0x91, 0x54, 0x23, 0xe4, | ||
12798 | 0x25, 0x11, 0x13, 0x20, | ||
12799 | 0x7c, 0x6f, 0x4f, 0x22, 0x20, 0xfb, 0x79, 0x20, 0x12, 0xcf, 0xfe, 0x14, | ||
12800 | 0x56, 0xfe, 0xd6, 0xf0, | ||
12801 | 0xfe, 0x26, 0x10, 0xf8, 0x74, 0xfe, 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, | ||
12802 | 0x18, 0x1c, 0x04, 0x42, | ||
12803 | 0xfe, 0x0c, 0x14, 0xfc, 0xfe, 0x07, 0xe6, 0x1b, 0xfe, 0xce, 0x47, 0xfe, | ||
12804 | 0xf5, 0x13, 0x04, 0x01, | ||
12805 | 0xb0, 0x7c, 0x6f, 0x4f, 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, | ||
12806 | 0x13, 0x32, 0x07, 0x2f, | ||
12807 | 0xfe, 0x34, 0x13, 0x09, 0x48, 0x01, 0x0e, 0xbb, 0xfe, 0x36, 0x12, 0xfe, | ||
12808 | 0x41, 0x48, 0xfe, 0x45, | ||
12809 | 0x48, 0x01, 0xf0, 0xfe, 0x00, 0xcc, 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, | ||
12810 | 0x07, 0x11, 0xac, 0x09, | ||
12811 | 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x5c, 0x01, 0x73, 0xfe, 0x0e, 0x10, 0x07, | ||
12812 | 0x82, 0x4e, 0xfe, 0x14, | ||
12813 | 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x60, 0x10, 0x04, 0xfe, 0x44, 0x58, 0x8d, | ||
12814 | 0xfe, 0x01, 0xec, 0xa2, | ||
12815 | 0xfe, 0x9e, 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x1a, 0x79, | ||
12816 | 0x2a, 0x01, 0xe3, 0xfe, | ||
12817 | 0xdd, 0x10, 0x2c, 0xc7, 0x81, 0xc8, 0x83, 0x33, 0x31, 0xde, 0x07, 0x1a, | ||
12818 | 0xfe, 0x48, 0x12, 0x07, | ||
12819 | 0x0a, 0xfe, 0x56, 0x12, 0x07, 0x19, 0xfe, 0x30, 0x12, 0x07, 0xc9, 0x17, | ||
12820 | 0xfe, 0x32, 0x12, 0x07, | ||
12821 | 0xfe, 0x23, 0x00, 0x17, 0xeb, 0x07, 0x06, 0x17, 0xfe, 0x9c, 0x12, 0x07, | ||
12822 | 0x1f, 0xfe, 0x12, 0x12, | ||
12823 | 0x07, 0x00, 0x17, 0x24, 0x15, 0xc9, 0x01, 0x36, 0xa9, 0x2d, 0x01, 0x0b, | ||
12824 | 0x94, 0x4b, 0x04, 0x2d, | ||
12825 | 0xdd, 0x09, 0xd1, 0x01, 0xfe, 0x26, 0x0f, 0x12, 0x82, 0x02, 0x2b, 0x2d, | ||
12826 | 0x32, 0x07, 0xa6, 0xfe, | ||
12827 | 0xd9, 0x13, 0x3a, 0x3d, 0x3b, 0x3e, 0x56, 0xfe, 0xf0, 0x11, 0x08, 0x05, | ||
12828 | 0x5a, 0xfe, 0x72, 0x12, | ||
12829 | 0x9b, 0x2e, 0x9c, 0x3c, 0x90, 0xc0, 0x96, 0xfe, 0xba, 0x11, 0x22, 0x62, | ||
12830 | 0xfe, 0x26, 0x13, 0x03, | ||
12831 | 0x7f, 0x29, 0x80, 0x56, 0xfe, 0x76, 0x0d, 0x0c, 0x60, 0x14, 0x61, 0x21, | ||
12832 | 0x0c, 0x7f, 0x0c, 0x80, | ||
12833 | 0x01, 0xb3, 0x25, 0x6e, 0x77, 0x13, 0x62, 0x01, 0xef, 0x9b, 0x2e, 0x9c, | ||
12834 | 0x3c, 0xfe, 0x04, 0x55, | ||
12835 | 0xfe, 0xa5, 0x55, 0xfe, 0x04, 0xfa, 0x2e, 0xfe, 0x05, 0xfa, 0x3c, 0xfe, | ||
12836 | 0x91, 0x10, 0x03, 0x3f, | ||
12837 | 0x29, 0x40, 0xfe, 0x40, 0x56, 0xfe, 0xe1, 0x56, 0x0c, 0x3f, 0x14, 0x40, | ||
12838 | 0x88, 0x9b, 0x2e, 0x9c, | ||
12839 | 0x3c, 0x90, 0xc0, 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x00, 0x56, 0xfe, 0xa1, | ||
12840 | 0x56, 0x0c, 0x5e, 0x14, | ||
12841 | 0x5f, 0x08, 0x05, 0x5a, 0xfe, 0x1e, 0x12, 0x22, 0x62, 0xfe, 0x1f, 0x40, | ||
12842 | 0x03, 0x60, 0x29, 0x61, | ||
12843 | 0xfe, 0x2c, 0x50, 0xfe, 0xae, 0x50, 0x03, 0x3f, 0x29, 0x40, 0xfe, 0x44, | ||
12844 | 0x50, 0xfe, 0xc6, 0x50, | ||
12845 | 0x03, 0x5e, 0x29, 0x5f, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x3d, | ||
12846 | 0x29, 0x3e, 0xfe, 0x40, | ||
12847 | 0x50, 0xfe, 0xc2, 0x50, 0x02, 0x89, 0x25, 0x06, 0x13, 0xd4, 0x02, 0x72, | ||
12848 | 0x2d, 0x01, 0x0b, 0x1d, | ||
12849 | 0x4c, 0x33, 0x31, 0xde, 0x07, 0x06, 0x23, 0x4c, 0x32, 0x07, 0xa6, 0x23, | ||
12850 | 0x72, 0x01, 0xaf, 0x1e, | ||
12851 | 0x43, 0x17, 0x4c, 0x08, 0x05, 0x0a, 0xee, 0x3a, 0x3d, 0x3b, 0x3e, 0xfe, | ||
12852 | 0x0a, 0x55, 0x35, 0xfe, | ||
12853 | 0x8b, 0x55, 0x57, 0x3d, 0x7d, 0x3e, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, 0x51, | ||
12854 | 0x02, 0x72, 0xfe, 0x19, | ||
12855 | 0x81, 0xba, 0xfe, 0x19, 0x41, 0x02, 0x72, 0x2d, 0x01, 0x0b, 0x1c, 0x34, | ||
12856 | 0x1d, 0xe8, 0x33, 0x31, | ||
12857 | 0xe1, 0x55, 0x19, 0xfe, 0xa6, 0x12, 0x55, 0x0a, 0x4d, 0x02, 0x4c, 0x01, | ||
12858 | 0x0b, 0x1c, 0x34, 0x1d, | ||
12859 | 0xe8, 0x33, 0x31, 0xdf, 0x07, 0x19, 0x23, 0x4c, 0x01, 0x0b, 0x1d, 0xe8, | ||
12860 | 0x33, 0x31, 0xfe, 0xe8, | ||
12861 | 0x09, 0xfe, 0xc2, 0x49, 0x51, 0x03, 0xfe, 0x9c, 0x00, 0x28, 0x8a, 0x53, | ||
12862 | 0x05, 0x1f, 0x35, 0xa9, | ||
12863 | 0xfe, 0xbb, 0x45, 0x55, 0x00, 0x4e, 0x44, 0x06, 0x7c, 0x43, 0xfe, 0xda, | ||
12864 | 0x14, 0x01, 0xaf, 0x8c, | ||
12865 | 0xfe, 0x4b, 0x45, 0xee, 0x32, 0x07, 0xa5, 0xed, 0x03, 0xcd, 0x28, 0x8a, | ||
12866 | 0x03, 0x45, 0x28, 0x35, | ||
12867 | 0x67, 0x02, 0x72, 0xfe, 0xc0, 0x5d, 0xfe, 0xf8, 0x14, 0xfe, 0x03, 0x17, | ||
12868 | 0x03, 0x5c, 0xc1, 0x0c, | ||
12869 | 0x5c, 0x67, 0x2d, 0x01, 0x0b, 0x26, 0x89, 0x01, 0xfe, 0x9e, 0x15, 0x02, | ||
12870 | 0x89, 0x01, 0x0b, 0x1c, | ||
12871 | 0x34, 0x1d, 0x4c, 0x33, 0x31, 0xdf, 0x07, 0x06, 0x23, 0x4c, 0x01, 0xf1, | ||
12872 | 0xfe, 0x42, 0x58, 0xf1, | ||
12873 | 0xfe, 0xa4, 0x14, 0x8c, 0xfe, 0x4a, 0xf4, 0x0a, 0x17, 0x4c, 0xfe, 0x4a, | ||
12874 | 0xf4, 0x06, 0xea, 0x32, | ||
12875 | 0x07, 0xa5, 0x8b, 0x02, 0x72, 0x03, 0x45, 0xc1, 0x0c, 0x45, 0x67, 0x2d, | ||
12876 | 0x01, 0x0b, 0x26, 0x89, | ||
12877 | 0x01, 0xfe, 0xcc, 0x15, 0x02, 0x89, 0x0f, 0x06, 0x27, 0xfe, 0xbe, 0x13, | ||
12878 | 0x26, 0xfe, 0xd4, 0x13, | ||
12879 | 0x76, 0xfe, 0x89, 0x48, 0x01, 0x0b, 0x21, 0x76, 0x04, 0x7b, 0xfe, 0xd0, | ||
12880 | 0x13, 0x1c, 0xfe, 0xd0, | ||
12881 | 0x13, 0x1d, 0xfe, 0xbe, 0x13, 0x67, 0x2d, 0x01, 0x0b, 0xfe, 0xd5, 0x10, | ||
12882 | 0x0f, 0x71, 0xff, 0x02, | ||
12883 | 0x00, 0x57, 0x52, 0x93, 0x1e, 0xfe, 0xff, 0x7f, 0xfe, 0x30, 0x56, 0xfe, | ||
12884 | 0x00, 0x5c, 0x04, 0x0f, | ||
12885 | 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x1e, 0x43, 0xfe, 0x30, 0x56, | ||
12886 | 0xfe, 0x00, 0x5c, 0x04, | ||
12887 | 0x0f, 0x71, 0xff, 0x02, 0x00, 0x57, 0x52, 0x93, 0x04, 0x0f, 0x71, 0xff, | ||
12888 | 0x02, 0x00, 0x57, 0x52, | ||
12889 | 0x93, 0xfe, 0x0b, 0x58, 0x04, 0x09, 0x5c, 0x01, 0x87, 0x09, 0x45, 0x01, | ||
12890 | 0x87, 0x04, 0xfe, 0x03, | ||
12891 | 0xa1, 0x1e, 0x11, 0xff, 0x03, 0x00, 0x54, 0xfe, 0x00, 0xf4, 0x1f, 0x52, | ||
12892 | 0xfe, 0x00, 0x7d, 0xfe, | ||
12893 | 0x01, 0x7d, 0xfe, 0x02, 0x7d, 0xfe, 0x03, 0x7c, 0x6a, 0x2a, 0x0c, 0x5e, | ||
12894 | 0x14, 0x5f, 0x57, 0x3f, | ||
12895 | 0x7d, 0x40, 0x04, 0xdd, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, | ||
12896 | 0x5a, 0x8d, 0x04, 0x01, | ||
12897 | 0xfe, 0x0c, 0x19, 0xfe, 0x42, 0x48, 0x50, 0x51, 0x91, 0x01, 0x0b, 0x1d, | ||
12898 | 0xfe, 0x96, 0x15, 0x33, | ||
12899 | 0x31, 0xe1, 0x01, 0x0b, 0x1d, 0xfe, 0x96, 0x15, 0x33, 0x31, 0xfe, 0xe8, | ||
12900 | 0x0a, 0xfe, 0xc1, 0x59, | ||
12901 | 0x03, 0xcd, 0x28, 0xfe, 0xcc, 0x12, 0x53, 0x05, 0x1a, 0xfe, 0xc4, 0x13, | ||
12902 | 0x21, 0x69, 0x1a, 0xee, | ||
12903 | 0x55, 0xca, 0x6b, 0xfe, 0xdc, 0x14, 0x4d, 0x0f, 0x06, 0x18, 0xca, 0x7c, | ||
12904 | 0x30, 0xfe, 0x78, 0x10, | ||
12905 | 0xff, 0x02, 0x83, 0x55, 0xab, 0xff, 0x02, 0x83, 0x55, 0x69, 0x19, 0xae, | ||
12906 | 0x98, 0xfe, 0x30, 0x00, | ||
12907 | 0x96, 0xf2, 0x18, 0x6d, 0x0f, 0x06, 0xfe, 0x56, 0x10, 0x69, 0x0a, 0xed, | ||
12908 | 0x98, 0xfe, 0x64, 0x00, | ||
12909 | 0x96, 0xf2, 0x09, 0xfe, 0x64, 0x00, 0x18, 0x9e, 0x0f, 0x06, 0xfe, 0x28, | ||
12910 | 0x10, 0x69, 0x06, 0xfe, | ||
12911 | 0x60, 0x13, 0x98, 0xfe, 0xc8, 0x00, 0x96, 0xf2, 0x09, 0xfe, 0xc8, 0x00, | ||
12912 | 0x18, 0x59, 0x0f, 0x06, | ||
12913 | 0x88, 0x98, 0xfe, 0x90, 0x01, 0x7a, 0xfe, 0x42, 0x15, 0x91, 0xe4, 0xfe, | ||
12914 | 0x43, 0xf4, 0x9f, 0xfe, | ||
12915 | 0x56, 0xf0, 0xfe, 0x54, 0x15, 0xfe, 0x04, 0xf4, 0x71, 0xfe, 0x43, 0xf4, | ||
12916 | 0x9e, 0xfe, 0xf3, 0x10, | ||
12917 | 0xfe, 0x40, 0x5c, 0x01, 0xfe, 0x16, 0x14, 0x1e, 0x43, 0xec, 0xfe, 0x00, | ||
12918 | 0x17, 0xfe, 0x4d, 0xe4, | ||
12919 | 0x6e, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0x6e, 0xfe, 0x1c, 0x10, 0xfe, 0x00, | ||
12920 | 0x17, 0xfe, 0x4d, 0xe4, | ||
12921 | 0xcc, 0x7a, 0xfe, 0x90, 0x15, 0xc4, 0xcc, 0x88, 0x51, 0x21, 0xfe, 0x4d, | ||
12922 | 0xf4, 0x00, 0xe9, 0x91, | ||
12923 | 0x0f, 0x06, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, 0x58, 0x04, 0x51, 0x0f, 0x0a, | ||
12924 | 0x04, 0x16, 0x06, 0x01, | ||
12925 | 0x0b, 0x26, 0xf3, 0x16, 0x0a, 0x01, 0x0b, 0x26, 0xf3, 0x16, 0x19, 0x01, | ||
12926 | 0x0b, 0x26, 0xf3, 0x76, | ||
12927 | 0xfe, 0x89, 0x49, 0x01, 0x0b, 0x04, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, | ||
12928 | 0x16, 0x19, 0x01, 0x0b, | ||
12929 | 0x26, 0xb1, 0x16, 0x06, 0x01, 0x0b, 0x26, 0xb1, 0xfe, 0x89, 0x49, 0x01, | ||
12930 | 0x0b, 0x26, 0xb1, 0x76, | ||
12931 | 0xfe, 0x89, 0x4a, 0x01, 0x0b, 0x04, 0x51, 0x04, 0x22, 0xd3, 0x07, 0x06, | ||
12932 | 0xfe, 0x48, 0x13, 0xb8, | ||
12933 | 0x13, 0xd3, 0xfe, 0x49, 0xf4, 0x00, 0x4d, 0x76, 0xa9, 0x67, 0xfe, 0x01, | ||
12934 | 0xec, 0xfe, 0x27, 0x01, | ||
12935 | 0xfe, 0x89, 0x48, 0xff, 0x02, 0x00, 0x10, 0x27, 0xfe, 0x2e, 0x16, 0x32, | ||
12936 | 0x07, 0xfe, 0xe3, 0x00, | ||
12937 | 0xfe, 0x20, 0x13, 0x1d, 0xfe, 0x52, 0x16, 0x21, 0x13, 0xd4, 0x01, 0x4b, | ||
12938 | 0x22, 0xd4, 0x07, 0x06, | ||
12939 | 0x4e, 0x08, 0x54, 0x06, 0x37, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfb, 0x8e, | ||
12940 | 0x07, 0x11, 0xae, 0x09, | ||
12941 | 0x84, 0x01, 0x0e, 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x84, 0x01, | ||
12942 | 0x0e, 0x8e, 0xfe, 0x80, | ||
12943 | 0xe7, 0x11, 0x07, 0x11, 0x8a, 0xfe, 0x45, 0x58, 0x01, 0xf0, 0x8e, 0x04, | ||
12944 | 0x09, 0x48, 0x01, 0x0e, | ||
12945 | 0x8e, 0x09, 0x5d, 0x01, 0xa8, 0x04, 0x09, 0x48, 0x01, 0x0e, 0xfe, 0x80, | ||
12946 | 0x80, 0xfe, 0x80, 0x4c, | ||
12947 | 0xfe, 0x49, 0xe4, 0x11, 0xae, 0x09, 0x84, 0x01, 0x0e, 0xfe, 0x80, 0x4c, | ||
12948 | 0x09, 0x5d, 0x01, 0x87, | ||
12949 | 0x04, 0x18, 0x11, 0x75, 0x6c, 0xfe, 0x60, 0x01, 0xfe, 0x18, 0xdf, 0xfe, | ||
12950 | 0x19, 0xde, 0xfe, 0x24, | ||
12951 | 0x1c, 0xfe, 0x1d, 0xf7, 0x1b, 0x97, 0xfe, 0xee, 0x16, 0x01, 0xfe, 0xf4, | ||
12952 | 0x17, 0xad, 0x9a, 0x1b, | ||
12953 | 0x6c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x04, 0xb9, 0x23, 0xfe, 0xde, | ||
12954 | 0x16, 0xfe, 0xda, 0x10, | ||
12955 | 0x18, 0x11, 0x75, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x1f, 0xfe, | ||
12956 | 0x18, 0x58, 0x03, 0xfe, | ||
12957 | 0x66, 0x01, 0xfe, 0x19, 0x58, 0x9a, 0x1f, 0xfe, 0x3c, 0x90, 0xfe, 0x30, | ||
12958 | 0xf4, 0x06, 0xfe, 0x3c, | ||
12959 | 0x50, 0x6c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, 0x1f, | ||
12960 | 0x97, 0xfe, 0x38, 0x17, | ||
12961 | 0xfe, 0xb6, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x10, 0x17, 0xfe, 0x9c, | ||
12962 | 0x10, 0x18, 0x11, 0x75, | ||
12963 | 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, 0x1d, 0xf7, | ||
12964 | 0x2e, 0x97, 0xfe, 0x5a, | ||
12965 | 0x17, 0xfe, 0x94, 0x14, 0xec, 0x9a, 0x2e, 0x6c, 0x1a, 0xfe, 0xaf, 0x19, | ||
12966 | 0xfe, 0x98, 0xe7, 0x00, | ||
12967 | 0x04, 0xb9, 0x23, 0xfe, 0x4e, 0x17, 0xfe, 0x6c, 0x10, 0x18, 0x11, 0x75, | ||
12968 | 0xfe, 0x30, 0xbc, 0xfe, | ||
12969 | 0xb2, 0xbc, 0x9a, 0xcb, 0x6c, 0x1a, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, 0xf7, | ||
12970 | 0xcb, 0x97, 0xfe, 0x92, | ||
12971 | 0x17, 0xfe, 0x5c, 0x14, 0x35, 0x04, 0xb9, 0x23, 0xfe, 0x7e, 0x17, 0xfe, | ||
12972 | 0x42, 0x10, 0xfe, 0x02, | ||
12973 | 0xf6, 0x11, 0x75, 0xfe, 0x18, 0xfe, 0x60, 0xfe, 0x19, 0xfe, 0x61, 0xfe, | ||
12974 | 0x03, 0xa1, 0xfe, 0x1d, | ||
12975 | 0xf7, 0x5b, 0x97, 0xfe, 0xb8, 0x17, 0xfe, 0x36, 0x14, 0xfe, 0x1c, 0x13, | ||
12976 | 0x9a, 0x5b, 0x41, 0xfe, | ||
12977 | 0x83, 0x58, 0xfe, 0xaf, 0x19, 0xfe, 0x80, 0xe7, 0x11, 0xfe, 0x81, 0xe7, | ||
12978 | 0x11, 0x12, 0xfe, 0xdd, | ||
12979 | 0x00, 0x6a, 0x2a, 0x04, 0x6a, 0x2a, 0xfe, 0x12, 0x45, 0x23, 0xfe, 0xa8, | ||
12980 | 0x17, 0x15, 0x06, 0x39, | ||
12981 | 0xa0, 0xb4, 0x02, 0x2b, 0xfe, 0x39, 0xf0, 0xfe, 0xfc, 0x17, 0x21, 0x04, | ||
12982 | 0xfe, 0x7e, 0x18, 0x1e, | ||
12983 | 0x19, 0x66, 0x0f, 0x0d, 0x04, 0x75, 0x03, 0xd2, 0x1e, 0x06, 0xfe, 0xef, | ||
12984 | 0x12, 0xfe, 0xe1, 0x10, | ||
12985 | 0x7c, 0x6f, 0x4f, 0x32, 0x07, 0x2f, 0xfe, 0x3c, 0x13, 0xf1, 0xfe, 0x42, | ||
12986 | 0x13, 0x42, 0x92, 0x09, | ||
12987 | 0x48, 0x01, 0x0e, 0xbb, 0xeb, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, | ||
12988 | 0xf0, 0xfe, 0x00, 0xcc, | ||
12989 | 0xbb, 0xfe, 0xf3, 0x13, 0x43, 0x78, 0x07, 0x11, 0xac, 0x09, 0x84, 0x01, | ||
12990 | 0x0e, 0xfe, 0x80, 0x4c, | ||
12991 | 0x01, 0x73, 0xfe, 0x16, 0x10, 0x07, 0x82, 0x8b, 0xfe, 0x40, 0x14, 0xfe, | ||
12992 | 0x24, 0x12, 0xfe, 0x14, | ||
12993 | 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0x1c, 0x18, 0x18, 0x0a, 0x04, 0xfe, 0x9c, | ||
12994 | 0xe7, 0x0a, 0x10, 0xfe, | ||
12995 | 0x15, 0x00, 0x64, 0x79, 0x2a, 0x01, 0xe3, 0x18, 0x06, 0x04, 0x42, 0x92, | ||
12996 | 0x08, 0x54, 0x1b, 0x37, | ||
12997 | 0x12, 0x2f, 0x01, 0x73, 0x18, 0x06, 0x04, 0xfe, 0x38, 0x90, 0xfe, 0xba, | ||
12998 | 0x90, 0x3a, 0xce, 0x3b, | ||
12999 | 0xcf, 0xfe, 0x48, 0x55, 0x35, 0xfe, 0xc9, 0x55, 0x04, 0x22, 0xa3, 0x77, | ||
13000 | 0x13, 0xa3, 0x04, 0x09, | ||
13001 | 0xa4, 0x01, 0x0e, 0xfe, 0x41, 0x48, 0x09, 0x46, 0x01, 0x0e, 0xfe, 0x49, | ||
13002 | 0x44, 0x17, 0xfe, 0xe8, | ||
13003 | 0x18, 0x77, 0x78, 0x04, 0x09, 0x48, 0x01, 0x0e, 0x07, 0x11, 0x4e, 0x09, | ||
13004 | 0x5d, 0x01, 0xa8, 0x09, | ||
13005 | 0x46, 0x01, 0x0e, 0x77, 0x78, 0x04, 0xfe, 0x4e, 0xe4, 0x19, 0x6b, 0xfe, | ||
13006 | 0x1c, 0x19, 0x03, 0xfe, | ||
13007 | 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, 0x4e, 0xe4, 0xc9, | ||
13008 | 0x6b, 0xfe, 0x2e, 0x19, | ||
13009 | 0x03, 0xfe, 0x92, 0x00, 0xfe, 0x02, 0xe6, 0x1a, 0xe5, 0xfe, 0x4e, 0xe4, | ||
13010 | 0xfe, 0x0b, 0x00, 0x6b, | ||
13011 | 0xfe, 0x40, 0x19, 0x03, 0xfe, 0x94, 0x00, 0xfe, 0x02, 0xe6, 0x1f, 0xfe, | ||
13012 | 0x08, 0x10, 0x03, 0xfe, | ||
13013 | 0x96, 0x00, 0xfe, 0x02, 0xe6, 0x6d, 0xfe, 0x4e, 0x45, 0xea, 0xba, 0xff, | ||
13014 | 0x04, 0x68, 0x54, 0xe7, | ||
13015 | 0x1e, 0x6e, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, 0xfe, | ||
13016 | 0x1a, 0xf4, 0xfe, 0x00, | ||
13017 | 0x04, 0xea, 0xfe, 0x48, 0xf4, 0x19, 0x7a, 0xfe, 0x74, 0x19, 0x0f, 0x19, | ||
13018 | 0x04, 0x07, 0x7e, 0xfe, | ||
13019 | 0x5a, 0xf0, 0xfe, 0x84, 0x19, 0x25, 0xfe, 0x09, 0x00, 0xfe, 0x34, 0x10, | ||
13020 | 0x07, 0x1a, 0xfe, 0x5a, | ||
13021 | 0xf0, 0xfe, 0x92, 0x19, 0x25, 0xca, 0xfe, 0x26, 0x10, 0x07, 0x19, 0x66, | ||
13022 | 0x25, 0x6d, 0xe5, 0x07, | ||
13023 | 0x0a, 0x66, 0x25, 0x9e, 0xfe, 0x0e, 0x10, 0x07, 0x06, 0x66, 0x25, 0x59, | ||
13024 | 0xa9, 0xb8, 0x04, 0x15, | ||
13025 | 0xfe, 0x09, 0x00, 0x01, 0x36, 0xfe, 0x04, 0xfe, 0x81, 0x03, 0x83, 0xfe, | ||
13026 | 0x40, 0x5c, 0x04, 0x1c, | ||
13027 | 0xf7, 0xfe, 0x14, 0xf0, 0x0b, 0x27, 0xfe, 0xd6, 0x19, 0x1c, 0xf7, 0x7b, | ||
13028 | 0xf7, 0xfe, 0x82, 0xf0, | ||
13029 | 0xfe, 0xda, 0x19, 0x04, 0xff, 0xcc, 0x00, 0x00, | ||
13030 | }; | ||
13031 | 11843 | ||
13032 | static unsigned short _adv_asc38C0800_size = sizeof(_adv_asc38C0800_buf); /* 0x14E1 */ | 11844 | switch (warn_code) { |
13033 | static ADV_DCNT _adv_asc38C0800_chksum = 0x050D3FD8UL; /* Expanded little-endian checksum. */ | 11845 | case 0: /* No error. */ |
11846 | break; | ||
11847 | case ASC_WARN_IO_PORT_ROTATE: | ||
11848 | shost_printk(KERN_WARNING, shost, "I/O port address " | ||
11849 | "modified\n"); | ||
11850 | break; | ||
11851 | case ASC_WARN_AUTO_CONFIG: | ||
11852 | shost_printk(KERN_WARNING, shost, "I/O port increment switch " | ||
11853 | "enabled\n"); | ||
11854 | break; | ||
11855 | case ASC_WARN_EEPROM_CHKSUM: | ||
11856 | shost_printk(KERN_WARNING, shost, "EEPROM checksum error\n"); | ||
11857 | break; | ||
11858 | case ASC_WARN_IRQ_MODIFIED: | ||
11859 | shost_printk(KERN_WARNING, shost, "IRQ modified\n"); | ||
11860 | break; | ||
11861 | case ASC_WARN_CMD_QNG_CONFLICT: | ||
11862 | shost_printk(KERN_WARNING, shost, "tag queuing w/o " | ||
11863 | "disconnects\n"); | ||
11864 | break; | ||
11865 | default: | ||
11866 | shost_printk(KERN_WARNING, shost, "unknown warning: 0x%x\n", | ||
11867 | warn_code); | ||
11868 | break; | ||
11869 | } | ||
13034 | 11870 | ||
13035 | /* Microcode buffer is kept after initialization for error recovery. */ | 11871 | if (asc_dvc->err_code != 0) |
13036 | static unsigned char _adv_asc38C1600_buf[] = { | 11872 | shost_printk(KERN_ERR, shost, "error 0x%x at init_state " |
13037 | 0x00, 0x00, 0x00, 0xf2, 0x00, 0x16, 0x00, 0xfc, 0x00, 0x10, 0x00, 0xf0, | 11873 | "0x%x\n", asc_dvc->err_code, asc_dvc->init_state); |
13038 | 0x18, 0xe4, 0x01, 0x00, | ||
13039 | 0x04, 0x1e, 0x48, 0xe4, 0x03, 0xf6, 0xf7, 0x13, 0x2e, 0x1e, 0x02, 0x00, | ||
13040 | 0x07, 0x17, 0xc0, 0x5f, | ||
13041 | 0x00, 0xfa, 0xff, 0xff, 0x04, 0x00, 0x00, 0xf6, 0x09, 0xe7, 0x82, 0xe7, | ||
13042 | 0x85, 0xf0, 0x86, 0xf0, | ||
13043 | 0x4e, 0x10, 0x9e, 0xe7, 0xff, 0x00, 0x55, 0xf0, 0x01, 0xf6, 0x03, 0x00, | ||
13044 | 0x98, 0x57, 0x01, 0xe6, | ||
13045 | 0x00, 0xea, 0x00, 0xec, 0x01, 0xfa, 0x18, 0xf4, 0x08, 0x00, 0xf0, 0x1d, | ||
13046 | 0x38, 0x54, 0x32, 0xf0, | ||
13047 | 0x10, 0x00, 0xc2, 0x0e, 0x1e, 0xf0, 0xd5, 0xf0, 0xbc, 0x00, 0x4b, 0xe4, | ||
13048 | 0x00, 0xe6, 0xb1, 0xf0, | ||
13049 | 0xb4, 0x00, 0x02, 0x13, 0x3e, 0x1c, 0xc8, 0x47, 0x3e, 0x00, 0xd8, 0x01, | ||
13050 | 0x06, 0x13, 0x0c, 0x1c, | ||
13051 | 0x5e, 0x1e, 0x00, 0x57, 0xc8, 0x57, 0x01, 0xfc, 0xbc, 0x0e, 0xa2, 0x12, | ||
13052 | 0xb9, 0x54, 0x00, 0x80, | ||
13053 | 0x62, 0x0a, 0x5a, 0x12, 0xc8, 0x15, 0x3e, 0x1e, 0x18, 0x40, 0xbd, 0x56, | ||
13054 | 0x03, 0xe6, 0x01, 0xea, | ||
13055 | 0x5c, 0xf0, 0x0f, 0x00, 0x20, 0x00, 0x6c, 0x01, 0x6e, 0x01, 0x04, 0x12, | ||
13056 | 0x04, 0x13, 0xbb, 0x55, | ||
13057 | 0x3c, 0x56, 0x3e, 0x57, 0x03, 0x58, 0x4a, 0xe4, 0x40, 0x00, 0xb6, 0x00, | ||
13058 | 0xbb, 0x00, 0xc0, 0x00, | ||
13059 | 0x00, 0x01, 0x01, 0x01, 0x3e, 0x01, 0x58, 0x0a, 0x44, 0x10, 0x0a, 0x12, | ||
13060 | 0x4c, 0x1c, 0x4e, 0x1c, | ||
13061 | 0x02, 0x4a, 0x30, 0xe4, 0x05, 0xe6, 0x0c, 0x00, 0x3c, 0x00, 0x80, 0x00, | ||
13062 | 0x24, 0x01, 0x3c, 0x01, | ||
13063 | 0x68, 0x01, 0x6a, 0x01, 0x70, 0x01, 0x72, 0x01, 0x74, 0x01, 0x76, 0x01, | ||
13064 | 0x78, 0x01, 0x7c, 0x01, | ||
13065 | 0xc6, 0x0e, 0x0c, 0x10, 0xac, 0x12, 0xae, 0x12, 0x16, 0x1a, 0x32, 0x1c, | ||
13066 | 0x6e, 0x1e, 0x02, 0x48, | ||
13067 | 0x3a, 0x55, 0xc9, 0x57, 0x02, 0xee, 0x5b, 0xf0, 0x03, 0xf7, 0x06, 0xf7, | ||
13068 | 0x03, 0xfc, 0x06, 0x00, | ||
13069 | 0x1e, 0x00, 0xbe, 0x00, 0xe1, 0x00, 0x0c, 0x12, 0x18, 0x1a, 0x70, 0x1a, | ||
13070 | 0x30, 0x1c, 0x38, 0x1c, | ||
13071 | 0x10, 0x44, 0x00, 0x4c, 0xb0, 0x57, 0x40, 0x5c, 0x4d, 0xe4, 0x04, 0xea, | ||
13072 | 0x5d, 0xf0, 0xa7, 0xf0, | ||
13073 | 0x04, 0xf6, 0x02, 0xfc, 0x05, 0x00, 0x09, 0x00, 0x19, 0x00, 0x32, 0x00, | ||
13074 | 0x33, 0x00, 0x34, 0x00, | ||
13075 | 0x36, 0x00, 0x98, 0x00, 0x9e, 0x00, 0xcc, 0x00, 0x20, 0x01, 0x4e, 0x01, | ||
13076 | 0x79, 0x01, 0x3c, 0x09, | ||
13077 | 0x68, 0x0d, 0x02, 0x10, 0x04, 0x10, 0x3a, 0x10, 0x08, 0x12, 0x0a, 0x13, | ||
13078 | 0x40, 0x16, 0x50, 0x16, | ||
13079 | 0x00, 0x17, 0x4a, 0x19, 0x00, 0x4e, 0x00, 0x54, 0x01, 0x58, 0x00, 0xdc, | ||
13080 | 0x05, 0xf0, 0x09, 0xf0, | ||
13081 | 0x59, 0xf0, 0xb8, 0xf0, 0x48, 0xf4, 0x0e, 0xf7, 0x0a, 0x00, 0x9b, 0x00, | ||
13082 | 0x9c, 0x00, 0xa4, 0x00, | ||
13083 | 0xb5, 0x00, 0xba, 0x00, 0xd0, 0x00, 0xe7, 0x00, 0xf0, 0x03, 0x69, 0x08, | ||
13084 | 0xe9, 0x09, 0x5c, 0x0c, | ||
13085 | 0xb6, 0x12, 0xbc, 0x19, 0xd8, 0x1b, 0x20, 0x1c, 0x34, 0x1c, 0x36, 0x1c, | ||
13086 | 0x42, 0x1d, 0x08, 0x44, | ||
13087 | 0x38, 0x44, 0x91, 0x44, 0x0a, 0x45, 0x48, 0x46, 0x89, 0x48, 0x68, 0x54, | ||
13088 | 0x83, 0x55, 0x83, 0x59, | ||
13089 | 0x31, 0xe4, 0x02, 0xe6, 0x07, 0xf0, 0x08, 0xf0, 0x0b, 0xf0, 0x0c, 0xf0, | ||
13090 | 0x4b, 0xf4, 0x04, 0xf8, | ||
13091 | 0x05, 0xf8, 0x02, 0xfa, 0x03, 0xfa, 0x04, 0xfc, 0x05, 0xfc, 0x07, 0x00, | ||
13092 | 0xa8, 0x00, 0xaa, 0x00, | ||
13093 | 0xb9, 0x00, 0xe0, 0x00, 0xe5, 0x00, 0x22, 0x01, 0x26, 0x01, 0x60, 0x01, | ||
13094 | 0x7a, 0x01, 0x82, 0x01, | ||
13095 | 0xc8, 0x01, 0xca, 0x01, 0x86, 0x02, 0x6a, 0x03, 0x18, 0x05, 0xb2, 0x07, | ||
13096 | 0x68, 0x08, 0x10, 0x0d, | ||
13097 | 0x06, 0x10, 0x0a, 0x10, 0x0e, 0x10, 0x12, 0x10, 0x60, 0x10, 0xed, 0x10, | ||
13098 | 0xf3, 0x10, 0x06, 0x12, | ||
13099 | 0x10, 0x12, 0x1e, 0x12, 0x0c, 0x13, 0x0e, 0x13, 0x10, 0x13, 0xfe, 0x9c, | ||
13100 | 0xf0, 0x35, 0x05, 0xfe, | ||
13101 | 0xec, 0x0e, 0xff, 0x10, 0x00, 0x00, 0xe9, 0xfe, 0x34, 0x1f, 0x00, 0xe8, | ||
13102 | 0xfe, 0x88, 0x01, 0xff, | ||
13103 | 0x03, 0x00, 0x00, 0xfe, 0x93, 0x15, 0xfe, 0x0f, 0x05, 0xff, 0x38, 0x00, | ||
13104 | 0x00, 0xfe, 0x57, 0x24, | ||
13105 | 0x00, 0xfe, 0x4c, 0x00, 0x65, 0xff, 0x04, 0x00, 0x00, 0x1a, 0xff, 0x09, | ||
13106 | 0x00, 0x00, 0xff, 0x08, | ||
13107 | 0x01, 0x01, 0xff, 0x08, 0xff, 0xff, 0xff, 0x27, 0x00, 0x00, 0xff, 0x10, | ||
13108 | 0xff, 0xff, 0xff, 0x13, | ||
13109 | 0x00, 0x00, 0xfe, 0x78, 0x56, 0xfe, 0x34, 0x12, 0xff, 0x21, 0x00, 0x00, | ||
13110 | 0xfe, 0x04, 0xf7, 0xe8, | ||
13111 | 0x37, 0x7d, 0x0d, 0x01, 0xfe, 0x4a, 0x11, 0xfe, 0x04, 0xf7, 0xe8, 0x7d, | ||
13112 | 0x0d, 0x51, 0x37, 0xfe, | ||
13113 | 0x3d, 0xf0, 0xfe, 0x0c, 0x02, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x91, 0xf0, | ||
13114 | 0xfe, 0xf8, 0x01, 0xfe, | ||
13115 | 0x90, 0xf0, 0xfe, 0xf8, 0x01, 0xfe, 0x8f, 0xf0, 0xbc, 0x03, 0x67, 0x4d, | ||
13116 | 0x05, 0xfe, 0x08, 0x0f, | ||
13117 | 0x01, 0xfe, 0x78, 0x0f, 0xfe, 0xdd, 0x12, 0x05, 0xfe, 0x0e, 0x03, 0xfe, | ||
13118 | 0x28, 0x1c, 0x03, 0xfe, | ||
13119 | 0xa6, 0x00, 0xfe, 0xd1, 0x12, 0x3e, 0x22, 0xfe, 0xa6, 0x00, 0xac, 0xfe, | ||
13120 | 0x48, 0xf0, 0xfe, 0x90, | ||
13121 | 0x02, 0xfe, 0x49, 0xf0, 0xfe, 0xaa, 0x02, 0xfe, 0x4a, 0xf0, 0xfe, 0xc8, | ||
13122 | 0x02, 0xfe, 0x46, 0xf0, | ||
13123 | 0xfe, 0x5a, 0x02, 0xfe, 0x47, 0xf0, 0xfe, 0x60, 0x02, 0xfe, 0x43, 0xf0, | ||
13124 | 0xfe, 0x4e, 0x02, 0xfe, | ||
13125 | 0x44, 0xf0, 0xfe, 0x52, 0x02, 0xfe, 0x45, 0xf0, 0xfe, 0x56, 0x02, 0x1c, | ||
13126 | 0x0d, 0xa2, 0x1c, 0x07, | ||
13127 | 0x22, 0xb7, 0x05, 0x35, 0xfe, 0x00, 0x1c, 0xfe, 0xf1, 0x10, 0xfe, 0x02, | ||
13128 | 0x1c, 0xf5, 0xfe, 0x1e, | ||
13129 | 0x1c, 0xfe, 0xe9, 0x10, 0x01, 0x5f, 0xfe, 0xe7, 0x10, 0xfe, 0x06, 0xfc, | ||
13130 | 0xde, 0x0a, 0x81, 0x01, | ||
13131 | 0xa3, 0x05, 0x35, 0x1f, 0x95, 0x47, 0xb8, 0x01, 0xfe, 0xe4, 0x11, 0x0a, | ||
13132 | 0x81, 0x01, 0x5c, 0xfe, | ||
13133 | 0xbd, 0x10, 0x0a, 0x81, 0x01, 0x5c, 0xfe, 0xad, 0x10, 0xfe, 0x16, 0x1c, | ||
13134 | 0xfe, 0x58, 0x1c, 0x1c, | ||
13135 | 0x07, 0x22, 0xb7, 0x37, 0x2a, 0x35, 0xfe, 0x3d, 0xf0, 0xfe, 0x0c, 0x02, | ||
13136 | 0x2b, 0xfe, 0x9e, 0x02, | ||
13137 | 0xfe, 0x5a, 0x1c, 0xfe, 0x12, 0x1c, 0xfe, 0x14, 0x1c, 0x1f, 0xfe, 0x30, | ||
13138 | 0x00, 0x47, 0xb8, 0x01, | ||
13139 | 0xfe, 0xd4, 0x11, 0x1c, 0x07, 0x22, 0xb7, 0x05, 0xe9, 0x21, 0x2c, 0x09, | ||
13140 | 0x1a, 0x31, 0xfe, 0x69, | ||
13141 | 0x10, 0x1c, 0x07, 0x22, 0xb7, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0x01, 0xfe, | ||
13142 | 0x1e, 0x1e, 0x20, 0x2c, | ||
13143 | 0xfe, 0x05, 0xf6, 0xde, 0x01, 0xfe, 0x62, 0x1b, 0x01, 0x0c, 0x61, 0x4a, | ||
13144 | 0x44, 0x15, 0x56, 0x51, | ||
13145 | 0x01, 0xfe, 0x9e, 0x1e, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x0a, 0x57, | ||
13146 | 0x01, 0x18, 0x09, 0x00, | ||
13147 | 0x36, 0x01, 0x85, 0xfe, 0x18, 0x10, 0xfe, 0x41, 0x58, 0x0a, 0xba, 0x01, | ||
13148 | 0x18, 0xfe, 0xc8, 0x54, | ||
13149 | 0x7b, 0xfe, 0x1c, 0x03, 0x01, 0xfe, 0x96, 0x1a, 0x05, 0x35, 0x37, 0x60, | ||
13150 | 0xfe, 0x02, 0xe8, 0x30, | ||
13151 | 0xfe, 0xbf, 0x57, 0xfe, 0x9e, 0x43, 0xfe, 0x77, 0x57, 0xfe, 0x27, 0xf0, | ||
13152 | 0xfe, 0xe4, 0x01, 0xfe, | ||
13153 | 0x07, 0x4b, 0xfe, 0x20, 0xf0, 0xbc, 0xfe, 0x40, 0x1c, 0x2a, 0xeb, 0xfe, | ||
13154 | 0x26, 0xf0, 0xfe, 0x66, | ||
13155 | 0x03, 0xfe, 0xa0, 0xf0, 0xfe, 0x54, 0x03, 0xfe, 0x11, 0xf0, 0xbc, 0xfe, | ||
13156 | 0xef, 0x10, 0xfe, 0x9f, | ||
13157 | 0xf0, 0xfe, 0x74, 0x03, 0xfe, 0x46, 0x1c, 0x19, 0xfe, 0x11, 0x00, 0x05, | ||
13158 | 0x70, 0x37, 0xfe, 0x48, | ||
13159 | 0x1c, 0xfe, 0x46, 0x1c, 0x01, 0x0c, 0x06, 0x28, 0xfe, 0x18, 0x13, 0x26, | ||
13160 | 0x21, 0xb9, 0xc7, 0x20, | ||
13161 | 0xb9, 0x0a, 0x57, 0x01, 0x18, 0xc7, 0x89, 0x01, 0xfe, 0xc8, 0x1a, 0x15, | ||
13162 | 0xe1, 0x2a, 0xeb, 0xfe, | ||
13163 | 0x01, 0xf0, 0xeb, 0xfe, 0x82, 0xf0, 0xfe, 0xa4, 0x03, 0xfe, 0x9c, 0x32, | ||
13164 | 0x15, 0xfe, 0xe4, 0x00, | ||
13165 | 0x2f, 0xfe, 0xb6, 0x03, 0x2a, 0x3c, 0x16, 0xfe, 0xc6, 0x03, 0x01, 0x41, | ||
13166 | 0xfe, 0x06, 0xf0, 0xfe, | ||
13167 | 0xd6, 0x03, 0xaf, 0xa0, 0xfe, 0x0a, 0xf0, 0xfe, 0xa2, 0x07, 0x05, 0x29, | ||
13168 | 0x03, 0x81, 0x1e, 0x1b, | ||
13169 | 0xfe, 0x24, 0x05, 0x1f, 0x63, 0x01, 0x42, 0x8f, 0xfe, 0x70, 0x02, 0x05, | ||
13170 | 0xea, 0xfe, 0x46, 0x1c, | ||
13171 | 0x37, 0x7d, 0x1d, 0xfe, 0x67, 0x1b, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, | ||
13172 | 0xfe, 0x48, 0x1c, 0x75, | ||
13173 | 0x01, 0xa6, 0x86, 0x0a, 0x57, 0x01, 0x18, 0x09, 0x00, 0x1b, 0xec, 0x0a, | ||
13174 | 0xe1, 0x01, 0x18, 0x77, | ||
13175 | 0x50, 0x40, 0x8d, 0x30, 0x03, 0x81, 0x1e, 0xf8, 0x1f, 0x63, 0x01, 0x42, | ||
13176 | 0x8f, 0xfe, 0x70, 0x02, | ||
13177 | 0x05, 0xea, 0xd7, 0x99, 0xd8, 0x9c, 0x2a, 0x29, 0x2f, 0xfe, 0x4e, 0x04, | ||
13178 | 0x16, 0xfe, 0x4a, 0x04, | ||
13179 | 0x7e, 0xfe, 0xa0, 0x00, 0xfe, 0x9b, 0x57, 0xfe, 0x54, 0x12, 0x32, 0xff, | ||
13180 | 0x02, 0x00, 0x10, 0x01, | ||
13181 | 0x08, 0x16, 0xfe, 0x02, 0x05, 0x32, 0x01, 0x08, 0x16, 0x29, 0x27, 0x25, | ||
13182 | 0xee, 0xfe, 0x4c, 0x44, | ||
13183 | 0xfe, 0x58, 0x12, 0x50, 0xfe, 0x44, 0x48, 0x13, 0x34, 0xfe, 0x4c, 0x54, | ||
13184 | 0x7b, 0xec, 0x60, 0x8d, | ||
13185 | 0x30, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x7c, 0x13, 0x01, | ||
13186 | 0x0c, 0x06, 0x28, 0xfe, | ||
13187 | 0x32, 0x13, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x68, 0x13, 0xfe, 0x26, 0x10, | ||
13188 | 0x13, 0x34, 0xfe, 0x4c, | ||
13189 | 0x54, 0x7b, 0xec, 0x01, 0xfe, 0x4e, 0x1e, 0xfe, 0x48, 0x47, 0xfe, 0x54, | ||
13190 | 0x13, 0x01, 0x0c, 0x06, | ||
13191 | 0x28, 0xa5, 0x01, 0x43, 0x09, 0x9b, 0xfe, 0x40, 0x13, 0x01, 0x0c, 0x06, | ||
13192 | 0x28, 0xf9, 0x1f, 0x7f, | ||
13193 | 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, 0x0d, 0x00, 0x01, 0x42, 0x8f, | ||
13194 | 0xfe, 0xa4, 0x0e, 0x05, | ||
13195 | 0x29, 0x32, 0x15, 0xfe, 0xe6, 0x00, 0x0f, 0xfe, 0x1c, 0x90, 0x04, 0xfe, | ||
13196 | 0x9c, 0x93, 0x3a, 0x0b, | ||
13197 | 0x0e, 0x8b, 0x02, 0x1f, 0x7f, 0x01, 0x42, 0x05, 0x35, 0xfe, 0x42, 0x5b, | ||
13198 | 0x7d, 0x1d, 0xfe, 0x46, | ||
13199 | 0x59, 0xfe, 0xbf, 0x57, 0xfe, 0x77, 0x57, 0x0f, 0xfe, 0x87, 0x80, 0x04, | ||
13200 | 0xfe, 0x87, 0x83, 0xfe, | ||
13201 | 0xc9, 0x47, 0x0b, 0x0e, 0xd0, 0x65, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x98, | ||
13202 | 0x13, 0x0f, 0xfe, 0x20, | ||
13203 | 0x80, 0x04, 0xfe, 0xa0, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x1d, 0xfe, 0x84, | ||
13204 | 0x12, 0x01, 0x38, 0x06, | ||
13205 | 0x07, 0xfe, 0x70, 0x13, 0x03, 0xfe, 0xa2, 0x00, 0x1e, 0x1b, 0xfe, 0xda, | ||
13206 | 0x05, 0xd0, 0x54, 0x01, | ||
13207 | 0x38, 0x06, 0x0d, 0xfe, 0x58, 0x13, 0x03, 0xfe, 0xa0, 0x00, 0x1e, 0xfe, | ||
13208 | 0x50, 0x12, 0x5e, 0xff, | ||
13209 | 0x02, 0x00, 0x10, 0x2f, 0xfe, 0x90, 0x05, 0x2a, 0x3c, 0xcc, 0xff, 0x02, | ||
13210 | 0x00, 0x10, 0x2f, 0xfe, | ||
13211 | 0x9e, 0x05, 0x17, 0xfe, 0xf4, 0x05, 0x15, 0xfe, 0xe3, 0x00, 0x26, 0x01, | ||
13212 | 0x38, 0xfe, 0x4a, 0xf0, | ||
13213 | 0xfe, 0xc0, 0x05, 0xfe, 0x49, 0xf0, 0xfe, 0xba, 0x05, 0x71, 0x2e, 0xfe, | ||
13214 | 0x21, 0x00, 0xf1, 0x2e, | ||
13215 | 0xfe, 0x22, 0x00, 0xa2, 0x2e, 0x4a, 0xfe, 0x09, 0x48, 0xff, 0x02, 0x00, | ||
13216 | 0x10, 0x2f, 0xfe, 0xd0, | ||
13217 | 0x05, 0x17, 0xfe, 0xf4, 0x05, 0xfe, 0xe2, 0x08, 0x01, 0x38, 0x06, 0xfe, | ||
13218 | 0x1c, 0x00, 0x4d, 0x01, | ||
13219 | 0xa7, 0x2e, 0x07, 0x20, 0xe4, 0x47, 0xfe, 0x27, 0x01, 0x01, 0x0c, 0x06, | ||
13220 | 0x28, 0xfe, 0x24, 0x12, | ||
13221 | 0x3e, 0x01, 0x84, 0x1f, 0x7f, 0x01, 0x0c, 0x06, 0x07, 0x4d, 0x1f, 0xfe, | ||
13222 | 0x0d, 0x00, 0x01, 0x42, | ||
13223 | 0x8f, 0xfe, 0xa4, 0x0e, 0x05, 0x29, 0x03, 0xe6, 0x1e, 0xfe, 0xca, 0x13, | ||
13224 | 0x03, 0xb6, 0x1e, 0xfe, | ||
13225 | 0x40, 0x12, 0x03, 0x66, 0x1e, 0xfe, 0x38, 0x13, 0x3e, 0x01, 0x84, 0x17, | ||
13226 | 0xfe, 0x72, 0x06, 0x0a, | ||
13227 | 0x07, 0x01, 0x38, 0x06, 0x24, 0xfe, 0x02, 0x12, 0x4f, 0x01, 0xfe, 0x56, | ||
13228 | 0x19, 0x16, 0xfe, 0x68, | ||
13229 | 0x06, 0x15, 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x66, 0x8a, 0x10, 0x66, | ||
13230 | 0x03, 0x9a, 0x1e, 0xfe, | ||
13231 | 0x70, 0x12, 0x03, 0x55, 0x1e, 0xfe, 0x68, 0x13, 0x01, 0xc6, 0x09, 0x12, | ||
13232 | 0x48, 0xfe, 0x92, 0x06, | ||
13233 | 0x2e, 0x12, 0x01, 0xfe, 0xac, 0x1d, 0xfe, 0x43, 0x48, 0x62, 0x80, 0x13, | ||
13234 | 0x58, 0xff, 0x02, 0x00, | ||
13235 | 0x57, 0x52, 0xad, 0x23, 0x3f, 0x4e, 0x62, 0x49, 0x3e, 0x01, 0x84, 0x17, | ||
13236 | 0xfe, 0xea, 0x06, 0x01, | ||
13237 | 0x38, 0x06, 0x12, 0xf7, 0x45, 0x0a, 0x95, 0x01, 0xfe, 0x84, 0x19, 0x16, | ||
13238 | 0xfe, 0xe0, 0x06, 0x15, | ||
13239 | 0x82, 0x01, 0x41, 0x15, 0xe2, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x1c, 0x07, | ||
13240 | 0x01, 0x84, 0xfe, 0xae, | ||
13241 | 0x10, 0x03, 0x6f, 0x1e, 0xfe, 0x9e, 0x13, 0x3e, 0x01, 0x84, 0x03, 0x9a, | ||
13242 | 0x1e, 0xfe, 0x1a, 0x12, | ||
13243 | 0x01, 0x38, 0x06, 0x12, 0xfc, 0x01, 0xc6, 0x01, 0xfe, 0xac, 0x1d, 0xfe, | ||
13244 | 0x43, 0x48, 0x62, 0x80, | ||
13245 | 0xf0, 0x45, 0x0a, 0x95, 0x03, 0xb6, 0x1e, 0xf8, 0x01, 0x38, 0x06, 0x24, | ||
13246 | 0x36, 0xfe, 0x02, 0xf6, | ||
13247 | 0x07, 0x71, 0x78, 0x8c, 0x00, 0x4d, 0x62, 0x49, 0x3e, 0x2d, 0x93, 0x4e, | ||
13248 | 0xd0, 0x0d, 0x17, 0xfe, | ||
13249 | 0x9a, 0x07, 0x01, 0xfe, 0xc0, 0x19, 0x16, 0xfe, 0x90, 0x07, 0x26, 0x20, | ||
13250 | 0x9e, 0x15, 0x82, 0x01, | ||
13251 | 0x41, 0x15, 0xe2, 0x21, 0x9e, 0x09, 0x07, 0xfb, 0x03, 0xe6, 0xfe, 0x58, | ||
13252 | 0x57, 0x10, 0xe6, 0x05, | ||
13253 | 0xfe, 0x2a, 0x06, 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x1c, 0x07, 0x01, 0x84, | ||
13254 | 0xfe, 0x9c, 0x32, 0x5f, | ||
13255 | 0x75, 0x01, 0xa6, 0x86, 0x15, 0xfe, 0xe2, 0x00, 0x2f, 0xed, 0x2a, 0x3c, | ||
13256 | 0xfe, 0x0a, 0xf0, 0xfe, | ||
13257 | 0xce, 0x07, 0xae, 0xfe, 0x96, 0x08, 0xfe, 0x06, 0xf0, 0xfe, 0x9e, 0x08, | ||
13258 | 0xaf, 0xa0, 0x05, 0x29, | ||
13259 | 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x2e, 0x12, 0x14, 0x1d, 0x01, 0x08, 0x14, | ||
13260 | 0x00, 0x01, 0x08, 0x14, | ||
13261 | 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0xfe, 0x99, 0xa4, 0x01, 0x08, | ||
13262 | 0x14, 0x00, 0x05, 0xfe, | ||
13263 | 0xc6, 0x09, 0x01, 0x76, 0x06, 0x12, 0xfe, 0x3a, 0x12, 0x01, 0x0c, 0x06, | ||
13264 | 0x12, 0xfe, 0x30, 0x13, | ||
13265 | 0x14, 0xfe, 0x1b, 0x00, 0x01, 0x08, 0x14, 0x00, 0x01, 0x08, 0x14, 0x00, | ||
13266 | 0x01, 0x08, 0x14, 0x00, | ||
13267 | 0x01, 0x08, 0x14, 0x07, 0x01, 0x08, 0x14, 0x00, 0x05, 0xef, 0x7c, 0x4a, | ||
13268 | 0x78, 0x4f, 0x0f, 0xfe, | ||
13269 | 0x9a, 0x81, 0x04, 0xfe, 0x9a, 0x83, 0xfe, 0xcb, 0x47, 0x0b, 0x0e, 0x2d, | ||
13270 | 0x28, 0x48, 0xfe, 0x6c, | ||
13271 | 0x08, 0x0a, 0x28, 0xfe, 0x09, 0x6f, 0xca, 0xfe, 0xca, 0x45, 0xfe, 0x32, | ||
13272 | 0x12, 0x53, 0x63, 0x4e, | ||
13273 | 0x7c, 0x97, 0x2f, 0xfe, 0x7e, 0x08, 0x2a, 0x3c, 0xfe, 0x0a, 0xf0, 0xfe, | ||
13274 | 0x6c, 0x08, 0xaf, 0xa0, | ||
13275 | 0xae, 0xfe, 0x96, 0x08, 0x05, 0x29, 0x01, 0x41, 0x05, 0xed, 0x14, 0x24, | ||
13276 | 0x05, 0xed, 0xfe, 0x9c, | ||
13277 | 0xf7, 0x9f, 0x01, 0xfe, 0xae, 0x1e, 0xfe, 0x18, 0x58, 0x01, 0xfe, 0xbe, | ||
13278 | 0x1e, 0xfe, 0x99, 0x58, | ||
13279 | 0xfe, 0x78, 0x18, 0xfe, 0xf9, 0x18, 0x8e, 0xfe, 0x16, 0x09, 0x10, 0x6a, | ||
13280 | 0x22, 0x6b, 0x01, 0x0c, | ||
13281 | 0x61, 0x54, 0x44, 0x21, 0x2c, 0x09, 0x1a, 0xf8, 0x77, 0x01, 0xfe, 0x7e, | ||
13282 | 0x1e, 0x47, 0x2c, 0x7a, | ||
13283 | 0x30, 0xf0, 0xfe, 0x83, 0xe7, 0xfe, 0x3f, 0x00, 0x71, 0xfe, 0x03, 0x40, | ||
13284 | 0x01, 0x0c, 0x61, 0x65, | ||
13285 | 0x44, 0x01, 0xc2, 0xc8, 0xfe, 0x1f, 0x40, 0x20, 0x6e, 0x01, 0xfe, 0x6a, | ||
13286 | 0x16, 0xfe, 0x08, 0x50, | ||
13287 | 0xfe, 0x8a, 0x50, 0xfe, 0x44, 0x51, 0xfe, 0xc6, 0x51, 0xfe, 0x10, 0x10, | ||
13288 | 0x01, 0xfe, 0xce, 0x1e, | ||
13289 | 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x01, 0xfe, 0xee, 0x1e, | ||
13290 | 0x01, 0xfe, 0xfe, 0x1e, | ||
13291 | 0xfe, 0x40, 0x50, 0xfe, 0xc2, 0x50, 0x10, 0x4b, 0x22, 0x4c, 0xfe, 0x8a, | ||
13292 | 0x10, 0x01, 0x0c, 0x06, | ||
13293 | 0x54, 0xfe, 0x50, 0x12, 0x01, 0xfe, 0xae, 0x1e, 0x01, 0xfe, 0xbe, 0x1e, | ||
13294 | 0x10, 0x6a, 0x22, 0x6b, | ||
13295 | 0x01, 0x0c, 0x06, 0x65, 0x4e, 0x01, 0xc2, 0x0f, 0xfe, 0x1f, 0x80, 0x04, | ||
13296 | 0xfe, 0x9f, 0x83, 0x33, | ||
13297 | 0x0b, 0x0e, 0x20, 0x6e, 0x0f, 0xfe, 0x44, 0x90, 0x04, 0xfe, 0xc4, 0x93, | ||
13298 | 0x3a, 0x0b, 0xfe, 0xc6, | ||
13299 | 0x90, 0x04, 0xfe, 0xc6, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0x6c, 0x22, 0x6d, | ||
13300 | 0x01, 0xfe, 0xce, 0x1e, | ||
13301 | 0x01, 0xfe, 0xde, 0x1e, 0x10, 0x68, 0x22, 0x69, 0x0f, 0xfe, 0x40, 0x90, | ||
13302 | 0x04, 0xfe, 0xc0, 0x93, | ||
13303 | 0x3a, 0x0b, 0xfe, 0xc2, 0x90, 0x04, 0xfe, 0xc2, 0x93, 0x79, 0x0b, 0x0e, | ||
13304 | 0x10, 0x4b, 0x22, 0x4c, | ||
13305 | 0x10, 0x64, 0x22, 0x34, 0x01, 0x0c, 0x61, 0x24, 0x44, 0x37, 0x13, 0xfe, | ||
13306 | 0x4e, 0x11, 0x2f, 0xfe, | ||
13307 | 0xde, 0x09, 0xfe, 0x9e, 0xf0, 0xfe, 0xf2, 0x09, 0xfe, 0x01, 0x48, 0x1b, | ||
13308 | 0x3c, 0x37, 0x88, 0xf5, | ||
13309 | 0xd4, 0xfe, 0x1e, 0x0a, 0xd5, 0xfe, 0x42, 0x0a, 0xd2, 0xfe, 0x1e, 0x0a, | ||
13310 | 0xd3, 0xfe, 0x42, 0x0a, | ||
13311 | 0xae, 0xfe, 0x12, 0x0a, 0xfe, 0x06, 0xf0, 0xfe, 0x18, 0x0a, 0xaf, 0xa0, | ||
13312 | 0x05, 0x29, 0x01, 0x41, | ||
13313 | 0xfe, 0xc1, 0x10, 0x14, 0x24, 0xfe, 0xc1, 0x10, 0x01, 0x76, 0x06, 0x07, | ||
13314 | 0xfe, 0x14, 0x12, 0x01, | ||
13315 | 0x76, 0x06, 0x0d, 0x5d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x74, 0x12, 0xfe, | ||
13316 | 0x2e, 0x1c, 0x05, 0xfe, | ||
13317 | 0x1a, 0x0c, 0x01, 0x76, 0x06, 0x07, 0x5d, 0x01, 0x76, 0x06, 0x0d, 0x41, | ||
13318 | 0xfe, 0x2c, 0x1c, 0xfe, | ||
13319 | 0xaa, 0xf0, 0xfe, 0xce, 0x0a, 0xfe, 0xac, 0xf0, 0xfe, 0x66, 0x0a, 0xfe, | ||
13320 | 0x92, 0x10, 0xc4, 0xf6, | ||
13321 | 0xfe, 0xad, 0xf0, 0xfe, 0x72, 0x0a, 0x05, 0xfe, 0x1a, 0x0c, 0xc5, 0xfe, | ||
13322 | 0xe7, 0x10, 0xfe, 0x2b, | ||
13323 | 0xf0, 0xbf, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xfe, 0xfe, 0x1c, 0x12, | ||
13324 | 0xac, 0xfe, 0xd2, 0xf0, | ||
13325 | 0xbf, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x1b, 0xbf, 0x03, 0xe3, 0x23, 0x07, | ||
13326 | 0x1b, 0xbf, 0xd4, 0x5b, | ||
13327 | 0xd5, 0x5b, 0xd2, 0x5b, 0xd3, 0x5b, 0xc4, 0xc5, 0xfe, 0xa9, 0x10, 0x75, | ||
13328 | 0x5e, 0x32, 0x1f, 0x7f, | ||
13329 | 0x01, 0x42, 0x19, 0xfe, 0x35, 0x00, 0xfe, 0x01, 0xf0, 0x70, 0x19, 0x98, | ||
13330 | 0x05, 0x70, 0xfe, 0x74, | ||
13331 | 0x18, 0x23, 0xfe, 0x00, 0xf8, 0x1b, 0x5b, 0x7d, 0x12, 0x01, 0xfe, 0x78, | ||
13332 | 0x0f, 0x4d, 0x01, 0xfe, | ||
13333 | 0x96, 0x1a, 0x21, 0x30, 0x77, 0x7d, 0x1d, 0x05, 0x5b, 0x01, 0x0c, 0x06, | ||
13334 | 0x0d, 0x2b, 0xfe, 0xe2, | ||
13335 | 0x0b, 0x01, 0x0c, 0x06, 0x54, 0xfe, 0xa6, 0x12, 0x01, 0x0c, 0x06, 0x24, | ||
13336 | 0xfe, 0x88, 0x13, 0x21, | ||
13337 | 0x6e, 0xc7, 0x01, 0xfe, 0x1e, 0x1f, 0x0f, 0xfe, 0x83, 0x80, 0x04, 0xfe, | ||
13338 | 0x83, 0x83, 0xfe, 0xc9, | ||
13339 | 0x47, 0x0b, 0x0e, 0xfe, 0xc8, 0x44, 0xfe, 0x42, 0x13, 0x0f, 0xfe, 0x04, | ||
13340 | 0x91, 0x04, 0xfe, 0x84, | ||
13341 | 0x93, 0xfe, 0xca, 0x57, 0x0b, 0xfe, 0x86, 0x91, 0x04, 0xfe, 0x86, 0x93, | ||
13342 | 0xfe, 0xcb, 0x57, 0x0b, | ||
13343 | 0x0e, 0x7a, 0x30, 0xfe, 0x40, 0x59, 0xfe, 0xc1, 0x59, 0x8e, 0x40, 0x03, | ||
13344 | 0x6a, 0x3b, 0x6b, 0x10, | ||
13345 | 0x97, 0x22, 0x98, 0xd9, 0x6a, 0xda, 0x6b, 0x01, 0xc2, 0xc8, 0x7a, 0x30, | ||
13346 | 0x20, 0x6e, 0xdb, 0x64, | ||
13347 | 0xdc, 0x34, 0x91, 0x6c, 0x7e, 0x6d, 0xfe, 0x44, 0x55, 0xfe, 0xe5, 0x55, | ||
13348 | 0xfe, 0x04, 0xfa, 0x64, | ||
13349 | 0xfe, 0x05, 0xfa, 0x34, 0x01, 0xfe, 0x6a, 0x16, 0xa3, 0x26, 0x10, 0x97, | ||
13350 | 0x10, 0x98, 0x91, 0x6c, | ||
13351 | 0x7e, 0x6d, 0xfe, 0x14, 0x10, 0x01, 0x0c, 0x06, 0x24, 0x1b, 0x40, 0x91, | ||
13352 | 0x4b, 0x7e, 0x4c, 0x01, | ||
13353 | 0x0c, 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x10, | ||
13354 | 0x58, 0xfe, 0x91, 0x58, | ||
13355 | 0xfe, 0x14, 0x59, 0xfe, 0x95, 0x59, 0x05, 0x5b, 0x01, 0x0c, 0x06, 0x24, | ||
13356 | 0x1b, 0x40, 0x01, 0x0c, | ||
13357 | 0x06, 0xfe, 0xf7, 0x00, 0x44, 0x78, 0x01, 0xfe, 0x8e, 0x1e, 0x4f, 0x0f, | ||
13358 | 0xfe, 0x10, 0x90, 0x04, | ||
13359 | 0xfe, 0x90, 0x93, 0x3a, 0x0b, 0xfe, 0x92, 0x90, 0x04, 0xfe, 0x92, 0x93, | ||
13360 | 0x79, 0x0b, 0x0e, 0xfe, | ||
13361 | 0xbd, 0x10, 0x01, 0x43, 0x09, 0xbb, 0x1b, 0xfe, 0x6e, 0x0a, 0x15, 0xbb, | ||
13362 | 0x01, 0x0c, 0x06, 0x0d, | ||
13363 | 0xfe, 0x14, 0x13, 0x03, 0x4b, 0x3b, 0x4c, 0x8e, 0xfe, 0x6e, 0x0a, 0xfe, | ||
13364 | 0x0c, 0x58, 0xfe, 0x8d, | ||
13365 | 0x58, 0x05, 0x5b, 0x26, 0x3e, 0x0f, 0xfe, 0x19, 0x80, 0x04, 0xfe, 0x99, | ||
13366 | 0x83, 0x33, 0x0b, 0x0e, | ||
13367 | 0xfe, 0xe5, 0x10, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1a, 0x12, 0xfe, 0x6c, | ||
13368 | 0x19, 0xfe, 0x19, 0x41, | ||
13369 | 0xfe, 0x6b, 0x18, 0xac, 0xfe, 0xd1, 0xf0, 0xef, 0x1f, 0x92, 0x01, 0x42, | ||
13370 | 0x19, 0xfe, 0x44, 0x00, | ||
13371 | 0xfe, 0x90, 0x10, 0xfe, 0x6c, 0x19, 0xd9, 0x4b, 0xfe, 0xed, 0x19, 0xda, | ||
13372 | 0x4c, 0xfe, 0x0c, 0x51, | ||
13373 | 0xfe, 0x8e, 0x51, 0xfe, 0x6b, 0x18, 0x23, 0xfe, 0x00, 0xff, 0x31, 0xfe, | ||
13374 | 0x76, 0x10, 0xac, 0xfe, | ||
13375 | 0xd2, 0xf0, 0xfe, 0xba, 0x0c, 0xfe, 0x76, 0x18, 0x23, 0x1d, 0x5d, 0x03, | ||
13376 | 0xe3, 0x23, 0x07, 0xfe, | ||
13377 | 0x08, 0x13, 0x19, 0xfe, 0x16, 0x00, 0x05, 0x70, 0xfe, 0xd1, 0xf0, 0xfe, | ||
13378 | 0xcc, 0x0c, 0x1f, 0x92, | ||
13379 | 0x01, 0x42, 0x19, 0xfe, 0x17, 0x00, 0x5c, 0xfe, 0xce, 0xf0, 0xfe, 0xd2, | ||
13380 | 0x0c, 0xfe, 0x3e, 0x10, | ||
13381 | 0xfe, 0xcd, 0xf0, 0xfe, 0xde, 0x0c, 0x19, 0xfe, 0x22, 0x00, 0x05, 0x70, | ||
13382 | 0xfe, 0xcb, 0xf0, 0xfe, | ||
13383 | 0xea, 0x0c, 0x19, 0xfe, 0x24, 0x00, 0x05, 0x70, 0xfe, 0xd0, 0xf0, 0xfe, | ||
13384 | 0xf4, 0x0c, 0x19, 0x94, | ||
13385 | 0xfe, 0x1c, 0x10, 0xfe, 0xcf, 0xf0, 0xfe, 0xfe, 0x0c, 0x19, 0x4a, 0xf3, | ||
13386 | 0xfe, 0xcc, 0xf0, 0xef, | ||
13387 | 0x01, 0x76, 0x06, 0x24, 0x4d, 0x19, 0xfe, 0x12, 0x00, 0x37, 0x13, 0xfe, | ||
13388 | 0x4e, 0x11, 0x2f, 0xfe, | ||
13389 | 0x16, 0x0d, 0xfe, 0x9e, 0xf0, 0xfe, 0x2a, 0x0d, 0xfe, 0x01, 0x48, 0x1b, | ||
13390 | 0x3c, 0x37, 0x88, 0xf5, | ||
13391 | 0xd4, 0x29, 0xd5, 0x29, 0xd2, 0x29, 0xd3, 0x29, 0x37, 0xfe, 0x9c, 0x32, | ||
13392 | 0x2f, 0xfe, 0x3e, 0x0d, | ||
13393 | 0x2a, 0x3c, 0xae, 0xfe, 0x62, 0x0d, 0xaf, 0xa0, 0xd4, 0x9f, 0xd5, 0x9f, | ||
13394 | 0xd2, 0x9f, 0xd3, 0x9f, | ||
13395 | 0x05, 0x29, 0x01, 0x41, 0xfe, 0xd3, 0x10, 0x15, 0xfe, 0xe8, 0x00, 0xc4, | ||
13396 | 0xc5, 0x75, 0xd7, 0x99, | ||
13397 | 0xd8, 0x9c, 0xfe, 0x89, 0xf0, 0x29, 0x27, 0x25, 0xbe, 0xd7, 0x99, 0xd8, | ||
13398 | 0x9c, 0x2f, 0xfe, 0x8c, | ||
13399 | 0x0d, 0x16, 0x29, 0x27, 0x25, 0xbd, 0xfe, 0x01, 0x48, 0xa4, 0x19, 0xfe, | ||
13400 | 0x42, 0x00, 0x05, 0x70, | ||
13401 | 0x90, 0x07, 0xfe, 0x81, 0x49, 0x1b, 0xfe, 0x64, 0x0e, 0x01, 0x0c, 0x06, | ||
13402 | 0x0d, 0xfe, 0x44, 0x13, | ||
13403 | 0x19, 0x00, 0x2d, 0x0d, 0xfe, 0x54, 0x12, 0x2d, 0xfe, 0x28, 0x00, 0x2b, | ||
13404 | 0xfe, 0xda, 0x0e, 0x0a, | ||
13405 | 0x57, 0x01, 0x18, 0x09, 0x00, 0x36, 0x46, 0xfe, 0x28, 0x00, 0xfe, 0xfa, | ||
13406 | 0x10, 0x01, 0xfe, 0xf4, | ||
13407 | 0x1c, 0x01, 0xfe, 0x00, 0x1d, 0x0a, 0xba, 0x01, 0xfe, 0x58, 0x10, 0x40, | ||
13408 | 0x15, 0x56, 0x01, 0x85, | ||
13409 | 0x05, 0x35, 0x19, 0xfe, 0x44, 0x00, 0x2d, 0x0d, 0xf7, 0x46, 0x0d, 0xfe, | ||
13410 | 0xcc, 0x10, 0x01, 0xa7, | ||
13411 | 0x46, 0x0d, 0xfe, 0xc2, 0x10, 0x01, 0xa7, 0x0f, 0xfe, 0x19, 0x82, 0x04, | ||
13412 | 0xfe, 0x99, 0x83, 0xfe, | ||
13413 | 0xcc, 0x47, 0x0b, 0x0e, 0xfe, 0x34, 0x46, 0xa5, 0x46, 0x0d, 0x19, 0xfe, | ||
13414 | 0x43, 0x00, 0xfe, 0xa2, | ||
13415 | 0x10, 0x01, 0x0c, 0x61, 0x0d, 0x44, 0x01, 0xfe, 0xf4, 0x1c, 0x01, 0xfe, | ||
13416 | 0x00, 0x1d, 0x40, 0x15, | ||
13417 | 0x56, 0x01, 0x85, 0x7d, 0x0d, 0x40, 0x51, 0x01, 0xfe, 0x9e, 0x1e, 0x05, | ||
13418 | 0xfe, 0x3a, 0x03, 0x01, | ||
13419 | 0x0c, 0x06, 0x0d, 0x5d, 0x46, 0x0d, 0x19, 0x00, 0xfe, 0x62, 0x10, 0x01, | ||
13420 | 0x76, 0x06, 0x12, 0xfe, | ||
13421 | 0x5c, 0x12, 0x01, 0x0c, 0x06, 0x12, 0xfe, 0x52, 0x13, 0xfe, 0x1c, 0x1c, | ||
13422 | 0xfe, 0x9d, 0xf0, 0xfe, | ||
13423 | 0x8e, 0x0e, 0xfe, 0x1c, 0x1c, 0xfe, 0x9d, 0xf0, 0xfe, 0x94, 0x0e, 0x01, | ||
13424 | 0x0c, 0x61, 0x12, 0x44, | ||
13425 | 0xfe, 0x9f, 0x10, 0x19, 0xfe, 0x15, 0x00, 0xfe, 0x04, 0xe6, 0x0d, 0x4f, | ||
13426 | 0xfe, 0x2e, 0x10, 0x19, | ||
13427 | 0xfe, 0x13, 0x00, 0xfe, 0x10, 0x10, 0x19, 0xfe, 0x47, 0x00, 0xf1, 0x19, | ||
13428 | 0xfe, 0x41, 0x00, 0xa2, | ||
13429 | 0x19, 0xfe, 0x24, 0x00, 0x86, 0xc4, 0xc5, 0x75, 0x03, 0x81, 0x1e, 0x2b, | ||
13430 | 0xea, 0x4f, 0xfe, 0x04, | ||
13431 | 0xe6, 0x12, 0xfe, 0x9d, 0x41, 0xfe, 0x1c, 0x42, 0x40, 0x01, 0xf4, 0x05, | ||
13432 | 0x35, 0xfe, 0x12, 0x1c, | ||
13433 | 0x1f, 0x0d, 0x47, 0xb5, 0xc3, 0x1f, 0xfe, 0x31, 0x00, 0x47, 0xb8, 0x01, | ||
13434 | 0xfe, 0xd4, 0x11, 0x05, | ||
13435 | 0xe9, 0x51, 0xfe, 0x06, 0xec, 0xe0, 0xfe, 0x0e, 0x47, 0x46, 0x28, 0xfe, | ||
13436 | 0xce, 0x45, 0x31, 0x51, | ||
13437 | 0xfe, 0x06, 0xea, 0xe0, 0xfe, 0x47, 0x4b, 0x45, 0xfe, 0x75, 0x57, 0x03, | ||
13438 | 0x67, 0xfe, 0x98, 0x56, | ||
13439 | 0xfe, 0x38, 0x12, 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x44, 0x48, 0x60, 0x01, | ||
13440 | 0x0c, 0x06, 0x28, 0xfe, | ||
13441 | 0x18, 0x13, 0x0a, 0x57, 0x01, 0x18, 0x3e, 0xfe, 0x41, 0x58, 0x0a, 0xba, | ||
13442 | 0xfe, 0xfa, 0x14, 0xfe, | ||
13443 | 0x49, 0x54, 0xb0, 0xfe, 0x5e, 0x0f, 0x05, 0xfe, 0x3a, 0x03, 0x0a, 0x67, | ||
13444 | 0xfe, 0xe0, 0x14, 0xfe, | ||
13445 | 0x0e, 0x47, 0x46, 0x28, 0xfe, 0xce, 0x45, 0x31, 0x51, 0xfe, 0xce, 0x47, | ||
13446 | 0xfe, 0xad, 0x13, 0x05, | ||
13447 | 0x35, 0x21, 0x2c, 0x09, 0x1a, 0xfe, 0x98, 0x12, 0x26, 0x20, 0x96, 0x20, | ||
13448 | 0xe7, 0xfe, 0x08, 0x1c, | ||
13449 | 0xfe, 0x7c, 0x19, 0xfe, 0xfd, 0x19, 0xfe, 0x0a, 0x1c, 0x03, 0xe5, 0xfe, | ||
13450 | 0x48, 0x55, 0xa5, 0x3b, | ||
13451 | 0xfe, 0x62, 0x01, 0xfe, 0xc9, 0x55, 0x31, 0xfe, 0x74, 0x10, 0x01, 0xfe, | ||
13452 | 0xf0, 0x1a, 0x03, 0xfe, | ||
13453 | 0x38, 0x01, 0x3b, 0xfe, 0x3a, 0x01, 0x8e, 0xfe, 0x1e, 0x10, 0xfe, 0x02, | ||
13454 | 0xec, 0xe7, 0x53, 0x00, | ||
13455 | 0x36, 0xfe, 0x04, 0xec, 0x2c, 0x60, 0xfe, 0x05, 0xf6, 0xfe, 0x34, 0x01, | ||
13456 | 0x01, 0xfe, 0x62, 0x1b, | ||
13457 | 0x01, 0xfe, 0xce, 0x1e, 0xb2, 0x11, 0xfe, 0x18, 0x13, 0xca, 0xfe, 0x02, | ||
13458 | 0xea, 0xe7, 0x53, 0x92, | ||
13459 | 0xfe, 0xc3, 0x13, 0x1f, 0x12, 0x47, 0xb5, 0xc3, 0xfe, 0x2a, 0x10, 0x03, | ||
13460 | 0xfe, 0x38, 0x01, 0x23, | ||
13461 | 0xfe, 0xf0, 0xff, 0x10, 0xe5, 0x03, 0xfe, 0x3a, 0x01, 0x10, 0xfe, 0x62, | ||
13462 | 0x01, 0x01, 0xfe, 0x1e, | ||
13463 | 0x1e, 0x20, 0x2c, 0x15, 0x56, 0x01, 0xfe, 0x9e, 0x1e, 0x13, 0x07, 0x02, | ||
13464 | 0x26, 0x02, 0x21, 0x96, | ||
13465 | 0xc7, 0x20, 0x96, 0x09, 0x92, 0xfe, 0x79, 0x13, 0x1f, 0x1d, 0x47, 0xb5, | ||
13466 | 0xc3, 0xfe, 0xe1, 0x10, | ||
13467 | 0xcf, 0xfe, 0x03, 0xdc, 0xfe, 0x73, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xcf, | ||
13468 | 0xfe, 0x03, 0xdc, 0xfe, | ||
13469 | 0x5b, 0x57, 0xfe, 0x80, 0x5d, 0x02, 0xfe, 0x03, 0x57, 0xcf, 0x26, 0xfe, | ||
13470 | 0x00, 0xcc, 0x02, 0xfe, | ||
13471 | 0x03, 0x57, 0xcf, 0x89, 0x02, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, | ||
13472 | 0x0f, 0xfe, 0x1c, 0x80, | ||
13473 | 0x04, 0xfe, 0x9c, 0x83, 0x33, 0x0b, 0x0e, 0x09, 0x07, 0xfe, 0x3a, 0x13, | ||
13474 | 0x0f, 0xfe, 0x1e, 0x80, | ||
13475 | 0x04, 0xfe, 0x9e, 0x83, 0x33, 0x0b, 0x0e, 0xfe, 0x2a, 0x13, 0x0f, 0xfe, | ||
13476 | 0x1d, 0x80, 0x04, 0xfe, | ||
13477 | 0x9d, 0x83, 0xfe, 0xf9, 0x13, 0x0e, 0xfe, 0x1c, 0x13, 0x01, 0xfe, 0xee, | ||
13478 | 0x1e, 0xac, 0xfe, 0x14, | ||
13479 | 0x13, 0x01, 0xfe, 0xfe, 0x1e, 0xfe, 0x81, 0x58, 0xfa, 0x01, 0xfe, 0x0e, | ||
13480 | 0x1f, 0xfe, 0x30, 0xf4, | ||
13481 | 0x0d, 0xfe, 0x3c, 0x50, 0xa2, 0x01, 0xfe, 0x92, 0x1b, 0x01, 0x43, 0x09, | ||
13482 | 0x56, 0xfb, 0x01, 0xfe, | ||
13483 | 0xc8, 0x1a, 0x01, 0x0c, 0x06, 0x28, 0xa4, 0x01, 0xfe, 0xf4, 0x1c, 0x01, | ||
13484 | 0xfe, 0x00, 0x1d, 0x15, | ||
13485 | 0xfe, 0xe9, 0x00, 0x01, 0x0c, 0x06, 0x4a, 0xfe, 0x4e, 0x13, 0x01, 0xfe, | ||
13486 | 0x22, 0x1b, 0xfe, 0x1e, | ||
13487 | 0x1c, 0x0f, 0xfe, 0x14, 0x90, 0x04, 0xfe, 0x94, 0x93, 0x3a, 0x0b, 0xfe, | ||
13488 | 0x96, 0x90, 0x04, 0xfe, | ||
13489 | 0x96, 0x93, 0x79, 0x0b, 0x0e, 0x10, 0xfe, 0x64, 0x01, 0x22, 0xfe, 0x66, | ||
13490 | 0x01, 0x01, 0x0c, 0x06, | ||
13491 | 0x65, 0xf9, 0x0f, 0xfe, 0x03, 0x80, 0x04, 0xfe, 0x83, 0x83, 0x33, 0x0b, | ||
13492 | 0x0e, 0x77, 0xfe, 0x01, | ||
13493 | 0xec, 0x2c, 0xfe, 0x80, 0x40, 0x20, 0x2c, 0x7a, 0x30, 0x15, 0xdf, 0x40, | ||
13494 | 0x21, 0x2c, 0xfe, 0x00, | ||
13495 | 0x40, 0x8d, 0x2c, 0x02, 0xfe, 0x08, 0x1c, 0x03, 0xfe, 0xac, 0x00, 0xfe, | ||
13496 | 0x06, 0x58, 0x03, 0xfe, | ||
13497 | 0xae, 0x00, 0xfe, 0x07, 0x58, 0x03, 0xfe, 0xb0, 0x00, 0xfe, 0x08, 0x58, | ||
13498 | 0x03, 0xfe, 0xb2, 0x00, | ||
13499 | 0xfe, 0x09, 0x58, 0xfe, 0x0a, 0x1c, 0x2e, 0x49, 0x20, 0xe0, 0x26, 0x10, | ||
13500 | 0x66, 0x10, 0x55, 0x10, | ||
13501 | 0x6f, 0x13, 0x57, 0x52, 0x4f, 0x1c, 0x28, 0xfe, 0x90, 0x4d, 0xfe, 0x91, | ||
13502 | 0x54, 0x2b, 0xfe, 0x88, | ||
13503 | 0x11, 0x46, 0x1a, 0x13, 0x5a, 0x52, 0x1c, 0x4a, 0xfe, 0x90, 0x4d, 0xfe, | ||
13504 | 0x91, 0x54, 0x2b, 0xfe, | ||
13505 | 0x9e, 0x11, 0x2e, 0x1a, 0x20, 0x2c, 0x90, 0x34, 0x60, 0x21, 0x2c, 0xfe, | ||
13506 | 0x00, 0x40, 0x8d, 0x2c, | ||
13507 | 0x15, 0xdf, 0xfe, 0x14, 0x56, 0xfe, 0xd6, 0xf0, 0xfe, 0xb2, 0x11, 0xfe, | ||
13508 | 0x12, 0x1c, 0x75, 0xfe, | ||
13509 | 0x14, 0x1c, 0xfe, 0x10, 0x1c, 0xfe, 0x18, 0x1c, 0x02, 0x51, 0xfe, 0x0c, | ||
13510 | 0x14, 0xfe, 0x0e, 0x47, | ||
13511 | 0xfe, 0x07, 0xe6, 0x28, 0xfe, 0xce, 0x47, 0xfe, 0xf5, 0x13, 0x02, 0x01, | ||
13512 | 0xa7, 0x90, 0x34, 0x60, | ||
13513 | 0xfe, 0x06, 0x80, 0xfe, 0x48, 0x47, 0xfe, 0x42, 0x13, 0xfe, 0x02, 0x80, | ||
13514 | 0x09, 0x56, 0xfe, 0x34, | ||
13515 | 0x13, 0x0a, 0x5a, 0x01, 0x18, 0xcb, 0xfe, 0x36, 0x12, 0xfe, 0x41, 0x48, | ||
13516 | 0xfe, 0x45, 0x48, 0x01, | ||
13517 | 0xfe, 0xb2, 0x16, 0xfe, 0x00, 0xcc, 0xcb, 0xfe, 0xf3, 0x13, 0x3f, 0x89, | ||
13518 | 0x09, 0x1a, 0xa5, 0x0a, | ||
13519 | 0x9d, 0x01, 0x18, 0xfe, 0x80, 0x5c, 0x01, 0x85, 0xf2, 0x09, 0x9b, 0xa4, | ||
13520 | 0xfe, 0x14, 0x56, 0xfe, | ||
13521 | 0xd6, 0xf0, 0xfe, 0xec, 0x11, 0x02, 0xfe, 0x44, 0x58, 0x77, 0xfe, 0x01, | ||
13522 | 0xec, 0xb8, 0xfe, 0x9e, | ||
13523 | 0x40, 0xfe, 0x9d, 0xe7, 0x00, 0xfe, 0x9c, 0xe7, 0x12, 0x8d, 0x30, 0x01, | ||
13524 | 0xf4, 0xfe, 0xdd, 0x10, | ||
13525 | 0x37, 0xd7, 0x99, 0xd8, 0x9c, 0x27, 0x25, 0xee, 0x09, 0x12, 0xfe, 0x48, | ||
13526 | 0x12, 0x09, 0x0d, 0xfe, | ||
13527 | 0x56, 0x12, 0x09, 0x1d, 0xfe, 0x30, 0x12, 0x09, 0xdd, 0x1b, 0xfe, 0xc4, | ||
13528 | 0x13, 0x09, 0xfe, 0x23, | ||
13529 | 0x00, 0x1b, 0xfe, 0xd0, 0x13, 0x09, 0x07, 0x1b, 0xfe, 0x34, 0x14, 0x09, | ||
13530 | 0x24, 0xfe, 0x12, 0x12, | ||
13531 | 0x09, 0x00, 0x1b, 0x29, 0x1f, 0xdd, 0x01, 0x42, 0xa1, 0x32, 0x01, 0x08, | ||
13532 | 0xae, 0x41, 0x02, 0x32, | ||
13533 | 0xfe, 0x62, 0x08, 0x0a, 0xe1, 0x01, 0xfe, 0x58, 0x10, 0x15, 0x9b, 0x05, | ||
13534 | 0x35, 0x32, 0x01, 0x43, | ||
13535 | 0x09, 0xbb, 0xfe, 0xd7, 0x13, 0x91, 0x4b, 0x7e, 0x4c, 0x8e, 0xfe, 0x80, | ||
13536 | 0x13, 0x01, 0x0c, 0x06, | ||
13537 | 0x54, 0xfe, 0x72, 0x12, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x44, 0x55, 0xfe, | ||
13538 | 0xe5, 0x55, 0xb0, 0xfe, | ||
13539 | 0x4a, 0x13, 0x21, 0x6e, 0xfe, 0x26, 0x13, 0x03, 0x97, 0x3b, 0x98, 0x8e, | ||
13540 | 0xfe, 0xb6, 0x0e, 0x10, | ||
13541 | 0x6a, 0x22, 0x6b, 0x26, 0x10, 0x97, 0x10, 0x98, 0x01, 0xc2, 0x2e, 0x49, | ||
13542 | 0x88, 0x20, 0x6e, 0x01, | ||
13543 | 0xfe, 0x6a, 0x16, 0xdb, 0x64, 0xdc, 0x34, 0xfe, 0x04, 0x55, 0xfe, 0xa5, | ||
13544 | 0x55, 0xfe, 0x04, 0xfa, | ||
13545 | 0x64, 0xfe, 0x05, 0xfa, 0x34, 0xfe, 0x8f, 0x10, 0x03, 0x6c, 0x3b, 0x6d, | ||
13546 | 0xfe, 0x40, 0x56, 0xfe, | ||
13547 | 0xe1, 0x56, 0x10, 0x6c, 0x22, 0x6d, 0x71, 0xdb, 0x64, 0xdc, 0x34, 0xfe, | ||
13548 | 0x44, 0x55, 0xfe, 0xe5, | ||
13549 | 0x55, 0x03, 0x68, 0x3b, 0x69, 0xfe, 0x00, 0x56, 0xfe, 0xa1, 0x56, 0x10, | ||
13550 | 0x68, 0x22, 0x69, 0x01, | ||
13551 | 0x0c, 0x06, 0x54, 0xf9, 0x21, 0x6e, 0xfe, 0x1f, 0x40, 0x03, 0x6a, 0x3b, | ||
13552 | 0x6b, 0xfe, 0x2c, 0x50, | ||
13553 | 0xfe, 0xae, 0x50, 0x03, 0x6c, 0x3b, 0x6d, 0xfe, 0x44, 0x50, 0xfe, 0xc6, | ||
13554 | 0x50, 0x03, 0x68, 0x3b, | ||
13555 | 0x69, 0xfe, 0x08, 0x50, 0xfe, 0x8a, 0x50, 0x03, 0x4b, 0x3b, 0x4c, 0xfe, | ||
13556 | 0x40, 0x50, 0xfe, 0xc2, | ||
13557 | 0x50, 0x05, 0x73, 0x2e, 0x07, 0x20, 0x9e, 0x05, 0x72, 0x32, 0x01, 0x08, | ||
13558 | 0x16, 0x3d, 0x27, 0x25, | ||
13559 | 0xee, 0x09, 0x07, 0x2b, 0x3d, 0x01, 0x43, 0x09, 0xbb, 0x2b, 0x72, 0x01, | ||
13560 | 0xa6, 0x23, 0x3f, 0x1b, | ||
13561 | 0x3d, 0x01, 0x0c, 0x06, 0x0d, 0xfe, 0x1e, 0x13, 0x91, 0x4b, 0x7e, 0x4c, | ||
13562 | 0xfe, 0x0a, 0x55, 0x31, | ||
13563 | 0xfe, 0x8b, 0x55, 0xd9, 0x4b, 0xda, 0x4c, 0xfe, 0x0c, 0x51, 0xfe, 0x8e, | ||
13564 | 0x51, 0x05, 0x72, 0x01, | ||
13565 | 0xfe, 0x8e, 0x1e, 0xca, 0xfe, 0x19, 0x41, 0x05, 0x72, 0x32, 0x01, 0x08, | ||
13566 | 0x2a, 0x3c, 0x16, 0xc0, | ||
13567 | 0x27, 0x25, 0xbe, 0x2d, 0x1d, 0xc0, 0x2d, 0x0d, 0x83, 0x2d, 0x7f, 0x1b, | ||
13568 | 0xfe, 0x66, 0x15, 0x05, | ||
13569 | 0x3d, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0xc0, 0x27, 0x25, 0xbd, 0x09, 0x1d, | ||
13570 | 0x2b, 0x3d, 0x01, 0x08, | ||
13571 | 0x16, 0xc0, 0x27, 0x25, 0xfe, 0xe8, 0x09, 0xfe, 0xc2, 0x49, 0x50, 0x03, | ||
13572 | 0xb6, 0x1e, 0x83, 0x01, | ||
13573 | 0x38, 0x06, 0x24, 0x31, 0xa1, 0xfe, 0xbb, 0x45, 0x2d, 0x00, 0xa4, 0x46, | ||
13574 | 0x07, 0x90, 0x3f, 0x01, | ||
13575 | 0xfe, 0xf8, 0x15, 0x01, 0xa6, 0x86, 0xfe, 0x4b, 0x45, 0xfe, 0x20, 0x13, | ||
13576 | 0x01, 0x43, 0x09, 0x82, | ||
13577 | 0xfe, 0x16, 0x13, 0x03, 0x9a, 0x1e, 0x5d, 0x03, 0x55, 0x1e, 0x31, 0x5e, | ||
13578 | 0x05, 0x72, 0xfe, 0xc0, | ||
13579 | 0x5d, 0x01, 0xa7, 0xfe, 0x03, 0x17, 0x03, 0x66, 0x8a, 0x10, 0x66, 0x5e, | ||
13580 | 0x32, 0x01, 0x08, 0x17, | ||
13581 | 0x73, 0x01, 0xfe, 0x56, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, | ||
13582 | 0x3d, 0x27, 0x25, 0xbd, | ||
13583 | 0x09, 0x07, 0x2b, 0x3d, 0x01, 0xfe, 0xbe, 0x16, 0xfe, 0x42, 0x58, 0xfe, | ||
13584 | 0xe8, 0x14, 0x01, 0xa6, | ||
13585 | 0x86, 0xfe, 0x4a, 0xf4, 0x0d, 0x1b, 0x3d, 0xfe, 0x4a, 0xf4, 0x07, 0xfe, | ||
13586 | 0x0e, 0x12, 0x01, 0x43, | ||
13587 | 0x09, 0x82, 0x4e, 0x05, 0x72, 0x03, 0x55, 0x8a, 0x10, 0x55, 0x5e, 0x32, | ||
13588 | 0x01, 0x08, 0x17, 0x73, | ||
13589 | 0x01, 0xfe, 0x84, 0x19, 0x05, 0x73, 0x01, 0x08, 0x2a, 0x3c, 0x16, 0x3d, | ||
13590 | 0x27, 0x25, 0xbd, 0x09, | ||
13591 | 0x12, 0x2b, 0x3d, 0x01, 0xfe, 0xe8, 0x17, 0x8b, 0xfe, 0xaa, 0x14, 0xfe, | ||
13592 | 0xb6, 0x14, 0x86, 0xa8, | ||
13593 | 0xb2, 0x0d, 0x1b, 0x3d, 0xb2, 0x07, 0xfe, 0x0e, 0x12, 0x01, 0x43, 0x09, | ||
13594 | 0x82, 0x4e, 0x05, 0x72, | ||
13595 | 0x03, 0x6f, 0x8a, 0x10, 0x6f, 0x5e, 0x32, 0x01, 0x08, 0x17, 0x73, 0x01, | ||
13596 | 0xfe, 0xc0, 0x19, 0x05, | ||
13597 | 0x73, 0x13, 0x07, 0x2f, 0xfe, 0xcc, 0x15, 0x17, 0xfe, 0xe2, 0x15, 0x5f, | ||
13598 | 0xcc, 0x01, 0x08, 0x26, | ||
13599 | 0x5f, 0x02, 0x8f, 0xfe, 0xde, 0x15, 0x2a, 0xfe, 0xde, 0x15, 0x16, 0xfe, | ||
13600 | 0xcc, 0x15, 0x5e, 0x32, | ||
13601 | 0x01, 0x08, 0xfe, 0xd5, 0x10, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, | ||
13602 | 0xad, 0x23, 0xfe, 0xff, | ||
13603 | 0x7f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, 0x02, | ||
13604 | 0x00, 0x57, 0x52, 0xad, | ||
13605 | 0x23, 0x3f, 0xfe, 0x30, 0x56, 0xfe, 0x00, 0x5c, 0x02, 0x13, 0x58, 0xff, | ||
13606 | 0x02, 0x00, 0x57, 0x52, | ||
13607 | 0xad, 0x02, 0x13, 0x58, 0xff, 0x02, 0x00, 0x57, 0x52, 0xfe, 0x00, 0x5e, | ||
13608 | 0x02, 0x13, 0x58, 0xff, | ||
13609 | 0x02, 0x00, 0x57, 0x52, 0xad, 0xfe, 0x0b, 0x58, 0x02, 0x0a, 0x66, 0x01, | ||
13610 | 0x5c, 0x0a, 0x55, 0x01, | ||
13611 | 0x5c, 0x0a, 0x6f, 0x01, 0x5c, 0x02, 0x01, 0xfe, 0x1e, 0x1f, 0x23, 0x1a, | ||
13612 | 0xff, 0x03, 0x00, 0x54, | ||
13613 | 0xfe, 0x00, 0xf4, 0x24, 0x52, 0x0f, 0xfe, 0x00, 0x7c, 0x04, 0xfe, 0x07, | ||
13614 | 0x7c, 0x3a, 0x0b, 0x0e, | ||
13615 | 0xfe, 0x00, 0x71, 0xfe, 0xf9, 0x18, 0xfe, 0x7a, 0x19, 0xfe, 0xfb, 0x19, | ||
13616 | 0xfe, 0x1a, 0xf7, 0x00, | ||
13617 | 0xfe, 0x1b, 0xf7, 0x00, 0x7a, 0x30, 0x10, 0x68, 0x22, 0x69, 0xd9, 0x6c, | ||
13618 | 0xda, 0x6d, 0x02, 0xfe, | ||
13619 | 0x62, 0x08, 0xfe, 0x82, 0x4a, 0xfe, 0xe1, 0x1a, 0xfe, 0x83, 0x5a, 0x77, | ||
13620 | 0x02, 0x01, 0xc6, 0xfe, | ||
13621 | 0x42, 0x48, 0x4f, 0x50, 0x45, 0x01, 0x08, 0x16, 0xfe, 0xe0, 0x17, 0x27, | ||
13622 | 0x25, 0xbe, 0x01, 0x08, | ||
13623 | 0x16, 0xfe, 0xe0, 0x17, 0x27, 0x25, 0xfe, 0xe8, 0x0a, 0xfe, 0xc1, 0x59, | ||
13624 | 0x03, 0x9a, 0x1e, 0xfe, | ||
13625 | 0xda, 0x12, 0x01, 0x38, 0x06, 0x12, 0xfe, 0xd0, 0x13, 0x26, 0x53, 0x12, | ||
13626 | 0x48, 0xfe, 0x08, 0x17, | ||
13627 | 0xd1, 0x12, 0x53, 0x12, 0xfe, 0x1e, 0x13, 0x2d, 0xb4, 0x7b, 0xfe, 0x26, | ||
13628 | 0x17, 0x4d, 0x13, 0x07, | ||
13629 | 0x1c, 0xb4, 0x90, 0x04, 0xfe, 0x78, 0x10, 0xff, 0x02, 0x83, 0x55, 0xf1, | ||
13630 | 0xff, 0x02, 0x83, 0x55, | ||
13631 | 0x53, 0x1d, 0xfe, 0x12, 0x13, 0xd6, 0xfe, 0x30, 0x00, 0xb0, 0xfe, 0x80, | ||
13632 | 0x17, 0x1c, 0x63, 0x13, | ||
13633 | 0x07, 0xfe, 0x56, 0x10, 0x53, 0x0d, 0xfe, 0x16, 0x13, 0xd6, 0xfe, 0x64, | ||
13634 | 0x00, 0xb0, 0xfe, 0x80, | ||
13635 | 0x17, 0x0a, 0xfe, 0x64, 0x00, 0x1c, 0x94, 0x13, 0x07, 0xfe, 0x28, 0x10, | ||
13636 | 0x53, 0x07, 0xfe, 0x60, | ||
13637 | 0x13, 0xd6, 0xfe, 0xc8, 0x00, 0xb0, 0xfe, 0x80, 0x17, 0x0a, 0xfe, 0xc8, | ||
13638 | 0x00, 0x1c, 0x95, 0x13, | ||
13639 | 0x07, 0x71, 0xd6, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0x8c, 0x17, 0x45, 0xf3, | ||
13640 | 0xfe, 0x43, 0xf4, 0x96, | ||
13641 | 0xfe, 0x56, 0xf0, 0xfe, 0x9e, 0x17, 0xfe, 0x04, 0xf4, 0x58, 0xfe, 0x43, | ||
13642 | 0xf4, 0x94, 0xf6, 0x8b, | ||
13643 | 0x01, 0xfe, 0x24, 0x16, 0x23, 0x3f, 0xfc, 0xa8, 0x8c, 0x49, 0x48, 0xfe, | ||
13644 | 0xda, 0x17, 0x62, 0x49, | ||
13645 | 0xfe, 0x1c, 0x10, 0xa8, 0x8c, 0x80, 0x48, 0xfe, 0xda, 0x17, 0x62, 0x80, | ||
13646 | 0x71, 0x50, 0x26, 0xfe, | ||
13647 | 0x4d, 0xf4, 0x00, 0xf7, 0x45, 0x13, 0x07, 0xfe, 0xb4, 0x56, 0xfe, 0xc3, | ||
13648 | 0x58, 0x02, 0x50, 0x13, | ||
13649 | 0x0d, 0x02, 0x50, 0x3e, 0x78, 0x4f, 0x45, 0x01, 0x08, 0x16, 0xa9, 0x27, | ||
13650 | 0x25, 0xbe, 0xfe, 0x03, | ||
13651 | 0xea, 0xfe, 0x7e, 0x01, 0x01, 0x08, 0x16, 0xa9, 0x27, 0x25, 0xfe, 0xe9, | ||
13652 | 0x0a, 0x01, 0x08, 0x16, | ||
13653 | 0xa9, 0x27, 0x25, 0xfe, 0xe9, 0x0a, 0xfe, 0x05, 0xea, 0xfe, 0x7f, 0x01, | ||
13654 | 0x01, 0x08, 0x16, 0xa9, | ||
13655 | 0x27, 0x25, 0xfe, 0x69, 0x09, 0xfe, 0x02, 0xea, 0xfe, 0x80, 0x01, 0x01, | ||
13656 | 0x08, 0x16, 0xa9, 0x27, | ||
13657 | 0x25, 0xfe, 0xe8, 0x08, 0x47, 0xfe, 0x81, 0x01, 0x03, 0xb6, 0x1e, 0x83, | ||
13658 | 0x01, 0x38, 0x06, 0x24, | ||
13659 | 0x31, 0xa2, 0x78, 0xf2, 0x53, 0x07, 0x36, 0xfe, 0x34, 0xf4, 0x3f, 0xa1, | ||
13660 | 0x78, 0x03, 0x9a, 0x1e, | ||
13661 | 0x83, 0x01, 0x38, 0x06, 0x12, 0x31, 0xf0, 0x4f, 0x45, 0xfe, 0x90, 0x10, | ||
13662 | 0xfe, 0x40, 0x5a, 0x23, | ||
13663 | 0x3f, 0xfb, 0x8c, 0x49, 0x48, 0xfe, 0xaa, 0x18, 0x62, 0x49, 0x71, 0x8c, | ||
13664 | 0x80, 0x48, 0xfe, 0xaa, | ||
13665 | 0x18, 0x62, 0x80, 0xfe, 0xb4, 0x56, 0xfe, 0x40, 0x5d, 0x01, 0xc6, 0x01, | ||
13666 | 0xfe, 0xac, 0x1d, 0xfe, | ||
13667 | 0x02, 0x17, 0xfe, 0xc8, 0x45, 0xfe, 0x5a, 0xf0, 0xfe, 0xc0, 0x18, 0xfe, | ||
13668 | 0x43, 0x48, 0x2d, 0x93, | ||
13669 | 0x36, 0xfe, 0x34, 0xf4, 0xfe, 0x00, 0x11, 0xfe, 0x40, 0x10, 0x2d, 0xb4, | ||
13670 | 0x36, 0xfe, 0x34, 0xf4, | ||
13671 | 0x04, 0xfe, 0x34, 0x10, 0x2d, 0xfe, 0x0b, 0x00, 0x36, 0x46, 0x63, 0xfe, | ||
13672 | 0x28, 0x10, 0xfe, 0xc0, | ||
13673 | 0x49, 0xff, 0x02, 0x00, 0x54, 0xb2, 0xfe, 0x90, 0x01, 0x48, 0xfe, 0xfa, | ||
13674 | 0x18, 0x45, 0xfe, 0x1c, | ||
13675 | 0xf4, 0x3f, 0xf3, 0xfe, 0x40, 0xf4, 0x96, 0xfe, 0x56, 0xf0, 0xfe, 0x0c, | ||
13676 | 0x19, 0xfe, 0x04, 0xf4, | ||
13677 | 0x58, 0xfe, 0x40, 0xf4, 0x94, 0xf6, 0x3e, 0x2d, 0x93, 0x4e, 0xd0, 0x0d, | ||
13678 | 0x21, 0xfe, 0x7f, 0x01, | ||
13679 | 0xfe, 0xc8, 0x46, 0xfe, 0x24, 0x13, 0x8c, 0x00, 0x5d, 0x26, 0x21, 0xfe, | ||
13680 | 0x7e, 0x01, 0xfe, 0xc8, | ||
13681 | 0x45, 0xfe, 0x14, 0x13, 0x21, 0xfe, 0x80, 0x01, 0xfe, 0x48, 0x45, 0xfa, | ||
13682 | 0x21, 0xfe, 0x81, 0x01, | ||
13683 | 0xfe, 0xc8, 0x44, 0x4e, 0x26, 0x02, 0x13, 0x07, 0x02, 0x78, 0x45, 0x50, | ||
13684 | 0x13, 0x0d, 0x02, 0x14, | ||
13685 | 0x07, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x14, 0x0d, 0x01, 0x08, 0x17, | ||
13686 | 0xfe, 0x82, 0x19, 0x14, | ||
13687 | 0x1d, 0x01, 0x08, 0x17, 0xfe, 0x82, 0x19, 0x5f, 0xfe, 0x89, 0x49, 0x01, | ||
13688 | 0x08, 0x02, 0x14, 0x07, | ||
13689 | 0x01, 0x08, 0x17, 0xc1, 0x14, 0x1d, 0x01, 0x08, 0x17, 0xc1, 0x14, 0x07, | ||
13690 | 0x01, 0x08, 0x17, 0xc1, | ||
13691 | 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0xc1, 0x5f, 0xfe, 0x89, 0x4a, 0x01, | ||
13692 | 0x08, 0x02, 0x50, 0x02, | ||
13693 | 0x14, 0x07, 0x01, 0x08, 0x17, 0x74, 0x14, 0x7f, 0x01, 0x08, 0x17, 0x74, | ||
13694 | 0x14, 0x12, 0x01, 0x08, | ||
13695 | 0x17, 0x74, 0xfe, 0x89, 0x49, 0x01, 0x08, 0x17, 0x74, 0x14, 0x00, 0x01, | ||
13696 | 0x08, 0x17, 0x74, 0xfe, | ||
13697 | 0x89, 0x4a, 0x01, 0x08, 0x17, 0x74, 0xfe, 0x09, 0x49, 0x01, 0x08, 0x17, | ||
13698 | 0x74, 0x5f, 0xcc, 0x01, | ||
13699 | 0x08, 0x02, 0x21, 0xe4, 0x09, 0x07, 0xfe, 0x4c, 0x13, 0xc8, 0x20, 0xe4, | ||
13700 | 0xfe, 0x49, 0xf4, 0x00, | ||
13701 | 0x4d, 0x5f, 0xa1, 0x5e, 0xfe, 0x01, 0xec, 0xfe, 0x27, 0x01, 0xcc, 0xff, | ||
13702 | 0x02, 0x00, 0x10, 0x2f, | ||
13703 | 0xfe, 0x3e, 0x1a, 0x01, 0x43, 0x09, 0xfe, 0xe3, 0x00, 0xfe, 0x22, 0x13, | ||
13704 | 0x16, 0xfe, 0x64, 0x1a, | ||
13705 | 0x26, 0x20, 0x9e, 0x01, 0x41, 0x21, 0x9e, 0x09, 0x07, 0x5d, 0x01, 0x0c, | ||
13706 | 0x61, 0x07, 0x44, 0x02, | ||
13707 | 0x0a, 0x5a, 0x01, 0x18, 0xfe, 0x00, 0x40, 0xaa, 0x09, 0x1a, 0xfe, 0x12, | ||
13708 | 0x13, 0x0a, 0x9d, 0x01, | ||
13709 | 0x18, 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x9d, 0x01, 0x18, 0xaa, | ||
13710 | 0xfe, 0x80, 0xe7, 0x1a, | ||
13711 | 0x09, 0x1a, 0x5d, 0xfe, 0x45, 0x58, 0x01, 0xfe, 0xb2, 0x16, 0xaa, 0x02, | ||
13712 | 0x0a, 0x5a, 0x01, 0x18, | ||
13713 | 0xaa, 0x0a, 0x67, 0x01, 0xa3, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x01, 0xfe, | ||
13714 | 0x7e, 0x1e, 0xfe, 0x80, | ||
13715 | 0x4c, 0xfe, 0x49, 0xe4, 0x1a, 0xfe, 0x12, 0x13, 0x0a, 0x9d, 0x01, 0x18, | ||
13716 | 0xfe, 0x80, 0x4c, 0x0a, | ||
13717 | 0x67, 0x01, 0x5c, 0x02, 0x1c, 0x1a, 0x87, 0x7c, 0xe5, 0xfe, 0x18, 0xdf, | ||
13718 | 0xfe, 0x19, 0xde, 0xfe, | ||
13719 | 0x24, 0x1c, 0xfe, 0x1d, 0xf7, 0x28, 0xb1, 0xfe, 0x04, 0x1b, 0x01, 0xfe, | ||
13720 | 0x2a, 0x1c, 0xfa, 0xb3, | ||
13721 | 0x28, 0x7c, 0xfe, 0x2c, 0x01, 0xfe, 0x2f, 0x19, 0x02, 0xc9, 0x2b, 0xfe, | ||
13722 | 0xf4, 0x1a, 0xfe, 0xfa, | ||
13723 | 0x10, 0x1c, 0x1a, 0x87, 0x03, 0xfe, 0x64, 0x01, 0xfe, 0x00, 0xf4, 0x24, | ||
13724 | 0xfe, 0x18, 0x58, 0x03, | ||
13725 | 0xfe, 0x66, 0x01, 0xfe, 0x19, 0x58, 0xb3, 0x24, 0x01, 0xfe, 0x0e, 0x1f, | ||
13726 | 0xfe, 0x30, 0xf4, 0x07, | ||
13727 | 0xfe, 0x3c, 0x50, 0x7c, 0xfe, 0x38, 0x00, 0xfe, 0x0f, 0x79, 0xfe, 0x1c, | ||
13728 | 0xf7, 0x24, 0xb1, 0xfe, | ||
13729 | 0x50, 0x1b, 0xfe, 0xd4, 0x14, 0x31, 0x02, 0xc9, 0x2b, 0xfe, 0x26, 0x1b, | ||
13730 | 0xfe, 0xba, 0x10, 0x1c, | ||
13731 | 0x1a, 0x87, 0xfe, 0x83, 0x5a, 0xfe, 0x18, 0xdf, 0xfe, 0x19, 0xde, 0xfe, | ||
13732 | 0x1d, 0xf7, 0x54, 0xb1, | ||
13733 | 0xfe, 0x72, 0x1b, 0xfe, 0xb2, 0x14, 0xfc, 0xb3, 0x54, 0x7c, 0x12, 0xfe, | ||
13734 | 0xaf, 0x19, 0xfe, 0x98, | ||
13735 | 0xe7, 0x00, 0x02, 0xc9, 0x2b, 0xfe, 0x66, 0x1b, 0xfe, 0x8a, 0x10, 0x1c, | ||
13736 | 0x1a, 0x87, 0x8b, 0x0f, | ||
13737 | 0xfe, 0x30, 0x90, 0x04, 0xfe, 0xb0, 0x93, 0x3a, 0x0b, 0xfe, 0x18, 0x58, | ||
13738 | 0xfe, 0x32, 0x90, 0x04, | ||
13739 | 0xfe, 0xb2, 0x93, 0x3a, 0x0b, 0xfe, 0x19, 0x58, 0x0e, 0xa8, 0xb3, 0x4a, | ||
13740 | 0x7c, 0x12, 0xfe, 0x0f, | ||
13741 | 0x79, 0xfe, 0x1c, 0xf7, 0x4a, 0xb1, 0xfe, 0xc6, 0x1b, 0xfe, 0x5e, 0x14, | ||
13742 | 0x31, 0x02, 0xc9, 0x2b, | ||
13743 | 0xfe, 0x96, 0x1b, 0x5c, 0xfe, 0x02, 0xf6, 0x1a, 0x87, 0xfe, 0x18, 0xfe, | ||
13744 | 0x6a, 0xfe, 0x19, 0xfe, | ||
13745 | 0x6b, 0x01, 0xfe, 0x1e, 0x1f, 0xfe, 0x1d, 0xf7, 0x65, 0xb1, 0xfe, 0xee, | ||
13746 | 0x1b, 0xfe, 0x36, 0x14, | ||
13747 | 0xfe, 0x1c, 0x13, 0xb3, 0x65, 0x3e, 0xfe, 0x83, 0x58, 0xfe, 0xaf, 0x19, | ||
13748 | 0xfe, 0x80, 0xe7, 0x1a, | ||
13749 | 0xfe, 0x81, 0xe7, 0x1a, 0x15, 0xfe, 0xdd, 0x00, 0x7a, 0x30, 0x02, 0x7a, | ||
13750 | 0x30, 0xfe, 0x12, 0x45, | ||
13751 | 0x2b, 0xfe, 0xdc, 0x1b, 0x1f, 0x07, 0x47, 0xb5, 0xc3, 0x05, 0x35, 0xfe, | ||
13752 | 0x39, 0xf0, 0x75, 0x26, | ||
13753 | 0x02, 0xfe, 0x7e, 0x18, 0x23, 0x1d, 0x36, 0x13, 0x11, 0x02, 0x87, 0x03, | ||
13754 | 0xe3, 0x23, 0x07, 0xfe, | ||
13755 | 0xef, 0x12, 0xfe, 0xe1, 0x10, 0x90, 0x34, 0x60, 0xfe, 0x02, 0x80, 0x09, | ||
13756 | 0x56, 0xfe, 0x3c, 0x13, | ||
13757 | 0xfe, 0x82, 0x14, 0xfe, 0x42, 0x13, 0x51, 0xfe, 0x06, 0x83, 0x0a, 0x5a, | ||
13758 | 0x01, 0x18, 0xcb, 0xfe, | ||
13759 | 0x3e, 0x12, 0xfe, 0x41, 0x48, 0xfe, 0x45, 0x48, 0x01, 0xfe, 0xb2, 0x16, | ||
13760 | 0xfe, 0x00, 0xcc, 0xcb, | ||
13761 | 0xfe, 0xf3, 0x13, 0x3f, 0x89, 0x09, 0x1a, 0xa5, 0x0a, 0x9d, 0x01, 0x18, | ||
13762 | 0xfe, 0x80, 0x4c, 0x01, | ||
13763 | 0x85, 0xfe, 0x16, 0x10, 0x09, 0x9b, 0x4e, 0xfe, 0x40, 0x14, 0xfe, 0x24, | ||
13764 | 0x12, 0xfe, 0x14, 0x56, | ||
13765 | 0xfe, 0xd6, 0xf0, 0xfe, 0x52, 0x1c, 0x1c, 0x0d, 0x02, 0xfe, 0x9c, 0xe7, | ||
13766 | 0x0d, 0x19, 0xfe, 0x15, | ||
13767 | 0x00, 0x40, 0x8d, 0x30, 0x01, 0xf4, 0x1c, 0x07, 0x02, 0x51, 0xfe, 0x06, | ||
13768 | 0x83, 0xfe, 0x18, 0x80, | ||
13769 | 0x61, 0x28, 0x44, 0x15, 0x56, 0x01, 0x85, 0x1c, 0x07, 0x02, 0xfe, 0x38, | ||
13770 | 0x90, 0xfe, 0xba, 0x90, | ||
13771 | 0x91, 0xde, 0x7e, 0xdf, 0xfe, 0x48, 0x55, 0x31, 0xfe, 0xc9, 0x55, 0x02, | ||
13772 | 0x21, 0xb9, 0x88, 0x20, | ||
13773 | 0xb9, 0x02, 0x0a, 0xba, 0x01, 0x18, 0xfe, 0x41, 0x48, 0x0a, 0x57, 0x01, | ||
13774 | 0x18, 0xfe, 0x49, 0x44, | ||
13775 | 0x1b, 0xfe, 0x1e, 0x1d, 0x88, 0x89, 0x02, 0x0a, 0x5a, 0x01, 0x18, 0x09, | ||
13776 | 0x1a, 0xa4, 0x0a, 0x67, | ||
13777 | 0x01, 0xa3, 0x0a, 0x57, 0x01, 0x18, 0x88, 0x89, 0x02, 0xfe, 0x4e, 0xe4, | ||
13778 | 0x1d, 0x7b, 0xfe, 0x52, | ||
13779 | 0x1d, 0x03, 0xfe, 0x90, 0x00, 0xfe, 0x3a, 0x45, 0xfe, 0x2c, 0x10, 0xfe, | ||
13780 | 0x4e, 0xe4, 0xdd, 0x7b, | ||
13781 | 0xfe, 0x64, 0x1d, 0x03, 0xfe, 0x92, 0x00, 0xd1, 0x12, 0xfe, 0x1a, 0x10, | ||
13782 | 0xfe, 0x4e, 0xe4, 0xfe, | ||
13783 | 0x0b, 0x00, 0x7b, 0xfe, 0x76, 0x1d, 0x03, 0xfe, 0x94, 0x00, 0xd1, 0x24, | ||
13784 | 0xfe, 0x08, 0x10, 0x03, | ||
13785 | 0xfe, 0x96, 0x00, 0xd1, 0x63, 0xfe, 0x4e, 0x45, 0x83, 0xca, 0xff, 0x04, | ||
13786 | 0x68, 0x54, 0xfe, 0xf1, | ||
13787 | 0x10, 0x23, 0x49, 0xfe, 0x08, 0x1c, 0xfe, 0x67, 0x19, 0xfe, 0x0a, 0x1c, | ||
13788 | 0xfe, 0x1a, 0xf4, 0xfe, | ||
13789 | 0x00, 0x04, 0x83, 0xb2, 0x1d, 0x48, 0xfe, 0xaa, 0x1d, 0x13, 0x1d, 0x02, | ||
13790 | 0x09, 0x92, 0xfe, 0x5a, | ||
13791 | 0xf0, 0xfe, 0xba, 0x1d, 0x2e, 0x93, 0xfe, 0x34, 0x10, 0x09, 0x12, 0xfe, | ||
13792 | 0x5a, 0xf0, 0xfe, 0xc8, | ||
13793 | 0x1d, 0x2e, 0xb4, 0xfe, 0x26, 0x10, 0x09, 0x1d, 0x36, 0x2e, 0x63, 0xfe, | ||
13794 | 0x1a, 0x10, 0x09, 0x0d, | ||
13795 | 0x36, 0x2e, 0x94, 0xf2, 0x09, 0x07, 0x36, 0x2e, 0x95, 0xa1, 0xc8, 0x02, | ||
13796 | 0x1f, 0x93, 0x01, 0x42, | ||
13797 | 0xfe, 0x04, 0xfe, 0x99, 0x03, 0x9c, 0x8b, 0x02, 0x2a, 0xfe, 0x1c, 0x1e, | ||
13798 | 0xfe, 0x14, 0xf0, 0x08, | ||
13799 | 0x2f, 0xfe, 0x0c, 0x1e, 0x2a, 0xfe, 0x1c, 0x1e, 0x8f, 0xfe, 0x1c, 0x1e, | ||
13800 | 0xfe, 0x82, 0xf0, 0xfe, | ||
13801 | 0x10, 0x1e, 0x02, 0x0f, 0x3f, 0x04, 0xfe, 0x80, 0x83, 0x33, 0x0b, 0x0e, | ||
13802 | 0x02, 0x0f, 0xfe, 0x18, | ||
13803 | 0x80, 0x04, 0xfe, 0x98, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x02, | ||
13804 | 0x80, 0x04, 0xfe, 0x82, | ||
13805 | 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x80, 0x04, 0xfe, 0x86, | ||
13806 | 0x83, 0x33, 0x0b, 0x0e, | ||
13807 | 0x02, 0x0f, 0xfe, 0x1b, 0x80, 0x04, 0xfe, 0x9b, 0x83, 0x33, 0x0b, 0x0e, | ||
13808 | 0x02, 0x0f, 0xfe, 0x04, | ||
13809 | 0x80, 0x04, 0xfe, 0x84, 0x83, 0x33, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x80, | ||
13810 | 0x80, 0x04, 0xfe, 0x80, | ||
13811 | 0x83, 0xfe, 0xc9, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x19, 0x81, 0x04, | ||
13812 | 0xfe, 0x99, 0x83, 0xfe, | ||
13813 | 0xca, 0x47, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x06, 0x83, 0x04, 0xfe, 0x86, | ||
13814 | 0x83, 0xfe, 0xce, 0x47, | ||
13815 | 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x2c, 0x90, 0x04, 0xfe, 0xac, 0x93, 0x3a, | ||
13816 | 0x0b, 0x0e, 0x02, 0x0f, | ||
13817 | 0xfe, 0xae, 0x90, 0x04, 0xfe, 0xae, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, | ||
13818 | 0xfe, 0x08, 0x90, 0x04, | ||
13819 | 0xfe, 0x88, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x8a, 0x90, 0x04, | ||
13820 | 0xfe, 0x8a, 0x93, 0x79, | ||
13821 | 0x0b, 0x0e, 0x02, 0x0f, 0xfe, 0x0c, 0x90, 0x04, 0xfe, 0x8c, 0x93, 0x3a, | ||
13822 | 0x0b, 0x0e, 0x02, 0x0f, | ||
13823 | 0xfe, 0x8e, 0x90, 0x04, 0xfe, 0x8e, 0x93, 0x79, 0x0b, 0x0e, 0x02, 0x0f, | ||
13824 | 0xfe, 0x3c, 0x90, 0x04, | ||
13825 | 0xfe, 0xbc, 0x93, 0x3a, 0x0b, 0x0e, 0x02, 0x8b, 0x0f, 0xfe, 0x03, 0x80, | ||
13826 | 0x04, 0xfe, 0x83, 0x83, | ||
13827 | 0x33, 0x0b, 0x77, 0x0e, 0xa8, 0x02, 0xff, 0x66, 0x00, 0x00, | ||
13828 | }; | ||
13829 | 11874 | ||
13830 | static unsigned short _adv_asc38C1600_size = sizeof(_adv_asc38C1600_buf); /* 0x1673 */ | 11875 | return asc_dvc->err_code; |
13831 | static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian checksum. */ | 11876 | } |
13832 | 11877 | ||
13833 | /* a_init.c */ | ||
13834 | /* | 11878 | /* |
13835 | * EEPROM Configuration. | 11879 | * EEPROM Configuration. |
13836 | * | 11880 | * |
@@ -13847,7 +11891,7 @@ static ADV_DCNT _adv_asc38C1600_chksum = 0x0604EF77UL; /* Expanded little-endian | |||
13847 | * on big-endian platforms so char fields read as words are actually being | 11891 | * on big-endian platforms so char fields read as words are actually being |
13848 | * unswapped on big-endian platforms. | 11892 | * unswapped on big-endian platforms. |
13849 | */ | 11893 | */ |
13850 | static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __initdata = { | 11894 | static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __devinitdata = { |
13851 | ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */ | 11895 | ADV_EEPROM_BIOS_ENABLE, /* cfg_lsw */ |
13852 | 0x0000, /* cfg_msw */ | 11896 | 0x0000, /* cfg_msw */ |
13853 | 0xFFFF, /* disc_enable */ | 11897 | 0xFFFF, /* disc_enable */ |
@@ -13885,7 +11929,7 @@ static ADVEEP_3550_CONFIG Default_3550_EEPROM_Config __initdata = { | |||
13885 | 0 /* num_of_err */ | 11929 | 0 /* num_of_err */ |
13886 | }; | 11930 | }; |
13887 | 11931 | ||
13888 | static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __initdata = { | 11932 | static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __devinitdata = { |
13889 | 0, /* cfg_lsw */ | 11933 | 0, /* cfg_lsw */ |
13890 | 0, /* cfg_msw */ | 11934 | 0, /* cfg_msw */ |
13891 | 0, /* -disc_enable */ | 11935 | 0, /* -disc_enable */ |
@@ -13923,7 +11967,7 @@ static ADVEEP_3550_CONFIG ADVEEP_3550_Config_Field_IsChar __initdata = { | |||
13923 | 0 /* num_of_err */ | 11967 | 0 /* num_of_err */ |
13924 | }; | 11968 | }; |
13925 | 11969 | ||
13926 | static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __initdata = { | 11970 | static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __devinitdata = { |
13927 | ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ | 11971 | ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ |
13928 | 0x0000, /* 01 cfg_msw */ | 11972 | 0x0000, /* 01 cfg_msw */ |
13929 | 0xFFFF, /* 02 disc_enable */ | 11973 | 0xFFFF, /* 02 disc_enable */ |
@@ -13988,7 +12032,7 @@ static ADVEEP_38C0800_CONFIG Default_38C0800_EEPROM_Config __initdata = { | |||
13988 | 0 /* 63 reserved */ | 12032 | 0 /* 63 reserved */ |
13989 | }; | 12033 | }; |
13990 | 12034 | ||
13991 | static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __initdata = { | 12035 | static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __devinitdata = { |
13992 | 0, /* 00 cfg_lsw */ | 12036 | 0, /* 00 cfg_lsw */ |
13993 | 0, /* 01 cfg_msw */ | 12037 | 0, /* 01 cfg_msw */ |
13994 | 0, /* 02 disc_enable */ | 12038 | 0, /* 02 disc_enable */ |
@@ -14053,7 +12097,7 @@ static ADVEEP_38C0800_CONFIG ADVEEP_38C0800_Config_Field_IsChar __initdata = { | |||
14053 | 0 /* 63 reserved */ | 12097 | 0 /* 63 reserved */ |
14054 | }; | 12098 | }; |
14055 | 12099 | ||
14056 | static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __initdata = { | 12100 | static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __devinitdata = { |
14057 | ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ | 12101 | ADV_EEPROM_BIOS_ENABLE, /* 00 cfg_lsw */ |
14058 | 0x0000, /* 01 cfg_msw */ | 12102 | 0x0000, /* 01 cfg_msw */ |
14059 | 0xFFFF, /* 02 disc_enable */ | 12103 | 0xFFFF, /* 02 disc_enable */ |
@@ -14118,7 +12162,7 @@ static ADVEEP_38C1600_CONFIG Default_38C1600_EEPROM_Config __initdata = { | |||
14118 | 0 /* 63 reserved */ | 12162 | 0 /* 63 reserved */ |
14119 | }; | 12163 | }; |
14120 | 12164 | ||
14121 | static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __initdata = { | 12165 | static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __devinitdata = { |
14122 | 0, /* 00 cfg_lsw */ | 12166 | 0, /* 00 cfg_lsw */ |
14123 | 0, /* 01 cfg_msw */ | 12167 | 0, /* 01 cfg_msw */ |
14124 | 0, /* 02 disc_enable */ | 12168 | 0, /* 02 disc_enable */ |
@@ -14183,1944 +12227,365 @@ static ADVEEP_38C1600_CONFIG ADVEEP_38C1600_Config_Field_IsChar __initdata = { | |||
14183 | 0 /* 63 reserved */ | 12227 | 0 /* 63 reserved */ |
14184 | }; | 12228 | }; |
14185 | 12229 | ||
12230 | #ifdef CONFIG_PCI | ||
14186 | /* | 12231 | /* |
14187 | * Initialize the ADV_DVC_VAR structure. | 12232 | * Wait for EEPROM command to complete |
14188 | * | ||
14189 | * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. | ||
14190 | * | ||
14191 | * For a non-fatal error return a warning code. If there are no warnings | ||
14192 | * then 0 is returned. | ||
14193 | */ | 12233 | */ |
14194 | static int __init AdvInitGetConfig(ADV_DVC_VAR *asc_dvc) | 12234 | static void __devinit AdvWaitEEPCmd(AdvPortAddr iop_base) |
14195 | { | 12235 | { |
14196 | ushort warn_code; | 12236 | int eep_delay_ms; |
14197 | AdvPortAddr iop_base; | ||
14198 | uchar pci_cmd_reg; | ||
14199 | int status; | ||
14200 | |||
14201 | warn_code = 0; | ||
14202 | asc_dvc->err_code = 0; | ||
14203 | iop_base = asc_dvc->iop_base; | ||
14204 | |||
14205 | /* | ||
14206 | * PCI Command Register | ||
14207 | * | ||
14208 | * Note: AscPCICmdRegBits_BusMastering definition (0x0007) includes | ||
14209 | * I/O Space Control, Memory Space Control and Bus Master Control bits. | ||
14210 | */ | ||
14211 | |||
14212 | if (((pci_cmd_reg = DvcAdvReadPCIConfigByte(asc_dvc, | ||
14213 | AscPCIConfigCommandRegister)) | ||
14214 | & AscPCICmdRegBits_BusMastering) | ||
14215 | != AscPCICmdRegBits_BusMastering) { | ||
14216 | pci_cmd_reg |= AscPCICmdRegBits_BusMastering; | ||
14217 | |||
14218 | DvcAdvWritePCIConfigByte(asc_dvc, | ||
14219 | AscPCIConfigCommandRegister, | ||
14220 | pci_cmd_reg); | ||
14221 | |||
14222 | if (((DvcAdvReadPCIConfigByte | ||
14223 | (asc_dvc, AscPCIConfigCommandRegister)) | ||
14224 | & AscPCICmdRegBits_BusMastering) | ||
14225 | != AscPCICmdRegBits_BusMastering) { | ||
14226 | warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; | ||
14227 | } | ||
14228 | } | ||
14229 | |||
14230 | /* | ||
14231 | * PCI Latency Timer | ||
14232 | * | ||
14233 | * If the "latency timer" register is 0x20 or above, then we don't need | ||
14234 | * to change it. Otherwise, set it to 0x20 (i.e. set it to 0x20 if it | ||
14235 | * comes up less than 0x20). | ||
14236 | */ | ||
14237 | if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < 0x20) { | ||
14238 | DvcAdvWritePCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer, | ||
14239 | 0x20); | ||
14240 | if (DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigLatencyTimer) < | ||
14241 | 0x20) { | ||
14242 | warn_code |= ASC_WARN_SET_PCI_CONFIG_SPACE; | ||
14243 | } | ||
14244 | } | ||
14245 | |||
14246 | /* | ||
14247 | * Save the state of the PCI Configuration Command Register | ||
14248 | * "Parity Error Response Control" Bit. If the bit is clear (0), | ||
14249 | * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore | ||
14250 | * DMA parity errors. | ||
14251 | */ | ||
14252 | asc_dvc->cfg->control_flag = 0; | ||
14253 | if (((DvcAdvReadPCIConfigByte(asc_dvc, AscPCIConfigCommandRegister) | ||
14254 | & AscPCICmdRegBits_ParErrRespCtrl)) == 0) { | ||
14255 | asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR; | ||
14256 | } | ||
14257 | |||
14258 | asc_dvc->cfg->lib_version = (ADV_LIB_VERSION_MAJOR << 8) | | ||
14259 | ADV_LIB_VERSION_MINOR; | ||
14260 | asc_dvc->cfg->chip_version = | ||
14261 | AdvGetChipVersion(iop_base, asc_dvc->bus_type); | ||
14262 | |||
14263 | ASC_DBG2(1, "AdvInitGetConfig: iopb_chip_id_1: 0x%x 0x%x\n", | ||
14264 | (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1), | ||
14265 | (ushort)ADV_CHIP_ID_BYTE); | ||
14266 | |||
14267 | ASC_DBG2(1, "AdvInitGetConfig: iopw_chip_id_0: 0x%x 0x%x\n", | ||
14268 | (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0), | ||
14269 | (ushort)ADV_CHIP_ID_WORD); | ||
14270 | |||
14271 | /* | ||
14272 | * Reset the chip to start and allow register writes. | ||
14273 | */ | ||
14274 | if (AdvFindSignature(iop_base) == 0) { | ||
14275 | asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; | ||
14276 | return ADV_ERROR; | ||
14277 | } else { | ||
14278 | /* | ||
14279 | * The caller must set 'chip_type' to a valid setting. | ||
14280 | */ | ||
14281 | if (asc_dvc->chip_type != ADV_CHIP_ASC3550 && | ||
14282 | asc_dvc->chip_type != ADV_CHIP_ASC38C0800 && | ||
14283 | asc_dvc->chip_type != ADV_CHIP_ASC38C1600) { | ||
14284 | asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE; | ||
14285 | return ADV_ERROR; | ||
14286 | } | ||
14287 | |||
14288 | /* | ||
14289 | * Reset Chip. | ||
14290 | */ | ||
14291 | AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, | ||
14292 | ADV_CTRL_REG_CMD_RESET); | ||
14293 | DvcSleepMilliSecond(100); | ||
14294 | AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, | ||
14295 | ADV_CTRL_REG_CMD_WR_IO_REG); | ||
14296 | 12237 | ||
14297 | if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { | 12238 | for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) { |
14298 | if ((status = | 12239 | if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & |
14299 | AdvInitFrom38C1600EEP(asc_dvc)) == ADV_ERROR) { | 12240 | ASC_EEP_CMD_DONE) { |
14300 | return ADV_ERROR; | 12241 | break; |
14301 | } | ||
14302 | } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) { | ||
14303 | if ((status = | ||
14304 | AdvInitFrom38C0800EEP(asc_dvc)) == ADV_ERROR) { | ||
14305 | return ADV_ERROR; | ||
14306 | } | ||
14307 | } else { | ||
14308 | if ((status = AdvInitFrom3550EEP(asc_dvc)) == ADV_ERROR) { | ||
14309 | return ADV_ERROR; | ||
14310 | } | ||
14311 | } | 12242 | } |
14312 | warn_code |= status; | 12243 | mdelay(1); |
14313 | } | 12244 | } |
14314 | 12245 | if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == | |
14315 | return warn_code; | 12246 | 0) |
12247 | BUG(); | ||
14316 | } | 12248 | } |
14317 | 12249 | ||
14318 | /* | 12250 | /* |
14319 | * Initialize the ASC-3550. | 12251 | * Read the EEPROM from specified location |
14320 | * | ||
14321 | * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. | ||
14322 | * | ||
14323 | * For a non-fatal error return a warning code. If there are no warnings | ||
14324 | * then 0 is returned. | ||
14325 | * | ||
14326 | * Needed after initialization for error recovery. | ||
14327 | */ | 12252 | */ |
14328 | static int AdvInitAsc3550Driver(ADV_DVC_VAR *asc_dvc) | 12253 | static ushort __devinit AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr) |
14329 | { | 12254 | { |
14330 | AdvPortAddr iop_base; | 12255 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, |
14331 | ushort warn_code; | 12256 | ASC_EEP_CMD_READ | eep_word_addr); |
14332 | ADV_DCNT sum; | 12257 | AdvWaitEEPCmd(iop_base); |
14333 | int begin_addr; | 12258 | return AdvReadWordRegister(iop_base, IOPW_EE_DATA); |
14334 | int end_addr; | 12259 | } |
14335 | ushort code_sum; | ||
14336 | int word; | ||
14337 | int j; | ||
14338 | int adv_asc3550_expanded_size; | ||
14339 | ADV_CARR_T *carrp; | ||
14340 | ADV_DCNT contig_len; | ||
14341 | ADV_SDCNT buf_size; | ||
14342 | ADV_PADDR carr_paddr; | ||
14343 | int i; | ||
14344 | ushort scsi_cfg1; | ||
14345 | uchar tid; | ||
14346 | ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */ | ||
14347 | ushort wdtr_able = 0, sdtr_able, tagqng_able; | ||
14348 | uchar max_cmd[ADV_MAX_TID + 1]; | ||
14349 | |||
14350 | /* If there is already an error, don't continue. */ | ||
14351 | if (asc_dvc->err_code != 0) { | ||
14352 | return ADV_ERROR; | ||
14353 | } | ||
14354 | 12260 | ||
14355 | /* | 12261 | /* |
14356 | * The caller must set 'chip_type' to ADV_CHIP_ASC3550. | 12262 | * Write the EEPROM from 'cfg_buf'. |
14357 | */ | 12263 | */ |
14358 | if (asc_dvc->chip_type != ADV_CHIP_ASC3550) { | 12264 | void __devinit |
14359 | asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE; | 12265 | AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) |
14360 | return ADV_ERROR; | 12266 | { |
14361 | } | 12267 | ushort *wbuf; |
12268 | ushort addr, chksum; | ||
12269 | ushort *charfields; | ||
14362 | 12270 | ||
14363 | warn_code = 0; | 12271 | wbuf = (ushort *)cfg_buf; |
14364 | iop_base = asc_dvc->iop_base; | 12272 | charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar; |
12273 | chksum = 0; | ||
14365 | 12274 | ||
14366 | /* | 12275 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE); |
14367 | * Save the RISC memory BIOS region before writing the microcode. | 12276 | AdvWaitEEPCmd(iop_base); |
14368 | * The BIOS may already be loaded and using its RISC LRAM region | ||
14369 | * so its region must be saved and restored. | ||
14370 | * | ||
14371 | * Note: This code makes the assumption, which is currently true, | ||
14372 | * that a chip reset does not clear RISC LRAM. | ||
14373 | */ | ||
14374 | for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { | ||
14375 | AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), | ||
14376 | bios_mem[i]); | ||
14377 | } | ||
14378 | 12277 | ||
14379 | /* | 12278 | /* |
14380 | * Save current per TID negotiated values. | 12279 | * Write EEPROM from word 0 to word 20. |
14381 | */ | 12280 | */ |
14382 | if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == 0x55AA) { | 12281 | for (addr = ADV_EEP_DVC_CFG_BEGIN; |
14383 | ushort bios_version, major, minor; | 12282 | addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) { |
14384 | 12283 | ushort word; | |
14385 | bios_version = | ||
14386 | bios_mem[(ASC_MC_BIOS_VERSION - ASC_MC_BIOSMEM) / 2]; | ||
14387 | major = (bios_version >> 12) & 0xF; | ||
14388 | minor = (bios_version >> 8) & 0xF; | ||
14389 | if (major < 3 || (major == 3 && minor == 1)) { | ||
14390 | /* BIOS 3.1 and earlier location of 'wdtr_able' variable. */ | ||
14391 | AdvReadWordLram(iop_base, 0x120, wdtr_able); | ||
14392 | } else { | ||
14393 | AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
14394 | } | ||
14395 | } | ||
14396 | AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
14397 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | ||
14398 | for (tid = 0; tid <= ADV_MAX_TID; tid++) { | ||
14399 | AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
14400 | max_cmd[tid]); | ||
14401 | } | ||
14402 | 12284 | ||
14403 | /* | 12285 | if (*charfields++) { |
14404 | * Load the Microcode | 12286 | word = cpu_to_le16(*wbuf); |
14405 | * | ||
14406 | * Write the microcode image to RISC memory starting at address 0. | ||
14407 | */ | ||
14408 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); | ||
14409 | /* Assume the following compressed format of the microcode buffer: | ||
14410 | * | ||
14411 | * 254 word (508 byte) table indexed by byte code followed | ||
14412 | * by the following byte codes: | ||
14413 | * | ||
14414 | * 1-Byte Code: | ||
14415 | * 00: Emit word 0 in table. | ||
14416 | * 01: Emit word 1 in table. | ||
14417 | * . | ||
14418 | * FD: Emit word 253 in table. | ||
14419 | * | ||
14420 | * Multi-Byte Code: | ||
14421 | * FE WW WW: (3 byte code) Word to emit is the next word WW WW. | ||
14422 | * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. | ||
14423 | */ | ||
14424 | word = 0; | ||
14425 | for (i = 253 * 2; i < _adv_asc3550_size; i++) { | ||
14426 | if (_adv_asc3550_buf[i] == 0xff) { | ||
14427 | for (j = 0; j < _adv_asc3550_buf[i + 1]; j++) { | ||
14428 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | ||
14429 | _adv_asc3550_buf | ||
14430 | [i + | ||
14431 | 3] << 8) | | ||
14432 | _adv_asc3550_buf | ||
14433 | [i + 2])); | ||
14434 | word++; | ||
14435 | } | ||
14436 | i += 3; | ||
14437 | } else if (_adv_asc3550_buf[i] == 0xfe) { | ||
14438 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | ||
14439 | _adv_asc3550_buf[i + | ||
14440 | 2] | ||
14441 | << 8) | | ||
14442 | _adv_asc3550_buf[i + | ||
14443 | 1])); | ||
14444 | i += 2; | ||
14445 | word++; | ||
14446 | } else { | 12287 | } else { |
14447 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | 12288 | word = *wbuf; |
14448 | _adv_asc3550_buf[(_adv_asc3550_buf[i] * 2) + 1] << 8) | _adv_asc3550_buf[_adv_asc3550_buf[i] * 2])); | ||
14449 | word++; | ||
14450 | } | 12289 | } |
12290 | chksum += *wbuf; /* Checksum is calculated from word values. */ | ||
12291 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); | ||
12292 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, | ||
12293 | ASC_EEP_CMD_WRITE | addr); | ||
12294 | AdvWaitEEPCmd(iop_base); | ||
12295 | mdelay(ADV_EEP_DELAY_MS); | ||
14451 | } | 12296 | } |
14452 | 12297 | ||
14453 | /* | 12298 | /* |
14454 | * Set 'word' for later use to clear the rest of memory and save | 12299 | * Write EEPROM checksum at word 21. |
14455 | * the expanded mcode size. | ||
14456 | */ | ||
14457 | word *= 2; | ||
14458 | adv_asc3550_expanded_size = word; | ||
14459 | |||
14460 | /* | ||
14461 | * Clear the rest of ASC-3550 Internal RAM (8KB). | ||
14462 | */ | ||
14463 | for (; word < ADV_3550_MEMSIZE; word += 2) { | ||
14464 | AdvWriteWordAutoIncLram(iop_base, 0); | ||
14465 | } | ||
14466 | |||
14467 | /* | ||
14468 | * Verify the microcode checksum. | ||
14469 | */ | ||
14470 | sum = 0; | ||
14471 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); | ||
14472 | |||
14473 | for (word = 0; word < adv_asc3550_expanded_size; word += 2) { | ||
14474 | sum += AdvReadWordAutoIncLram(iop_base); | ||
14475 | } | ||
14476 | |||
14477 | if (sum != _adv_asc3550_chksum) { | ||
14478 | asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; | ||
14479 | return ADV_ERROR; | ||
14480 | } | ||
14481 | |||
14482 | /* | ||
14483 | * Restore the RISC memory BIOS region. | ||
14484 | */ | ||
14485 | for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { | ||
14486 | AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), | ||
14487 | bios_mem[i]); | ||
14488 | } | ||
14489 | |||
14490 | /* | ||
14491 | * Calculate and write the microcode code checksum to the microcode | ||
14492 | * code checksum location ASC_MC_CODE_CHK_SUM (0x2C). | ||
14493 | */ | ||
14494 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr); | ||
14495 | AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr); | ||
14496 | code_sum = 0; | ||
14497 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr); | ||
14498 | for (word = begin_addr; word < end_addr; word += 2) { | ||
14499 | code_sum += AdvReadWordAutoIncLram(iop_base); | ||
14500 | } | ||
14501 | AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum); | ||
14502 | |||
14503 | /* | ||
14504 | * Read and save microcode version and date. | ||
14505 | */ | ||
14506 | AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, | ||
14507 | asc_dvc->cfg->mcode_date); | ||
14508 | AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, | ||
14509 | asc_dvc->cfg->mcode_version); | ||
14510 | |||
14511 | /* | ||
14512 | * Set the chip type to indicate the ASC3550. | ||
14513 | */ | ||
14514 | AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC3550); | ||
14515 | |||
14516 | /* | ||
14517 | * If the PCI Configuration Command Register "Parity Error Response | ||
14518 | * Control" Bit was clear (0), then set the microcode variable | ||
14519 | * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode | ||
14520 | * to ignore DMA parity errors. | ||
14521 | */ | ||
14522 | if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) { | ||
14523 | AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
14524 | word |= CONTROL_FLAG_IGNORE_PERR; | ||
14525 | AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
14526 | } | ||
14527 | |||
14528 | /* | ||
14529 | * For ASC-3550, setting the START_CTL_EMFU [3:2] bits sets a FIFO | ||
14530 | * threshold of 128 bytes. This register is only accessible to the host. | ||
14531 | */ | 12300 | */ |
14532 | AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0, | 12301 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum); |
14533 | START_CTL_EMFU | READ_CMD_MRM); | 12302 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); |
12303 | AdvWaitEEPCmd(iop_base); | ||
12304 | wbuf++; | ||
12305 | charfields++; | ||
14534 | 12306 | ||
14535 | /* | 12307 | /* |
14536 | * Microcode operating variables for WDTR, SDTR, and command tag | 12308 | * Write EEPROM OEM name at words 22 to 29. |
14537 | * queuing will be set in AdvInquiryHandling() based on what a | ||
14538 | * device reports it is capable of in Inquiry byte 7. | ||
14539 | * | ||
14540 | * If SCSI Bus Resets have been disabled, then directly set | ||
14541 | * SDTR and WDTR from the EEPROM configuration. This will allow | ||
14542 | * the BIOS and warm boot to work without a SCSI bus hang on | ||
14543 | * the Inquiry caused by host and target mismatched DTR values. | ||
14544 | * Without the SCSI Bus Reset, before an Inquiry a device can't | ||
14545 | * be assumed to be in Asynchronous, Narrow mode. | ||
14546 | */ | 12309 | */ |
14547 | if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) { | 12310 | for (addr = ADV_EEP_DVC_CTL_BEGIN; |
14548 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, | 12311 | addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) { |
14549 | asc_dvc->wdtr_able); | 12312 | ushort word; |
14550 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, | ||
14551 | asc_dvc->sdtr_able); | ||
14552 | } | ||
14553 | 12313 | ||
14554 | /* | 12314 | if (*charfields++) { |
14555 | * Set microcode operating variables for SDTR_SPEED1, SDTR_SPEED2, | 12315 | word = cpu_to_le16(*wbuf); |
14556 | * SDTR_SPEED3, and SDTR_SPEED4 based on the ULTRA EEPROM per TID | ||
14557 | * bitmask. These values determine the maximum SDTR speed negotiated | ||
14558 | * with a device. | ||
14559 | * | ||
14560 | * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, | ||
14561 | * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them | ||
14562 | * without determining here whether the device supports SDTR. | ||
14563 | * | ||
14564 | * 4-bit speed SDTR speed name | ||
14565 | * =========== =============== | ||
14566 | * 0000b (0x0) SDTR disabled | ||
14567 | * 0001b (0x1) 5 Mhz | ||
14568 | * 0010b (0x2) 10 Mhz | ||
14569 | * 0011b (0x3) 20 Mhz (Ultra) | ||
14570 | * 0100b (0x4) 40 Mhz (LVD/Ultra2) | ||
14571 | * 0101b (0x5) 80 Mhz (LVD2/Ultra3) | ||
14572 | * 0110b (0x6) Undefined | ||
14573 | * . | ||
14574 | * 1111b (0xF) Undefined | ||
14575 | */ | ||
14576 | word = 0; | ||
14577 | for (tid = 0; tid <= ADV_MAX_TID; tid++) { | ||
14578 | if (ADV_TID_TO_TIDMASK(tid) & asc_dvc->ultra_able) { | ||
14579 | /* Set Ultra speed for TID 'tid'. */ | ||
14580 | word |= (0x3 << (4 * (tid % 4))); | ||
14581 | } else { | 12316 | } else { |
14582 | /* Set Fast speed for TID 'tid'. */ | 12317 | word = *wbuf; |
14583 | word |= (0x2 << (4 * (tid % 4))); | ||
14584 | } | ||
14585 | if (tid == 3) { /* Check if done with sdtr_speed1. */ | ||
14586 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, word); | ||
14587 | word = 0; | ||
14588 | } else if (tid == 7) { /* Check if done with sdtr_speed2. */ | ||
14589 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, word); | ||
14590 | word = 0; | ||
14591 | } else if (tid == 11) { /* Check if done with sdtr_speed3. */ | ||
14592 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, word); | ||
14593 | word = 0; | ||
14594 | } else if (tid == 15) { /* Check if done with sdtr_speed4. */ | ||
14595 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, word); | ||
14596 | /* End of loop. */ | ||
14597 | } | ||
14598 | } | ||
14599 | |||
14600 | /* | ||
14601 | * Set microcode operating variable for the disconnect per TID bitmask. | ||
14602 | */ | ||
14603 | AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, | ||
14604 | asc_dvc->cfg->disc_enable); | ||
14605 | |||
14606 | /* | ||
14607 | * Set SCSI_CFG0 Microcode Default Value. | ||
14608 | * | ||
14609 | * The microcode will set the SCSI_CFG0 register using this value | ||
14610 | * after it is started below. | ||
14611 | */ | ||
14612 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0, | ||
14613 | PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN | | ||
14614 | asc_dvc->chip_scsi_id); | ||
14615 | |||
14616 | /* | ||
14617 | * Determine SCSI_CFG1 Microcode Default Value. | ||
14618 | * | ||
14619 | * The microcode will set the SCSI_CFG1 register using this value | ||
14620 | * after it is started below. | ||
14621 | */ | ||
14622 | |||
14623 | /* Read current SCSI_CFG1 Register value. */ | ||
14624 | scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); | ||
14625 | |||
14626 | /* | ||
14627 | * If all three connectors are in use, return an error. | ||
14628 | */ | ||
14629 | if ((scsi_cfg1 & CABLE_ILLEGAL_A) == 0 || | ||
14630 | (scsi_cfg1 & CABLE_ILLEGAL_B) == 0) { | ||
14631 | asc_dvc->err_code |= ASC_IERR_ILLEGAL_CONNECTION; | ||
14632 | return ADV_ERROR; | ||
14633 | } | ||
14634 | |||
14635 | /* | ||
14636 | * If the internal narrow cable is reversed all of the SCSI_CTRL | ||
14637 | * register signals will be set. Check for and return an error if | ||
14638 | * this condition is found. | ||
14639 | */ | ||
14640 | if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) { | ||
14641 | asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE; | ||
14642 | return ADV_ERROR; | ||
14643 | } | ||
14644 | |||
14645 | /* | ||
14646 | * If this is a differential board and a single-ended device | ||
14647 | * is attached to one of the connectors, return an error. | ||
14648 | */ | ||
14649 | if ((scsi_cfg1 & DIFF_MODE) && (scsi_cfg1 & DIFF_SENSE) == 0) { | ||
14650 | asc_dvc->err_code |= ASC_IERR_SINGLE_END_DEVICE; | ||
14651 | return ADV_ERROR; | ||
14652 | } | ||
14653 | |||
14654 | /* | ||
14655 | * If automatic termination control is enabled, then set the | ||
14656 | * termination value based on a table listed in a_condor.h. | ||
14657 | * | ||
14658 | * If manual termination was specified with an EEPROM setting | ||
14659 | * then 'termination' was set-up in AdvInitFrom3550EEPROM() and | ||
14660 | * is ready to be 'ored' into SCSI_CFG1. | ||
14661 | */ | ||
14662 | if (asc_dvc->cfg->termination == 0) { | ||
14663 | /* | ||
14664 | * The software always controls termination by setting TERM_CTL_SEL. | ||
14665 | * If TERM_CTL_SEL were set to 0, the hardware would set termination. | ||
14666 | */ | ||
14667 | asc_dvc->cfg->termination |= TERM_CTL_SEL; | ||
14668 | |||
14669 | switch (scsi_cfg1 & CABLE_DETECT) { | ||
14670 | /* TERM_CTL_H: on, TERM_CTL_L: on */ | ||
14671 | case 0x3: | ||
14672 | case 0x7: | ||
14673 | case 0xB: | ||
14674 | case 0xD: | ||
14675 | case 0xE: | ||
14676 | case 0xF: | ||
14677 | asc_dvc->cfg->termination |= (TERM_CTL_H | TERM_CTL_L); | ||
14678 | break; | ||
14679 | |||
14680 | /* TERM_CTL_H: on, TERM_CTL_L: off */ | ||
14681 | case 0x1: | ||
14682 | case 0x5: | ||
14683 | case 0x9: | ||
14684 | case 0xA: | ||
14685 | case 0xC: | ||
14686 | asc_dvc->cfg->termination |= TERM_CTL_H; | ||
14687 | break; | ||
14688 | |||
14689 | /* TERM_CTL_H: off, TERM_CTL_L: off */ | ||
14690 | case 0x2: | ||
14691 | case 0x6: | ||
14692 | break; | ||
14693 | } | 12318 | } |
12319 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); | ||
12320 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, | ||
12321 | ASC_EEP_CMD_WRITE | addr); | ||
12322 | AdvWaitEEPCmd(iop_base); | ||
14694 | } | 12323 | } |
12324 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE); | ||
12325 | AdvWaitEEPCmd(iop_base); | ||
12326 | } | ||
14695 | 12327 | ||
14696 | /* | 12328 | /* |
14697 | * Clear any set TERM_CTL_H and TERM_CTL_L bits. | 12329 | * Write the EEPROM from 'cfg_buf'. |
14698 | */ | 12330 | */ |
14699 | scsi_cfg1 &= ~TERM_CTL; | 12331 | void __devinit |
14700 | 12332 | AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf) | |
14701 | /* | 12333 | { |
14702 | * Invert the TERM_CTL_H and TERM_CTL_L bits and then | 12334 | ushort *wbuf; |
14703 | * set 'scsi_cfg1'. The TERM_POL bit does not need to be | 12335 | ushort *charfields; |
14704 | * referenced, because the hardware internally inverts | 12336 | ushort addr, chksum; |
14705 | * the Termination High and Low bits if TERM_POL is set. | ||
14706 | */ | ||
14707 | scsi_cfg1 |= (TERM_CTL_SEL | (~asc_dvc->cfg->termination & TERM_CTL)); | ||
14708 | |||
14709 | /* | ||
14710 | * Set SCSI_CFG1 Microcode Default Value | ||
14711 | * | ||
14712 | * Set filter value and possibly modified termination control | ||
14713 | * bits in the Microcode SCSI_CFG1 Register Value. | ||
14714 | * | ||
14715 | * The microcode will set the SCSI_CFG1 register using this value | ||
14716 | * after it is started below. | ||
14717 | */ | ||
14718 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, | ||
14719 | FLTR_DISABLE | scsi_cfg1); | ||
14720 | 12337 | ||
14721 | /* | 12338 | wbuf = (ushort *)cfg_buf; |
14722 | * Set MEM_CFG Microcode Default Value | 12339 | charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar; |
14723 | * | 12340 | chksum = 0; |
14724 | * The microcode will set the MEM_CFG register using this value | ||
14725 | * after it is started below. | ||
14726 | * | ||
14727 | * MEM_CFG may be accessed as a word or byte, but only bits 0-7 | ||
14728 | * are defined. | ||
14729 | * | ||
14730 | * ASC-3550 has 8KB internal memory. | ||
14731 | */ | ||
14732 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, | ||
14733 | BIOS_EN | RAM_SZ_8KB); | ||
14734 | 12341 | ||
14735 | /* | 12342 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE); |
14736 | * Set SEL_MASK Microcode Default Value | 12343 | AdvWaitEEPCmd(iop_base); |
14737 | * | ||
14738 | * The microcode will set the SEL_MASK register using this value | ||
14739 | * after it is started below. | ||
14740 | */ | ||
14741 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, | ||
14742 | ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); | ||
14743 | 12344 | ||
14744 | /* | 12345 | /* |
14745 | * Build carrier freelist. | 12346 | * Write EEPROM from word 0 to word 20. |
14746 | * | ||
14747 | * Driver must have already allocated memory and set 'carrier_buf'. | ||
14748 | */ | 12347 | */ |
14749 | ASC_ASSERT(asc_dvc->carrier_buf != NULL); | 12348 | for (addr = ADV_EEP_DVC_CFG_BEGIN; |
14750 | 12349 | addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) { | |
14751 | carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf); | 12350 | ushort word; |
14752 | asc_dvc->carr_freelist = NULL; | ||
14753 | if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) { | ||
14754 | buf_size = ADV_CARRIER_BUFSIZE; | ||
14755 | } else { | ||
14756 | buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T); | ||
14757 | } | ||
14758 | |||
14759 | do { | ||
14760 | /* | ||
14761 | * Get physical address of the carrier 'carrp'. | ||
14762 | */ | ||
14763 | contig_len = sizeof(ADV_CARR_T); | ||
14764 | carr_paddr = | ||
14765 | cpu_to_le32(DvcGetPhyAddr | ||
14766 | (asc_dvc, NULL, (uchar *)carrp, | ||
14767 | (ADV_SDCNT *)&contig_len, | ||
14768 | ADV_IS_CARRIER_FLAG)); | ||
14769 | |||
14770 | buf_size -= sizeof(ADV_CARR_T); | ||
14771 | 12351 | ||
14772 | /* | 12352 | if (*charfields++) { |
14773 | * If the current carrier is not physically contiguous, then | 12353 | word = cpu_to_le16(*wbuf); |
14774 | * maybe there was a page crossing. Try the next carrier aligned | 12354 | } else { |
14775 | * start address. | 12355 | word = *wbuf; |
14776 | */ | ||
14777 | if (contig_len < sizeof(ADV_CARR_T)) { | ||
14778 | carrp++; | ||
14779 | continue; | ||
14780 | } | 12356 | } |
14781 | 12357 | chksum += *wbuf; /* Checksum is calculated from word values. */ | |
14782 | carrp->carr_pa = carr_paddr; | 12358 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); |
14783 | carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp)); | 12359 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, |
14784 | 12360 | ASC_EEP_CMD_WRITE | addr); | |
14785 | /* | 12361 | AdvWaitEEPCmd(iop_base); |
14786 | * Insert the carrier at the beginning of the freelist. | 12362 | mdelay(ADV_EEP_DELAY_MS); |
14787 | */ | ||
14788 | carrp->next_vpa = | ||
14789 | cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); | ||
14790 | asc_dvc->carr_freelist = carrp; | ||
14791 | |||
14792 | carrp++; | ||
14793 | } | ||
14794 | while (buf_size > 0); | ||
14795 | |||
14796 | /* | ||
14797 | * Set-up the Host->RISC Initiator Command Queue (ICQ). | ||
14798 | */ | ||
14799 | |||
14800 | if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) { | ||
14801 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; | ||
14802 | return ADV_ERROR; | ||
14803 | } | ||
14804 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
14805 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa)); | ||
14806 | |||
14807 | /* | ||
14808 | * The first command issued will be placed in the stopper carrier. | ||
14809 | */ | ||
14810 | asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
14811 | |||
14812 | /* | ||
14813 | * Set RISC ICQ physical address start value. | ||
14814 | */ | ||
14815 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa); | ||
14816 | |||
14817 | /* | ||
14818 | * Set-up the RISC->Host Initiator Response Queue (IRQ). | ||
14819 | */ | ||
14820 | if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) { | ||
14821 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; | ||
14822 | return ADV_ERROR; | ||
14823 | } | 12363 | } |
14824 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
14825 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa)); | ||
14826 | 12364 | ||
14827 | /* | 12365 | /* |
14828 | * The first command completed by the RISC will be placed in | 12366 | * Write EEPROM checksum at word 21. |
14829 | * the stopper. | ||
14830 | * | ||
14831 | * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is | ||
14832 | * completed the RISC will set the ASC_RQ_STOPPER bit. | ||
14833 | */ | 12367 | */ |
14834 | asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | 12368 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum); |
12369 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); | ||
12370 | AdvWaitEEPCmd(iop_base); | ||
12371 | wbuf++; | ||
12372 | charfields++; | ||
14835 | 12373 | ||
14836 | /* | 12374 | /* |
14837 | * Set RISC IRQ physical address start value. | 12375 | * Write EEPROM OEM name at words 22 to 29. |
14838 | */ | 12376 | */ |
14839 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa); | 12377 | for (addr = ADV_EEP_DVC_CTL_BEGIN; |
14840 | asc_dvc->carr_pending_cnt = 0; | 12378 | addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) { |
14841 | 12379 | ushort word; | |
14842 | AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES, | ||
14843 | (ADV_INTR_ENABLE_HOST_INTR | | ||
14844 | ADV_INTR_ENABLE_GLOBAL_INTR)); | ||
14845 | |||
14846 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word); | ||
14847 | AdvWriteWordRegister(iop_base, IOPW_PC, word); | ||
14848 | |||
14849 | /* finally, finally, gentlemen, start your engine */ | ||
14850 | AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN); | ||
14851 | 12380 | ||
14852 | /* | 12381 | if (*charfields++) { |
14853 | * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus | 12382 | word = cpu_to_le16(*wbuf); |
14854 | * Resets should be performed. The RISC has to be running | ||
14855 | * to issue a SCSI Bus Reset. | ||
14856 | */ | ||
14857 | if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) { | ||
14858 | /* | ||
14859 | * If the BIOS Signature is present in memory, restore the | ||
14860 | * BIOS Handshake Configuration Table and do not perform | ||
14861 | * a SCSI Bus Reset. | ||
14862 | */ | ||
14863 | if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == | ||
14864 | 0x55AA) { | ||
14865 | /* | ||
14866 | * Restore per TID negotiated values. | ||
14867 | */ | ||
14868 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
14869 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
14870 | AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, | ||
14871 | tagqng_able); | ||
14872 | for (tid = 0; tid <= ADV_MAX_TID; tid++) { | ||
14873 | AdvWriteByteLram(iop_base, | ||
14874 | ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
14875 | max_cmd[tid]); | ||
14876 | } | ||
14877 | } else { | 12383 | } else { |
14878 | if (AdvResetSB(asc_dvc) != ADV_TRUE) { | 12384 | word = *wbuf; |
14879 | warn_code = ASC_WARN_BUSRESET_ERROR; | ||
14880 | } | ||
14881 | } | 12385 | } |
12386 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); | ||
12387 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, | ||
12388 | ASC_EEP_CMD_WRITE | addr); | ||
12389 | AdvWaitEEPCmd(iop_base); | ||
14882 | } | 12390 | } |
14883 | 12391 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE); | |
14884 | return warn_code; | 12392 | AdvWaitEEPCmd(iop_base); |
14885 | } | 12393 | } |
14886 | 12394 | ||
14887 | /* | 12395 | /* |
14888 | * Initialize the ASC-38C0800. | 12396 | * Write the EEPROM from 'cfg_buf'. |
14889 | * | ||
14890 | * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. | ||
14891 | * | ||
14892 | * For a non-fatal error return a warning code. If there are no warnings | ||
14893 | * then 0 is returned. | ||
14894 | * | ||
14895 | * Needed after initialization for error recovery. | ||
14896 | */ | 12397 | */ |
14897 | static int AdvInitAsc38C0800Driver(ADV_DVC_VAR *asc_dvc) | 12398 | void __devinit |
12399 | AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf) | ||
14898 | { | 12400 | { |
14899 | AdvPortAddr iop_base; | 12401 | ushort *wbuf; |
14900 | ushort warn_code; | 12402 | ushort *charfields; |
14901 | ADV_DCNT sum; | 12403 | ushort addr, chksum; |
14902 | int begin_addr; | ||
14903 | int end_addr; | ||
14904 | ushort code_sum; | ||
14905 | int word; | ||
14906 | int j; | ||
14907 | int adv_asc38C0800_expanded_size; | ||
14908 | ADV_CARR_T *carrp; | ||
14909 | ADV_DCNT contig_len; | ||
14910 | ADV_SDCNT buf_size; | ||
14911 | ADV_PADDR carr_paddr; | ||
14912 | int i; | ||
14913 | ushort scsi_cfg1; | ||
14914 | uchar byte; | ||
14915 | uchar tid; | ||
14916 | ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */ | ||
14917 | ushort wdtr_able, sdtr_able, tagqng_able; | ||
14918 | uchar max_cmd[ADV_MAX_TID + 1]; | ||
14919 | |||
14920 | /* If there is already an error, don't continue. */ | ||
14921 | if (asc_dvc->err_code != 0) { | ||
14922 | return ADV_ERROR; | ||
14923 | } | ||
14924 | |||
14925 | /* | ||
14926 | * The caller must set 'chip_type' to ADV_CHIP_ASC38C0800. | ||
14927 | */ | ||
14928 | if (asc_dvc->chip_type != ADV_CHIP_ASC38C0800) { | ||
14929 | asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE; | ||
14930 | return ADV_ERROR; | ||
14931 | } | ||
14932 | |||
14933 | warn_code = 0; | ||
14934 | iop_base = asc_dvc->iop_base; | ||
14935 | |||
14936 | /* | ||
14937 | * Save the RISC memory BIOS region before writing the microcode. | ||
14938 | * The BIOS may already be loaded and using its RISC LRAM region | ||
14939 | * so its region must be saved and restored. | ||
14940 | * | ||
14941 | * Note: This code makes the assumption, which is currently true, | ||
14942 | * that a chip reset does not clear RISC LRAM. | ||
14943 | */ | ||
14944 | for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { | ||
14945 | AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), | ||
14946 | bios_mem[i]); | ||
14947 | } | ||
14948 | |||
14949 | /* | ||
14950 | * Save current per TID negotiated values. | ||
14951 | */ | ||
14952 | AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
14953 | AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
14954 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | ||
14955 | for (tid = 0; tid <= ADV_MAX_TID; tid++) { | ||
14956 | AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
14957 | max_cmd[tid]); | ||
14958 | } | ||
14959 | |||
14960 | /* | ||
14961 | * RAM BIST (RAM Built-In Self Test) | ||
14962 | * | ||
14963 | * Address : I/O base + offset 0x38h register (byte). | ||
14964 | * Function: Bit 7-6(RW) : RAM mode | ||
14965 | * Normal Mode : 0x00 | ||
14966 | * Pre-test Mode : 0x40 | ||
14967 | * RAM Test Mode : 0x80 | ||
14968 | * Bit 5 : unused | ||
14969 | * Bit 4(RO) : Done bit | ||
14970 | * Bit 3-0(RO) : Status | ||
14971 | * Host Error : 0x08 | ||
14972 | * Int_RAM Error : 0x04 | ||
14973 | * RISC Error : 0x02 | ||
14974 | * SCSI Error : 0x01 | ||
14975 | * No Error : 0x00 | ||
14976 | * | ||
14977 | * Note: RAM BIST code should be put right here, before loading the | ||
14978 | * microcode and after saving the RISC memory BIOS region. | ||
14979 | */ | ||
14980 | |||
14981 | /* | ||
14982 | * LRAM Pre-test | ||
14983 | * | ||
14984 | * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds. | ||
14985 | * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return | ||
14986 | * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset | ||
14987 | * to NORMAL_MODE, return an error too. | ||
14988 | */ | ||
14989 | for (i = 0; i < 2; i++) { | ||
14990 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE); | ||
14991 | DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ | ||
14992 | byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); | ||
14993 | if ((byte & RAM_TEST_DONE) == 0 | ||
14994 | || (byte & 0x0F) != PRE_TEST_VALUE) { | ||
14995 | asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; | ||
14996 | return ADV_ERROR; | ||
14997 | } | ||
14998 | |||
14999 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); | ||
15000 | DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ | ||
15001 | if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) | ||
15002 | != NORMAL_VALUE) { | ||
15003 | asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; | ||
15004 | return ADV_ERROR; | ||
15005 | } | ||
15006 | } | ||
15007 | |||
15008 | /* | ||
15009 | * LRAM Test - It takes about 1.5 ms to run through the test. | ||
15010 | * | ||
15011 | * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds. | ||
15012 | * If Done bit not set or Status not 0, save register byte, set the | ||
15013 | * err_code, and return an error. | ||
15014 | */ | ||
15015 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE); | ||
15016 | DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */ | ||
15017 | 12404 | ||
15018 | byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); | 12405 | wbuf = (ushort *)cfg_buf; |
15019 | if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) { | 12406 | charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar; |
15020 | /* Get here if Done bit not set or Status not 0. */ | 12407 | chksum = 0; |
15021 | asc_dvc->bist_err_code = byte; /* for BIOS display message */ | ||
15022 | asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST; | ||
15023 | return ADV_ERROR; | ||
15024 | } | ||
15025 | 12408 | ||
15026 | /* We need to reset back to normal mode after LRAM test passes. */ | 12409 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE); |
15027 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); | 12410 | AdvWaitEEPCmd(iop_base); |
15028 | 12411 | ||
15029 | /* | 12412 | /* |
15030 | * Load the Microcode | 12413 | * Write EEPROM from word 0 to word 20. |
15031 | * | ||
15032 | * Write the microcode image to RISC memory starting at address 0. | ||
15033 | * | ||
15034 | */ | 12414 | */ |
15035 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); | 12415 | for (addr = ADV_EEP_DVC_CFG_BEGIN; |
12416 | addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) { | ||
12417 | ushort word; | ||
15036 | 12418 | ||
15037 | /* Assume the following compressed format of the microcode buffer: | 12419 | if (*charfields++) { |
15038 | * | 12420 | word = cpu_to_le16(*wbuf); |
15039 | * 254 word (508 byte) table indexed by byte code followed | ||
15040 | * by the following byte codes: | ||
15041 | * | ||
15042 | * 1-Byte Code: | ||
15043 | * 00: Emit word 0 in table. | ||
15044 | * 01: Emit word 1 in table. | ||
15045 | * . | ||
15046 | * FD: Emit word 253 in table. | ||
15047 | * | ||
15048 | * Multi-Byte Code: | ||
15049 | * FE WW WW: (3 byte code) Word to emit is the next word WW WW. | ||
15050 | * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. | ||
15051 | */ | ||
15052 | word = 0; | ||
15053 | for (i = 253 * 2; i < _adv_asc38C0800_size; i++) { | ||
15054 | if (_adv_asc38C0800_buf[i] == 0xff) { | ||
15055 | for (j = 0; j < _adv_asc38C0800_buf[i + 1]; j++) { | ||
15056 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | ||
15057 | _adv_asc38C0800_buf | ||
15058 | [i + | ||
15059 | 3] << 8) | | ||
15060 | _adv_asc38C0800_buf | ||
15061 | [i + 2])); | ||
15062 | word++; | ||
15063 | } | ||
15064 | i += 3; | ||
15065 | } else if (_adv_asc38C0800_buf[i] == 0xfe) { | ||
15066 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | ||
15067 | _adv_asc38C0800_buf | ||
15068 | [i + | ||
15069 | 2] << 8) | | ||
15070 | _adv_asc38C0800_buf[i | ||
15071 | + | ||
15072 | 1])); | ||
15073 | i += 2; | ||
15074 | word++; | ||
15075 | } else { | 12421 | } else { |
15076 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | 12422 | word = *wbuf; |
15077 | _adv_asc38C0800_buf[(_adv_asc38C0800_buf[i] * 2) + 1] << 8) | _adv_asc38C0800_buf[_adv_asc38C0800_buf[i] * 2])); | ||
15078 | word++; | ||
15079 | } | ||
15080 | } | ||
15081 | |||
15082 | /* | ||
15083 | * Set 'word' for later use to clear the rest of memory and save | ||
15084 | * the expanded mcode size. | ||
15085 | */ | ||
15086 | word *= 2; | ||
15087 | adv_asc38C0800_expanded_size = word; | ||
15088 | |||
15089 | /* | ||
15090 | * Clear the rest of ASC-38C0800 Internal RAM (16KB). | ||
15091 | */ | ||
15092 | for (; word < ADV_38C0800_MEMSIZE; word += 2) { | ||
15093 | AdvWriteWordAutoIncLram(iop_base, 0); | ||
15094 | } | ||
15095 | |||
15096 | /* | ||
15097 | * Verify the microcode checksum. | ||
15098 | */ | ||
15099 | sum = 0; | ||
15100 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); | ||
15101 | |||
15102 | for (word = 0; word < adv_asc38C0800_expanded_size; word += 2) { | ||
15103 | sum += AdvReadWordAutoIncLram(iop_base); | ||
15104 | } | ||
15105 | ASC_DBG2(1, "AdvInitAsc38C0800Driver: word %d, i %d\n", word, i); | ||
15106 | |||
15107 | ASC_DBG2(1, | ||
15108 | "AdvInitAsc38C0800Driver: sum 0x%lx, _adv_asc38C0800_chksum 0x%lx\n", | ||
15109 | (ulong)sum, (ulong)_adv_asc38C0800_chksum); | ||
15110 | |||
15111 | if (sum != _adv_asc38C0800_chksum) { | ||
15112 | asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; | ||
15113 | return ADV_ERROR; | ||
15114 | } | ||
15115 | |||
15116 | /* | ||
15117 | * Restore the RISC memory BIOS region. | ||
15118 | */ | ||
15119 | for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { | ||
15120 | AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), | ||
15121 | bios_mem[i]); | ||
15122 | } | ||
15123 | |||
15124 | /* | ||
15125 | * Calculate and write the microcode code checksum to the microcode | ||
15126 | * code checksum location ASC_MC_CODE_CHK_SUM (0x2C). | ||
15127 | */ | ||
15128 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr); | ||
15129 | AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr); | ||
15130 | code_sum = 0; | ||
15131 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr); | ||
15132 | for (word = begin_addr; word < end_addr; word += 2) { | ||
15133 | code_sum += AdvReadWordAutoIncLram(iop_base); | ||
15134 | } | ||
15135 | AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum); | ||
15136 | |||
15137 | /* | ||
15138 | * Read microcode version and date. | ||
15139 | */ | ||
15140 | AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, | ||
15141 | asc_dvc->cfg->mcode_date); | ||
15142 | AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, | ||
15143 | asc_dvc->cfg->mcode_version); | ||
15144 | |||
15145 | /* | ||
15146 | * Set the chip type to indicate the ASC38C0800. | ||
15147 | */ | ||
15148 | AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C0800); | ||
15149 | |||
15150 | /* | ||
15151 | * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register. | ||
15152 | * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current | ||
15153 | * cable detection and then we are able to read C_DET[3:0]. | ||
15154 | * | ||
15155 | * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1 | ||
15156 | * Microcode Default Value' section below. | ||
15157 | */ | ||
15158 | scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); | ||
15159 | AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, | ||
15160 | scsi_cfg1 | DIS_TERM_DRV); | ||
15161 | |||
15162 | /* | ||
15163 | * If the PCI Configuration Command Register "Parity Error Response | ||
15164 | * Control" Bit was clear (0), then set the microcode variable | ||
15165 | * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode | ||
15166 | * to ignore DMA parity errors. | ||
15167 | */ | ||
15168 | if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) { | ||
15169 | AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
15170 | word |= CONTROL_FLAG_IGNORE_PERR; | ||
15171 | AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
15172 | } | ||
15173 | |||
15174 | /* | ||
15175 | * For ASC-38C0800, set FIFO_THRESH_80B [6:4] bits and START_CTL_TH [3:2] | ||
15176 | * bits for the default FIFO threshold. | ||
15177 | * | ||
15178 | * Note: ASC-38C0800 FIFO threshold has been changed to 256 bytes. | ||
15179 | * | ||
15180 | * For DMA Errata #4 set the BC_THRESH_ENB bit. | ||
15181 | */ | ||
15182 | AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0, | ||
15183 | BC_THRESH_ENB | FIFO_THRESH_80B | START_CTL_TH | | ||
15184 | READ_CMD_MRM); | ||
15185 | |||
15186 | /* | ||
15187 | * Microcode operating variables for WDTR, SDTR, and command tag | ||
15188 | * queuing will be set in AdvInquiryHandling() based on what a | ||
15189 | * device reports it is capable of in Inquiry byte 7. | ||
15190 | * | ||
15191 | * If SCSI Bus Resets have been disabled, then directly set | ||
15192 | * SDTR and WDTR from the EEPROM configuration. This will allow | ||
15193 | * the BIOS and warm boot to work without a SCSI bus hang on | ||
15194 | * the Inquiry caused by host and target mismatched DTR values. | ||
15195 | * Without the SCSI Bus Reset, before an Inquiry a device can't | ||
15196 | * be assumed to be in Asynchronous, Narrow mode. | ||
15197 | */ | ||
15198 | if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) { | ||
15199 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, | ||
15200 | asc_dvc->wdtr_able); | ||
15201 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, | ||
15202 | asc_dvc->sdtr_able); | ||
15203 | } | ||
15204 | |||
15205 | /* | ||
15206 | * Set microcode operating variables for DISC and SDTR_SPEED1, | ||
15207 | * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM | ||
15208 | * configuration values. | ||
15209 | * | ||
15210 | * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, | ||
15211 | * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them | ||
15212 | * without determining here whether the device supports SDTR. | ||
15213 | */ | ||
15214 | AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, | ||
15215 | asc_dvc->cfg->disc_enable); | ||
15216 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1); | ||
15217 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2); | ||
15218 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3); | ||
15219 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4); | ||
15220 | |||
15221 | /* | ||
15222 | * Set SCSI_CFG0 Microcode Default Value. | ||
15223 | * | ||
15224 | * The microcode will set the SCSI_CFG0 register using this value | ||
15225 | * after it is started below. | ||
15226 | */ | ||
15227 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0, | ||
15228 | PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN | | ||
15229 | asc_dvc->chip_scsi_id); | ||
15230 | |||
15231 | /* | ||
15232 | * Determine SCSI_CFG1 Microcode Default Value. | ||
15233 | * | ||
15234 | * The microcode will set the SCSI_CFG1 register using this value | ||
15235 | * after it is started below. | ||
15236 | */ | ||
15237 | |||
15238 | /* Read current SCSI_CFG1 Register value. */ | ||
15239 | scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); | ||
15240 | |||
15241 | /* | ||
15242 | * If the internal narrow cable is reversed all of the SCSI_CTRL | ||
15243 | * register signals will be set. Check for and return an error if | ||
15244 | * this condition is found. | ||
15245 | */ | ||
15246 | if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) { | ||
15247 | asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE; | ||
15248 | return ADV_ERROR; | ||
15249 | } | ||
15250 | |||
15251 | /* | ||
15252 | * All kind of combinations of devices attached to one of four connectors | ||
15253 | * are acceptable except HVD device attached. For example, LVD device can | ||
15254 | * be attached to SE connector while SE device attached to LVD connector. | ||
15255 | * If LVD device attached to SE connector, it only runs up to Ultra speed. | ||
15256 | * | ||
15257 | * If an HVD device is attached to one of LVD connectors, return an error. | ||
15258 | * However, there is no way to detect HVD device attached to SE connectors. | ||
15259 | */ | ||
15260 | if (scsi_cfg1 & HVD) { | ||
15261 | asc_dvc->err_code |= ASC_IERR_HVD_DEVICE; | ||
15262 | return ADV_ERROR; | ||
15263 | } | ||
15264 | |||
15265 | /* | ||
15266 | * If either SE or LVD automatic termination control is enabled, then | ||
15267 | * set the termination value based on a table listed in a_condor.h. | ||
15268 | * | ||
15269 | * If manual termination was specified with an EEPROM setting then | ||
15270 | * 'termination' was set-up in AdvInitFrom38C0800EEPROM() and is ready to | ||
15271 | * be 'ored' into SCSI_CFG1. | ||
15272 | */ | ||
15273 | if ((asc_dvc->cfg->termination & TERM_SE) == 0) { | ||
15274 | /* SE automatic termination control is enabled. */ | ||
15275 | switch (scsi_cfg1 & C_DET_SE) { | ||
15276 | /* TERM_SE_HI: on, TERM_SE_LO: on */ | ||
15277 | case 0x1: | ||
15278 | case 0x2: | ||
15279 | case 0x3: | ||
15280 | asc_dvc->cfg->termination |= TERM_SE; | ||
15281 | break; | ||
15282 | |||
15283 | /* TERM_SE_HI: on, TERM_SE_LO: off */ | ||
15284 | case 0x0: | ||
15285 | asc_dvc->cfg->termination |= TERM_SE_HI; | ||
15286 | break; | ||
15287 | } | ||
15288 | } | ||
15289 | |||
15290 | if ((asc_dvc->cfg->termination & TERM_LVD) == 0) { | ||
15291 | /* LVD automatic termination control is enabled. */ | ||
15292 | switch (scsi_cfg1 & C_DET_LVD) { | ||
15293 | /* TERM_LVD_HI: on, TERM_LVD_LO: on */ | ||
15294 | case 0x4: | ||
15295 | case 0x8: | ||
15296 | case 0xC: | ||
15297 | asc_dvc->cfg->termination |= TERM_LVD; | ||
15298 | break; | ||
15299 | |||
15300 | /* TERM_LVD_HI: off, TERM_LVD_LO: off */ | ||
15301 | case 0x0: | ||
15302 | break; | ||
15303 | } | ||
15304 | } | ||
15305 | |||
15306 | /* | ||
15307 | * Clear any set TERM_SE and TERM_LVD bits. | ||
15308 | */ | ||
15309 | scsi_cfg1 &= (~TERM_SE & ~TERM_LVD); | ||
15310 | |||
15311 | /* | ||
15312 | * Invert the TERM_SE and TERM_LVD bits and then set 'scsi_cfg1'. | ||
15313 | */ | ||
15314 | scsi_cfg1 |= (~asc_dvc->cfg->termination & 0xF0); | ||
15315 | |||
15316 | /* | ||
15317 | * Clear BIG_ENDIAN, DIS_TERM_DRV, Terminator Polarity and HVD/LVD/SE bits | ||
15318 | * and set possibly modified termination control bits in the Microcode | ||
15319 | * SCSI_CFG1 Register Value. | ||
15320 | */ | ||
15321 | scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL & ~HVD_LVD_SE); | ||
15322 | |||
15323 | /* | ||
15324 | * Set SCSI_CFG1 Microcode Default Value | ||
15325 | * | ||
15326 | * Set possibly modified termination control and reset DIS_TERM_DRV | ||
15327 | * bits in the Microcode SCSI_CFG1 Register Value. | ||
15328 | * | ||
15329 | * The microcode will set the SCSI_CFG1 register using this value | ||
15330 | * after it is started below. | ||
15331 | */ | ||
15332 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1); | ||
15333 | |||
15334 | /* | ||
15335 | * Set MEM_CFG Microcode Default Value | ||
15336 | * | ||
15337 | * The microcode will set the MEM_CFG register using this value | ||
15338 | * after it is started below. | ||
15339 | * | ||
15340 | * MEM_CFG may be accessed as a word or byte, but only bits 0-7 | ||
15341 | * are defined. | ||
15342 | * | ||
15343 | * ASC-38C0800 has 16KB internal memory. | ||
15344 | */ | ||
15345 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, | ||
15346 | BIOS_EN | RAM_SZ_16KB); | ||
15347 | |||
15348 | /* | ||
15349 | * Set SEL_MASK Microcode Default Value | ||
15350 | * | ||
15351 | * The microcode will set the SEL_MASK register using this value | ||
15352 | * after it is started below. | ||
15353 | */ | ||
15354 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, | ||
15355 | ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); | ||
15356 | |||
15357 | /* | ||
15358 | * Build the carrier freelist. | ||
15359 | * | ||
15360 | * Driver must have already allocated memory and set 'carrier_buf'. | ||
15361 | */ | ||
15362 | ASC_ASSERT(asc_dvc->carrier_buf != NULL); | ||
15363 | |||
15364 | carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf); | ||
15365 | asc_dvc->carr_freelist = NULL; | ||
15366 | if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) { | ||
15367 | buf_size = ADV_CARRIER_BUFSIZE; | ||
15368 | } else { | ||
15369 | buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T); | ||
15370 | } | ||
15371 | |||
15372 | do { | ||
15373 | /* | ||
15374 | * Get physical address for the carrier 'carrp'. | ||
15375 | */ | ||
15376 | contig_len = sizeof(ADV_CARR_T); | ||
15377 | carr_paddr = | ||
15378 | cpu_to_le32(DvcGetPhyAddr | ||
15379 | (asc_dvc, NULL, (uchar *)carrp, | ||
15380 | (ADV_SDCNT *)&contig_len, | ||
15381 | ADV_IS_CARRIER_FLAG)); | ||
15382 | |||
15383 | buf_size -= sizeof(ADV_CARR_T); | ||
15384 | |||
15385 | /* | ||
15386 | * If the current carrier is not physically contiguous, then | ||
15387 | * maybe there was a page crossing. Try the next carrier aligned | ||
15388 | * start address. | ||
15389 | */ | ||
15390 | if (contig_len < sizeof(ADV_CARR_T)) { | ||
15391 | carrp++; | ||
15392 | continue; | ||
15393 | } | 12423 | } |
15394 | 12424 | chksum += *wbuf; /* Checksum is calculated from word values. */ | |
15395 | carrp->carr_pa = carr_paddr; | 12425 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); |
15396 | carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp)); | 12426 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, |
15397 | 12427 | ASC_EEP_CMD_WRITE | addr); | |
15398 | /* | 12428 | AdvWaitEEPCmd(iop_base); |
15399 | * Insert the carrier at the beginning of the freelist. | 12429 | mdelay(ADV_EEP_DELAY_MS); |
15400 | */ | ||
15401 | carrp->next_vpa = | ||
15402 | cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); | ||
15403 | asc_dvc->carr_freelist = carrp; | ||
15404 | |||
15405 | carrp++; | ||
15406 | } | ||
15407 | while (buf_size > 0); | ||
15408 | |||
15409 | /* | ||
15410 | * Set-up the Host->RISC Initiator Command Queue (ICQ). | ||
15411 | */ | ||
15412 | |||
15413 | if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) { | ||
15414 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; | ||
15415 | return ADV_ERROR; | ||
15416 | } | ||
15417 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
15418 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa)); | ||
15419 | |||
15420 | /* | ||
15421 | * The first command issued will be placed in the stopper carrier. | ||
15422 | */ | ||
15423 | asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
15424 | |||
15425 | /* | ||
15426 | * Set RISC ICQ physical address start value. | ||
15427 | * carr_pa is LE, must be native before write | ||
15428 | */ | ||
15429 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa); | ||
15430 | |||
15431 | /* | ||
15432 | * Set-up the RISC->Host Initiator Response Queue (IRQ). | ||
15433 | */ | ||
15434 | if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) { | ||
15435 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; | ||
15436 | return ADV_ERROR; | ||
15437 | } | 12430 | } |
15438 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
15439 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa)); | ||
15440 | 12431 | ||
15441 | /* | 12432 | /* |
15442 | * The first command completed by the RISC will be placed in | 12433 | * Write EEPROM checksum at word 21. |
15443 | * the stopper. | ||
15444 | * | ||
15445 | * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is | ||
15446 | * completed the RISC will set the ASC_RQ_STOPPER bit. | ||
15447 | */ | 12434 | */ |
15448 | asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | 12435 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum); |
12436 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); | ||
12437 | AdvWaitEEPCmd(iop_base); | ||
12438 | wbuf++; | ||
12439 | charfields++; | ||
15449 | 12440 | ||
15450 | /* | 12441 | /* |
15451 | * Set RISC IRQ physical address start value. | 12442 | * Write EEPROM OEM name at words 22 to 29. |
15452 | * | ||
15453 | * carr_pa is LE, must be native before write * | ||
15454 | */ | 12443 | */ |
15455 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa); | 12444 | for (addr = ADV_EEP_DVC_CTL_BEGIN; |
15456 | asc_dvc->carr_pending_cnt = 0; | 12445 | addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) { |
15457 | 12446 | ushort word; | |
15458 | AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES, | ||
15459 | (ADV_INTR_ENABLE_HOST_INTR | | ||
15460 | ADV_INTR_ENABLE_GLOBAL_INTR)); | ||
15461 | |||
15462 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word); | ||
15463 | AdvWriteWordRegister(iop_base, IOPW_PC, word); | ||
15464 | |||
15465 | /* finally, finally, gentlemen, start your engine */ | ||
15466 | AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN); | ||
15467 | 12447 | ||
15468 | /* | 12448 | if (*charfields++) { |
15469 | * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus | 12449 | word = cpu_to_le16(*wbuf); |
15470 | * Resets should be performed. The RISC has to be running | ||
15471 | * to issue a SCSI Bus Reset. | ||
15472 | */ | ||
15473 | if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) { | ||
15474 | /* | ||
15475 | * If the BIOS Signature is present in memory, restore the | ||
15476 | * BIOS Handshake Configuration Table and do not perform | ||
15477 | * a SCSI Bus Reset. | ||
15478 | */ | ||
15479 | if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == | ||
15480 | 0x55AA) { | ||
15481 | /* | ||
15482 | * Restore per TID negotiated values. | ||
15483 | */ | ||
15484 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
15485 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
15486 | AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, | ||
15487 | tagqng_able); | ||
15488 | for (tid = 0; tid <= ADV_MAX_TID; tid++) { | ||
15489 | AdvWriteByteLram(iop_base, | ||
15490 | ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
15491 | max_cmd[tid]); | ||
15492 | } | ||
15493 | } else { | 12450 | } else { |
15494 | if (AdvResetSB(asc_dvc) != ADV_TRUE) { | 12451 | word = *wbuf; |
15495 | warn_code = ASC_WARN_BUSRESET_ERROR; | ||
15496 | } | ||
15497 | } | 12452 | } |
12453 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); | ||
12454 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, | ||
12455 | ASC_EEP_CMD_WRITE | addr); | ||
12456 | AdvWaitEEPCmd(iop_base); | ||
15498 | } | 12457 | } |
15499 | 12458 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE); | |
15500 | return warn_code; | 12459 | AdvWaitEEPCmd(iop_base); |
15501 | } | 12460 | } |
15502 | 12461 | ||
15503 | /* | 12462 | /* |
15504 | * Initialize the ASC-38C1600. | 12463 | * Read EEPROM configuration into the specified buffer. |
15505 | * | ||
15506 | * On failure set the ASC_DVC_VAR field 'err_code' and return ADV_ERROR. | ||
15507 | * | ||
15508 | * For a non-fatal error return a warning code. If there are no warnings | ||
15509 | * then 0 is returned. | ||
15510 | * | 12464 | * |
15511 | * Needed after initialization for error recovery. | 12465 | * Return a checksum based on the EEPROM configuration read. |
15512 | */ | 12466 | */ |
15513 | static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) | 12467 | static ushort __devinit |
12468 | AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) | ||
15514 | { | 12469 | { |
15515 | AdvPortAddr iop_base; | 12470 | ushort wval, chksum; |
15516 | ushort warn_code; | 12471 | ushort *wbuf; |
15517 | ADV_DCNT sum; | 12472 | int eep_addr; |
15518 | int begin_addr; | 12473 | ushort *charfields; |
15519 | int end_addr; | ||
15520 | ushort code_sum; | ||
15521 | long word; | ||
15522 | int j; | ||
15523 | int adv_asc38C1600_expanded_size; | ||
15524 | ADV_CARR_T *carrp; | ||
15525 | ADV_DCNT contig_len; | ||
15526 | ADV_SDCNT buf_size; | ||
15527 | ADV_PADDR carr_paddr; | ||
15528 | int i; | ||
15529 | ushort scsi_cfg1; | ||
15530 | uchar byte; | ||
15531 | uchar tid; | ||
15532 | ushort bios_mem[ASC_MC_BIOSLEN / 2]; /* BIOS RISC Memory 0x40-0x8F. */ | ||
15533 | ushort wdtr_able, sdtr_able, ppr_able, tagqng_able; | ||
15534 | uchar max_cmd[ASC_MAX_TID + 1]; | ||
15535 | |||
15536 | /* If there is already an error, don't continue. */ | ||
15537 | if (asc_dvc->err_code != 0) { | ||
15538 | return ADV_ERROR; | ||
15539 | } | ||
15540 | |||
15541 | /* | ||
15542 | * The caller must set 'chip_type' to ADV_CHIP_ASC38C1600. | ||
15543 | */ | ||
15544 | if (asc_dvc->chip_type != ADV_CHIP_ASC38C1600) { | ||
15545 | asc_dvc->err_code = ASC_IERR_BAD_CHIPTYPE; | ||
15546 | return ADV_ERROR; | ||
15547 | } | ||
15548 | |||
15549 | warn_code = 0; | ||
15550 | iop_base = asc_dvc->iop_base; | ||
15551 | |||
15552 | /* | ||
15553 | * Save the RISC memory BIOS region before writing the microcode. | ||
15554 | * The BIOS may already be loaded and using its RISC LRAM region | ||
15555 | * so its region must be saved and restored. | ||
15556 | * | ||
15557 | * Note: This code makes the assumption, which is currently true, | ||
15558 | * that a chip reset does not clear RISC LRAM. | ||
15559 | */ | ||
15560 | for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { | ||
15561 | AdvReadWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), | ||
15562 | bios_mem[i]); | ||
15563 | } | ||
15564 | |||
15565 | /* | ||
15566 | * Save current per TID negotiated values. | ||
15567 | */ | ||
15568 | AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
15569 | AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
15570 | AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); | ||
15571 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | ||
15572 | for (tid = 0; tid <= ASC_MAX_TID; tid++) { | ||
15573 | AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
15574 | max_cmd[tid]); | ||
15575 | } | ||
15576 | |||
15577 | /* | ||
15578 | * RAM BIST (Built-In Self Test) | ||
15579 | * | ||
15580 | * Address : I/O base + offset 0x38h register (byte). | ||
15581 | * Function: Bit 7-6(RW) : RAM mode | ||
15582 | * Normal Mode : 0x00 | ||
15583 | * Pre-test Mode : 0x40 | ||
15584 | * RAM Test Mode : 0x80 | ||
15585 | * Bit 5 : unused | ||
15586 | * Bit 4(RO) : Done bit | ||
15587 | * Bit 3-0(RO) : Status | ||
15588 | * Host Error : 0x08 | ||
15589 | * Int_RAM Error : 0x04 | ||
15590 | * RISC Error : 0x02 | ||
15591 | * SCSI Error : 0x01 | ||
15592 | * No Error : 0x00 | ||
15593 | * | ||
15594 | * Note: RAM BIST code should be put right here, before loading the | ||
15595 | * microcode and after saving the RISC memory BIOS region. | ||
15596 | */ | ||
15597 | 12474 | ||
15598 | /* | 12475 | charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar; |
15599 | * LRAM Pre-test | 12476 | wbuf = (ushort *)cfg_buf; |
15600 | * | 12477 | chksum = 0; |
15601 | * Write PRE_TEST_MODE (0x40) to register and wait for 10 milliseconds. | ||
15602 | * If Done bit not set or low nibble not PRE_TEST_VALUE (0x05), return | ||
15603 | * an error. Reset to NORMAL_MODE (0x00) and do again. If cannot reset | ||
15604 | * to NORMAL_MODE, return an error too. | ||
15605 | */ | ||
15606 | for (i = 0; i < 2; i++) { | ||
15607 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, PRE_TEST_MODE); | ||
15608 | DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ | ||
15609 | byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); | ||
15610 | if ((byte & RAM_TEST_DONE) == 0 | ||
15611 | || (byte & 0x0F) != PRE_TEST_VALUE) { | ||
15612 | asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; | ||
15613 | return ADV_ERROR; | ||
15614 | } | ||
15615 | 12478 | ||
15616 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); | 12479 | for (eep_addr = ADV_EEP_DVC_CFG_BEGIN; |
15617 | DvcSleepMilliSecond(10); /* Wait for 10ms before reading back. */ | 12480 | eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) { |
15618 | if (AdvReadByteRegister(iop_base, IOPB_RAM_BIST) | 12481 | wval = AdvReadEEPWord(iop_base, eep_addr); |
15619 | != NORMAL_VALUE) { | 12482 | chksum += wval; /* Checksum is calculated from word values. */ |
15620 | asc_dvc->err_code |= ASC_IERR_BIST_PRE_TEST; | 12483 | if (*charfields++) { |
15621 | return ADV_ERROR; | 12484 | *wbuf = le16_to_cpu(wval); |
12485 | } else { | ||
12486 | *wbuf = wval; | ||
15622 | } | 12487 | } |
15623 | } | 12488 | } |
12489 | /* Read checksum word. */ | ||
12490 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); | ||
12491 | wbuf++; | ||
12492 | charfields++; | ||
15624 | 12493 | ||
15625 | /* | 12494 | /* Read rest of EEPROM not covered by the checksum. */ |
15626 | * LRAM Test - It takes about 1.5 ms to run through the test. | 12495 | for (eep_addr = ADV_EEP_DVC_CTL_BEGIN; |
15627 | * | 12496 | eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) { |
15628 | * Write RAM_TEST_MODE (0x80) to register and wait for 10 milliseconds. | 12497 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); |
15629 | * If Done bit not set or Status not 0, save register byte, set the | 12498 | if (*charfields++) { |
15630 | * err_code, and return an error. | 12499 | *wbuf = le16_to_cpu(*wbuf); |
15631 | */ | 12500 | } |
15632 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, RAM_TEST_MODE); | ||
15633 | DvcSleepMilliSecond(10); /* Wait for 10ms before checking status. */ | ||
15634 | |||
15635 | byte = AdvReadByteRegister(iop_base, IOPB_RAM_BIST); | ||
15636 | if ((byte & RAM_TEST_DONE) == 0 || (byte & RAM_TEST_STATUS) != 0) { | ||
15637 | /* Get here if Done bit not set or Status not 0. */ | ||
15638 | asc_dvc->bist_err_code = byte; /* for BIOS display message */ | ||
15639 | asc_dvc->err_code |= ASC_IERR_BIST_RAM_TEST; | ||
15640 | return ADV_ERROR; | ||
15641 | } | 12501 | } |
12502 | return chksum; | ||
12503 | } | ||
15642 | 12504 | ||
15643 | /* We need to reset back to normal mode after LRAM test passes. */ | 12505 | /* |
15644 | AdvWriteByteRegister(iop_base, IOPB_RAM_BIST, NORMAL_MODE); | 12506 | * Read EEPROM configuration into the specified buffer. |
12507 | * | ||
12508 | * Return a checksum based on the EEPROM configuration read. | ||
12509 | */ | ||
12510 | static ushort __devinit | ||
12511 | AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf) | ||
12512 | { | ||
12513 | ushort wval, chksum; | ||
12514 | ushort *wbuf; | ||
12515 | int eep_addr; | ||
12516 | ushort *charfields; | ||
15645 | 12517 | ||
15646 | /* | 12518 | charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar; |
15647 | * Load the Microcode | 12519 | wbuf = (ushort *)cfg_buf; |
15648 | * | 12520 | chksum = 0; |
15649 | * Write the microcode image to RISC memory starting at address 0. | ||
15650 | * | ||
15651 | */ | ||
15652 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); | ||
15653 | 12521 | ||
15654 | /* | 12522 | for (eep_addr = ADV_EEP_DVC_CFG_BEGIN; |
15655 | * Assume the following compressed format of the microcode buffer: | 12523 | eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) { |
15656 | * | 12524 | wval = AdvReadEEPWord(iop_base, eep_addr); |
15657 | * 254 word (508 byte) table indexed by byte code followed | 12525 | chksum += wval; /* Checksum is calculated from word values. */ |
15658 | * by the following byte codes: | 12526 | if (*charfields++) { |
15659 | * | 12527 | *wbuf = le16_to_cpu(wval); |
15660 | * 1-Byte Code: | ||
15661 | * 00: Emit word 0 in table. | ||
15662 | * 01: Emit word 1 in table. | ||
15663 | * . | ||
15664 | * FD: Emit word 253 in table. | ||
15665 | * | ||
15666 | * Multi-Byte Code: | ||
15667 | * FE WW WW: (3 byte code) Word to emit is the next word WW WW. | ||
15668 | * FF BB WW WW: (4 byte code) Emit BB count times next word WW WW. | ||
15669 | */ | ||
15670 | word = 0; | ||
15671 | for (i = 253 * 2; i < _adv_asc38C1600_size; i++) { | ||
15672 | if (_adv_asc38C1600_buf[i] == 0xff) { | ||
15673 | for (j = 0; j < _adv_asc38C1600_buf[i + 1]; j++) { | ||
15674 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | ||
15675 | _adv_asc38C1600_buf | ||
15676 | [i + | ||
15677 | 3] << 8) | | ||
15678 | _adv_asc38C1600_buf | ||
15679 | [i + 2])); | ||
15680 | word++; | ||
15681 | } | ||
15682 | i += 3; | ||
15683 | } else if (_adv_asc38C1600_buf[i] == 0xfe) { | ||
15684 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | ||
15685 | _adv_asc38C1600_buf | ||
15686 | [i + | ||
15687 | 2] << 8) | | ||
15688 | _adv_asc38C1600_buf[i | ||
15689 | + | ||
15690 | 1])); | ||
15691 | i += 2; | ||
15692 | word++; | ||
15693 | } else { | 12528 | } else { |
15694 | AdvWriteWordAutoIncLram(iop_base, (((ushort) | 12529 | *wbuf = wval; |
15695 | _adv_asc38C1600_buf[(_adv_asc38C1600_buf[i] * 2) + 1] << 8) | _adv_asc38C1600_buf[_adv_asc38C1600_buf[i] * 2])); | ||
15696 | word++; | ||
15697 | } | 12530 | } |
15698 | } | 12531 | } |
12532 | /* Read checksum word. */ | ||
12533 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); | ||
12534 | wbuf++; | ||
12535 | charfields++; | ||
15699 | 12536 | ||
15700 | /* | 12537 | /* Read rest of EEPROM not covered by the checksum. */ |
15701 | * Set 'word' for later use to clear the rest of memory and save | 12538 | for (eep_addr = ADV_EEP_DVC_CTL_BEGIN; |
15702 | * the expanded mcode size. | 12539 | eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) { |
15703 | */ | 12540 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); |
15704 | word *= 2; | 12541 | if (*charfields++) { |
15705 | adv_asc38C1600_expanded_size = word; | 12542 | *wbuf = le16_to_cpu(*wbuf); |
15706 | |||
15707 | /* | ||
15708 | * Clear the rest of ASC-38C1600 Internal RAM (32KB). | ||
15709 | */ | ||
15710 | for (; word < ADV_38C1600_MEMSIZE; word += 2) { | ||
15711 | AdvWriteWordAutoIncLram(iop_base, 0); | ||
15712 | } | ||
15713 | |||
15714 | /* | ||
15715 | * Verify the microcode checksum. | ||
15716 | */ | ||
15717 | sum = 0; | ||
15718 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, 0); | ||
15719 | |||
15720 | for (word = 0; word < adv_asc38C1600_expanded_size; word += 2) { | ||
15721 | sum += AdvReadWordAutoIncLram(iop_base); | ||
15722 | } | ||
15723 | |||
15724 | if (sum != _adv_asc38C1600_chksum) { | ||
15725 | asc_dvc->err_code |= ASC_IERR_MCODE_CHKSUM; | ||
15726 | return ADV_ERROR; | ||
15727 | } | ||
15728 | |||
15729 | /* | ||
15730 | * Restore the RISC memory BIOS region. | ||
15731 | */ | ||
15732 | for (i = 0; i < ASC_MC_BIOSLEN / 2; i++) { | ||
15733 | AdvWriteWordLram(iop_base, ASC_MC_BIOSMEM + (2 * i), | ||
15734 | bios_mem[i]); | ||
15735 | } | ||
15736 | |||
15737 | /* | ||
15738 | * Calculate and write the microcode code checksum to the microcode | ||
15739 | * code checksum location ASC_MC_CODE_CHK_SUM (0x2C). | ||
15740 | */ | ||
15741 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, begin_addr); | ||
15742 | AdvReadWordLram(iop_base, ASC_MC_CODE_END_ADDR, end_addr); | ||
15743 | code_sum = 0; | ||
15744 | AdvWriteWordRegister(iop_base, IOPW_RAM_ADDR, begin_addr); | ||
15745 | for (word = begin_addr; word < end_addr; word += 2) { | ||
15746 | code_sum += AdvReadWordAutoIncLram(iop_base); | ||
15747 | } | ||
15748 | AdvWriteWordLram(iop_base, ASC_MC_CODE_CHK_SUM, code_sum); | ||
15749 | |||
15750 | /* | ||
15751 | * Read microcode version and date. | ||
15752 | */ | ||
15753 | AdvReadWordLram(iop_base, ASC_MC_VERSION_DATE, | ||
15754 | asc_dvc->cfg->mcode_date); | ||
15755 | AdvReadWordLram(iop_base, ASC_MC_VERSION_NUM, | ||
15756 | asc_dvc->cfg->mcode_version); | ||
15757 | |||
15758 | /* | ||
15759 | * Set the chip type to indicate the ASC38C1600. | ||
15760 | */ | ||
15761 | AdvWriteWordLram(iop_base, ASC_MC_CHIP_TYPE, ADV_CHIP_ASC38C1600); | ||
15762 | |||
15763 | /* | ||
15764 | * Write 1 to bit 14 'DIS_TERM_DRV' in the SCSI_CFG1 register. | ||
15765 | * When DIS_TERM_DRV set to 1, C_DET[3:0] will reflect current | ||
15766 | * cable detection and then we are able to read C_DET[3:0]. | ||
15767 | * | ||
15768 | * Note: We will reset DIS_TERM_DRV to 0 in the 'Set SCSI_CFG1 | ||
15769 | * Microcode Default Value' section below. | ||
15770 | */ | ||
15771 | scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); | ||
15772 | AdvWriteWordRegister(iop_base, IOPW_SCSI_CFG1, | ||
15773 | scsi_cfg1 | DIS_TERM_DRV); | ||
15774 | |||
15775 | /* | ||
15776 | * If the PCI Configuration Command Register "Parity Error Response | ||
15777 | * Control" Bit was clear (0), then set the microcode variable | ||
15778 | * 'control_flag' CONTROL_FLAG_IGNORE_PERR flag to tell the microcode | ||
15779 | * to ignore DMA parity errors. | ||
15780 | */ | ||
15781 | if (asc_dvc->cfg->control_flag & CONTROL_FLAG_IGNORE_PERR) { | ||
15782 | AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
15783 | word |= CONTROL_FLAG_IGNORE_PERR; | ||
15784 | AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
15785 | } | ||
15786 | |||
15787 | /* | ||
15788 | * If the BIOS control flag AIPP (Asynchronous Information | ||
15789 | * Phase Protection) disable bit is not set, then set the firmware | ||
15790 | * 'control_flag' CONTROL_FLAG_ENABLE_AIPP bit to enable | ||
15791 | * AIPP checking and encoding. | ||
15792 | */ | ||
15793 | if ((asc_dvc->bios_ctrl & BIOS_CTRL_AIPP_DIS) == 0) { | ||
15794 | AdvReadWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
15795 | word |= CONTROL_FLAG_ENABLE_AIPP; | ||
15796 | AdvWriteWordLram(iop_base, ASC_MC_CONTROL_FLAG, word); | ||
15797 | } | ||
15798 | |||
15799 | /* | ||
15800 | * For ASC-38C1600 use DMA_CFG0 default values: FIFO_THRESH_80B [6:4], | ||
15801 | * and START_CTL_TH [3:2]. | ||
15802 | */ | ||
15803 | AdvWriteByteRegister(iop_base, IOPB_DMA_CFG0, | ||
15804 | FIFO_THRESH_80B | START_CTL_TH | READ_CMD_MRM); | ||
15805 | |||
15806 | /* | ||
15807 | * Microcode operating variables for WDTR, SDTR, and command tag | ||
15808 | * queuing will be set in AdvInquiryHandling() based on what a | ||
15809 | * device reports it is capable of in Inquiry byte 7. | ||
15810 | * | ||
15811 | * If SCSI Bus Resets have been disabled, then directly set | ||
15812 | * SDTR and WDTR from the EEPROM configuration. This will allow | ||
15813 | * the BIOS and warm boot to work without a SCSI bus hang on | ||
15814 | * the Inquiry caused by host and target mismatched DTR values. | ||
15815 | * Without the SCSI Bus Reset, before an Inquiry a device can't | ||
15816 | * be assumed to be in Asynchronous, Narrow mode. | ||
15817 | */ | ||
15818 | if ((asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) == 0) { | ||
15819 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, | ||
15820 | asc_dvc->wdtr_able); | ||
15821 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, | ||
15822 | asc_dvc->sdtr_able); | ||
15823 | } | ||
15824 | |||
15825 | /* | ||
15826 | * Set microcode operating variables for DISC and SDTR_SPEED1, | ||
15827 | * SDTR_SPEED2, SDTR_SPEED3, and SDTR_SPEED4 based on the EEPROM | ||
15828 | * configuration values. | ||
15829 | * | ||
15830 | * The SDTR per TID bitmask overrides the SDTR_SPEED1, SDTR_SPEED2, | ||
15831 | * SDTR_SPEED3, and SDTR_SPEED4 values so it is safe to set them | ||
15832 | * without determining here whether the device supports SDTR. | ||
15833 | */ | ||
15834 | AdvWriteWordLram(iop_base, ASC_MC_DISC_ENABLE, | ||
15835 | asc_dvc->cfg->disc_enable); | ||
15836 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED1, asc_dvc->sdtr_speed1); | ||
15837 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED2, asc_dvc->sdtr_speed2); | ||
15838 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED3, asc_dvc->sdtr_speed3); | ||
15839 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_SPEED4, asc_dvc->sdtr_speed4); | ||
15840 | |||
15841 | /* | ||
15842 | * Set SCSI_CFG0 Microcode Default Value. | ||
15843 | * | ||
15844 | * The microcode will set the SCSI_CFG0 register using this value | ||
15845 | * after it is started below. | ||
15846 | */ | ||
15847 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG0, | ||
15848 | PARITY_EN | QUEUE_128 | SEL_TMO_LONG | OUR_ID_EN | | ||
15849 | asc_dvc->chip_scsi_id); | ||
15850 | |||
15851 | /* | ||
15852 | * Calculate SCSI_CFG1 Microcode Default Value. | ||
15853 | * | ||
15854 | * The microcode will set the SCSI_CFG1 register using this value | ||
15855 | * after it is started below. | ||
15856 | * | ||
15857 | * Each ASC-38C1600 function has only two cable detect bits. | ||
15858 | * The bus mode override bits are in IOPB_SOFT_OVER_WR. | ||
15859 | */ | ||
15860 | scsi_cfg1 = AdvReadWordRegister(iop_base, IOPW_SCSI_CFG1); | ||
15861 | |||
15862 | /* | ||
15863 | * If the cable is reversed all of the SCSI_CTRL register signals | ||
15864 | * will be set. Check for and return an error if this condition is | ||
15865 | * found. | ||
15866 | */ | ||
15867 | if ((AdvReadWordRegister(iop_base, IOPW_SCSI_CTRL) & 0x3F07) == 0x3F07) { | ||
15868 | asc_dvc->err_code |= ASC_IERR_REVERSED_CABLE; | ||
15869 | return ADV_ERROR; | ||
15870 | } | ||
15871 | |||
15872 | /* | ||
15873 | * Each ASC-38C1600 function has two connectors. Only an HVD device | ||
15874 | * can not be connected to either connector. An LVD device or SE device | ||
15875 | * may be connected to either connecor. If an SE device is connected, | ||
15876 | * then at most Ultra speed (20 Mhz) can be used on both connectors. | ||
15877 | * | ||
15878 | * If an HVD device is attached, return an error. | ||
15879 | */ | ||
15880 | if (scsi_cfg1 & HVD) { | ||
15881 | asc_dvc->err_code |= ASC_IERR_HVD_DEVICE; | ||
15882 | return ADV_ERROR; | ||
15883 | } | ||
15884 | |||
15885 | /* | ||
15886 | * Each function in the ASC-38C1600 uses only the SE cable detect and | ||
15887 | * termination because there are two connectors for each function. Each | ||
15888 | * function may use either LVD or SE mode. Corresponding the SE automatic | ||
15889 | * termination control EEPROM bits are used for each function. Each | ||
15890 | * function has its own EEPROM. If SE automatic control is enabled for | ||
15891 | * the function, then set the termination value based on a table listed | ||
15892 | * in a_condor.h. | ||
15893 | * | ||
15894 | * If manual termination is specified in the EEPROM for the function, | ||
15895 | * then 'termination' was set-up in AscInitFrom38C1600EEPROM() and is | ||
15896 | * ready to be 'ored' into SCSI_CFG1. | ||
15897 | */ | ||
15898 | if ((asc_dvc->cfg->termination & TERM_SE) == 0) { | ||
15899 | /* SE automatic termination control is enabled. */ | ||
15900 | switch (scsi_cfg1 & C_DET_SE) { | ||
15901 | /* TERM_SE_HI: on, TERM_SE_LO: on */ | ||
15902 | case 0x1: | ||
15903 | case 0x2: | ||
15904 | case 0x3: | ||
15905 | asc_dvc->cfg->termination |= TERM_SE; | ||
15906 | break; | ||
15907 | |||
15908 | case 0x0: | ||
15909 | if (ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) == 0) { | ||
15910 | /* Function 0 - TERM_SE_HI: off, TERM_SE_LO: off */ | ||
15911 | } else { | ||
15912 | /* Function 1 - TERM_SE_HI: on, TERM_SE_LO: off */ | ||
15913 | asc_dvc->cfg->termination |= TERM_SE_HI; | ||
15914 | } | ||
15915 | break; | ||
15916 | } | 12543 | } |
15917 | } | 12544 | } |
12545 | return chksum; | ||
12546 | } | ||
15918 | 12547 | ||
15919 | /* | 12548 | /* |
15920 | * Clear any set TERM_SE bits. | 12549 | * Read EEPROM configuration into the specified buffer. |
15921 | */ | 12550 | * |
15922 | scsi_cfg1 &= ~TERM_SE; | 12551 | * Return a checksum based on the EEPROM configuration read. |
15923 | 12552 | */ | |
15924 | /* | 12553 | static ushort __devinit |
15925 | * Invert the TERM_SE bits and then set 'scsi_cfg1'. | 12554 | AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf) |
15926 | */ | 12555 | { |
15927 | scsi_cfg1 |= (~asc_dvc->cfg->termination & TERM_SE); | 12556 | ushort wval, chksum; |
15928 | 12557 | ushort *wbuf; | |
15929 | /* | 12558 | int eep_addr; |
15930 | * Clear Big Endian and Terminator Polarity bits and set possibly | 12559 | ushort *charfields; |
15931 | * modified termination control bits in the Microcode SCSI_CFG1 | ||
15932 | * Register Value. | ||
15933 | * | ||
15934 | * Big Endian bit is not used even on big endian machines. | ||
15935 | */ | ||
15936 | scsi_cfg1 &= (~BIG_ENDIAN & ~DIS_TERM_DRV & ~TERM_POL); | ||
15937 | |||
15938 | /* | ||
15939 | * Set SCSI_CFG1 Microcode Default Value | ||
15940 | * | ||
15941 | * Set possibly modified termination control bits in the Microcode | ||
15942 | * SCSI_CFG1 Register Value. | ||
15943 | * | ||
15944 | * The microcode will set the SCSI_CFG1 register using this value | ||
15945 | * after it is started below. | ||
15946 | */ | ||
15947 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SCSI_CFG1, scsi_cfg1); | ||
15948 | |||
15949 | /* | ||
15950 | * Set MEM_CFG Microcode Default Value | ||
15951 | * | ||
15952 | * The microcode will set the MEM_CFG register using this value | ||
15953 | * after it is started below. | ||
15954 | * | ||
15955 | * MEM_CFG may be accessed as a word or byte, but only bits 0-7 | ||
15956 | * are defined. | ||
15957 | * | ||
15958 | * ASC-38C1600 has 32KB internal memory. | ||
15959 | * | ||
15960 | * XXX - Since ASC38C1600 Rev.3 has a Local RAM failure issue, we come | ||
15961 | * out a special 16K Adv Library and Microcode version. After the issue | ||
15962 | * resolved, we should turn back to the 32K support. Both a_condor.h and | ||
15963 | * mcode.sas files also need to be updated. | ||
15964 | * | ||
15965 | * AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, | ||
15966 | * BIOS_EN | RAM_SZ_32KB); | ||
15967 | */ | ||
15968 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_MEM_CFG, | ||
15969 | BIOS_EN | RAM_SZ_16KB); | ||
15970 | |||
15971 | /* | ||
15972 | * Set SEL_MASK Microcode Default Value | ||
15973 | * | ||
15974 | * The microcode will set the SEL_MASK register using this value | ||
15975 | * after it is started below. | ||
15976 | */ | ||
15977 | AdvWriteWordLram(iop_base, ASC_MC_DEFAULT_SEL_MASK, | ||
15978 | ADV_TID_TO_TIDMASK(asc_dvc->chip_scsi_id)); | ||
15979 | |||
15980 | /* | ||
15981 | * Build the carrier freelist. | ||
15982 | * | ||
15983 | * Driver must have already allocated memory and set 'carrier_buf'. | ||
15984 | */ | ||
15985 | |||
15986 | ASC_ASSERT(asc_dvc->carrier_buf != NULL); | ||
15987 | |||
15988 | carrp = (ADV_CARR_T *) ADV_16BALIGN(asc_dvc->carrier_buf); | ||
15989 | asc_dvc->carr_freelist = NULL; | ||
15990 | if (carrp == (ADV_CARR_T *) asc_dvc->carrier_buf) { | ||
15991 | buf_size = ADV_CARRIER_BUFSIZE; | ||
15992 | } else { | ||
15993 | buf_size = ADV_CARRIER_BUFSIZE - sizeof(ADV_CARR_T); | ||
15994 | } | ||
15995 | |||
15996 | do { | ||
15997 | /* | ||
15998 | * Get physical address for the carrier 'carrp'. | ||
15999 | */ | ||
16000 | contig_len = sizeof(ADV_CARR_T); | ||
16001 | carr_paddr = | ||
16002 | cpu_to_le32(DvcGetPhyAddr | ||
16003 | (asc_dvc, NULL, (uchar *)carrp, | ||
16004 | (ADV_SDCNT *)&contig_len, | ||
16005 | ADV_IS_CARRIER_FLAG)); | ||
16006 | 12560 | ||
16007 | buf_size -= sizeof(ADV_CARR_T); | 12561 | charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar; |
12562 | wbuf = (ushort *)cfg_buf; | ||
12563 | chksum = 0; | ||
16008 | 12564 | ||
16009 | /* | 12565 | for (eep_addr = ADV_EEP_DVC_CFG_BEGIN; |
16010 | * If the current carrier is not physically contiguous, then | 12566 | eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) { |
16011 | * maybe there was a page crossing. Try the next carrier aligned | 12567 | wval = AdvReadEEPWord(iop_base, eep_addr); |
16012 | * start address. | 12568 | chksum += wval; /* Checksum is calculated from word values. */ |
16013 | */ | 12569 | if (*charfields++) { |
16014 | if (contig_len < sizeof(ADV_CARR_T)) { | 12570 | *wbuf = le16_to_cpu(wval); |
16015 | carrp++; | 12571 | } else { |
16016 | continue; | 12572 | *wbuf = wval; |
16017 | } | 12573 | } |
16018 | |||
16019 | carrp->carr_pa = carr_paddr; | ||
16020 | carrp->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(carrp)); | ||
16021 | |||
16022 | /* | ||
16023 | * Insert the carrier at the beginning of the freelist. | ||
16024 | */ | ||
16025 | carrp->next_vpa = | ||
16026 | cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); | ||
16027 | asc_dvc->carr_freelist = carrp; | ||
16028 | |||
16029 | carrp++; | ||
16030 | } | ||
16031 | while (buf_size > 0); | ||
16032 | |||
16033 | /* | ||
16034 | * Set-up the Host->RISC Initiator Command Queue (ICQ). | ||
16035 | */ | ||
16036 | if ((asc_dvc->icq_sp = asc_dvc->carr_freelist) == NULL) { | ||
16037 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; | ||
16038 | return ADV_ERROR; | ||
16039 | } | 12574 | } |
16040 | asc_dvc->carr_freelist = (ADV_CARR_T *) | 12575 | /* Read checksum word. */ |
16041 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->icq_sp->next_vpa)); | 12576 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); |
16042 | 12577 | wbuf++; | |
16043 | /* | 12578 | charfields++; |
16044 | * The first command issued will be placed in the stopper carrier. | ||
16045 | */ | ||
16046 | asc_dvc->icq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
16047 | |||
16048 | /* | ||
16049 | * Set RISC ICQ physical address start value. Initialize the | ||
16050 | * COMMA register to the same value otherwise the RISC will | ||
16051 | * prematurely detect a command is available. | ||
16052 | */ | ||
16053 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_ICQ, asc_dvc->icq_sp->carr_pa); | ||
16054 | AdvWriteDWordRegister(iop_base, IOPDW_COMMA, | ||
16055 | le32_to_cpu(asc_dvc->icq_sp->carr_pa)); | ||
16056 | |||
16057 | /* | ||
16058 | * Set-up the RISC->Host Initiator Response Queue (IRQ). | ||
16059 | */ | ||
16060 | if ((asc_dvc->irq_sp = asc_dvc->carr_freelist) == NULL) { | ||
16061 | asc_dvc->err_code |= ASC_IERR_NO_CARRIER; | ||
16062 | return ADV_ERROR; | ||
16063 | } | ||
16064 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
16065 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->next_vpa)); | ||
16066 | |||
16067 | /* | ||
16068 | * The first command completed by the RISC will be placed in | ||
16069 | * the stopper. | ||
16070 | * | ||
16071 | * Note: Set 'next_vpa' to ASC_CQ_STOPPER. When the request is | ||
16072 | * completed the RISC will set the ASC_RQ_STOPPER bit. | ||
16073 | */ | ||
16074 | asc_dvc->irq_sp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
16075 | |||
16076 | /* | ||
16077 | * Set RISC IRQ physical address start value. | ||
16078 | */ | ||
16079 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IRQ, asc_dvc->irq_sp->carr_pa); | ||
16080 | asc_dvc->carr_pending_cnt = 0; | ||
16081 | |||
16082 | AdvWriteByteRegister(iop_base, IOPB_INTR_ENABLES, | ||
16083 | (ADV_INTR_ENABLE_HOST_INTR | | ||
16084 | ADV_INTR_ENABLE_GLOBAL_INTR)); | ||
16085 | AdvReadWordLram(iop_base, ASC_MC_CODE_BEGIN_ADDR, word); | ||
16086 | AdvWriteWordRegister(iop_base, IOPW_PC, word); | ||
16087 | |||
16088 | /* finally, finally, gentlemen, start your engine */ | ||
16089 | AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_RUN); | ||
16090 | 12579 | ||
16091 | /* | 12580 | /* Read rest of EEPROM not covered by the checksum. */ |
16092 | * Reset the SCSI Bus if the EEPROM indicates that SCSI Bus | 12581 | for (eep_addr = ADV_EEP_DVC_CTL_BEGIN; |
16093 | * Resets should be performed. The RISC has to be running | 12582 | eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) { |
16094 | * to issue a SCSI Bus Reset. | 12583 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); |
16095 | */ | 12584 | if (*charfields++) { |
16096 | if (asc_dvc->bios_ctrl & BIOS_CTRL_RESET_SCSI_BUS) { | 12585 | *wbuf = le16_to_cpu(*wbuf); |
16097 | /* | ||
16098 | * If the BIOS Signature is present in memory, restore the | ||
16099 | * per TID microcode operating variables. | ||
16100 | */ | ||
16101 | if (bios_mem[(ASC_MC_BIOS_SIGNATURE - ASC_MC_BIOSMEM) / 2] == | ||
16102 | 0x55AA) { | ||
16103 | /* | ||
16104 | * Restore per TID negotiated values. | ||
16105 | */ | ||
16106 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
16107 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
16108 | AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); | ||
16109 | AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, | ||
16110 | tagqng_able); | ||
16111 | for (tid = 0; tid <= ASC_MAX_TID; tid++) { | ||
16112 | AdvWriteByteLram(iop_base, | ||
16113 | ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
16114 | max_cmd[tid]); | ||
16115 | } | ||
16116 | } else { | ||
16117 | if (AdvResetSB(asc_dvc) != ADV_TRUE) { | ||
16118 | warn_code = ASC_WARN_BUSRESET_ERROR; | ||
16119 | } | ||
16120 | } | 12586 | } |
16121 | } | 12587 | } |
16122 | 12588 | return chksum; | |
16123 | return warn_code; | ||
16124 | } | 12589 | } |
16125 | 12590 | ||
16126 | /* | 12591 | /* |
@@ -16135,12 +12600,11 @@ static int AdvInitAsc38C1600Driver(ADV_DVC_VAR *asc_dvc) | |||
16135 | * | 12600 | * |
16136 | * Note: Chip is stopped on entry. | 12601 | * Note: Chip is stopped on entry. |
16137 | */ | 12602 | */ |
16138 | static int __init AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc) | 12603 | static int __devinit AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc) |
16139 | { | 12604 | { |
16140 | AdvPortAddr iop_base; | 12605 | AdvPortAddr iop_base; |
16141 | ushort warn_code; | 12606 | ushort warn_code; |
16142 | ADVEEP_3550_CONFIG eep_config; | 12607 | ADVEEP_3550_CONFIG eep_config; |
16143 | int i; | ||
16144 | 12608 | ||
16145 | iop_base = asc_dvc->iop_base; | 12609 | iop_base = asc_dvc->iop_base; |
16146 | 12610 | ||
@@ -16157,15 +12621,12 @@ static int __init AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc) | |||
16157 | /* | 12621 | /* |
16158 | * Set EEPROM default values. | 12622 | * Set EEPROM default values. |
16159 | */ | 12623 | */ |
16160 | for (i = 0; i < sizeof(ADVEEP_3550_CONFIG); i++) { | 12624 | memcpy(&eep_config, &Default_3550_EEPROM_Config, |
16161 | *((uchar *)&eep_config + i) = | 12625 | sizeof(ADVEEP_3550_CONFIG)); |
16162 | *((uchar *)&Default_3550_EEPROM_Config + i); | ||
16163 | } | ||
16164 | 12626 | ||
16165 | /* | 12627 | /* |
16166 | * Assume the 6 byte board serial number that was read | 12628 | * Assume the 6 byte board serial number that was read from |
16167 | * from EEPROM is correct even if the EEPROM checksum | 12629 | * EEPROM is correct even if the EEPROM checksum failed. |
16168 | * failed. | ||
16169 | */ | 12630 | */ |
16170 | eep_config.serial_number_word3 = | 12631 | eep_config.serial_number_word3 = |
16171 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); | 12632 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); |
@@ -16289,12 +12750,11 @@ static int __init AdvInitFrom3550EEP(ADV_DVC_VAR *asc_dvc) | |||
16289 | * | 12750 | * |
16290 | * Note: Chip is stopped on entry. | 12751 | * Note: Chip is stopped on entry. |
16291 | */ | 12752 | */ |
16292 | static int __init AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc) | 12753 | static int __devinit AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc) |
16293 | { | 12754 | { |
16294 | AdvPortAddr iop_base; | 12755 | AdvPortAddr iop_base; |
16295 | ushort warn_code; | 12756 | ushort warn_code; |
16296 | ADVEEP_38C0800_CONFIG eep_config; | 12757 | ADVEEP_38C0800_CONFIG eep_config; |
16297 | int i; | ||
16298 | uchar tid, termination; | 12758 | uchar tid, termination; |
16299 | ushort sdtr_speed = 0; | 12759 | ushort sdtr_speed = 0; |
16300 | 12760 | ||
@@ -16314,15 +12774,12 @@ static int __init AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc) | |||
16314 | /* | 12774 | /* |
16315 | * Set EEPROM default values. | 12775 | * Set EEPROM default values. |
16316 | */ | 12776 | */ |
16317 | for (i = 0; i < sizeof(ADVEEP_38C0800_CONFIG); i++) { | 12777 | memcpy(&eep_config, &Default_38C0800_EEPROM_Config, |
16318 | *((uchar *)&eep_config + i) = | 12778 | sizeof(ADVEEP_38C0800_CONFIG)); |
16319 | *((uchar *)&Default_38C0800_EEPROM_Config + i); | ||
16320 | } | ||
16321 | 12779 | ||
16322 | /* | 12780 | /* |
16323 | * Assume the 6 byte board serial number that was read | 12781 | * Assume the 6 byte board serial number that was read from |
16324 | * from EEPROM is correct even if the EEPROM checksum | 12782 | * EEPROM is correct even if the EEPROM checksum failed. |
16325 | * failed. | ||
16326 | */ | 12783 | */ |
16327 | eep_config.serial_number_word3 = | 12784 | eep_config.serial_number_word3 = |
16328 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); | 12785 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); |
@@ -16492,12 +12949,11 @@ static int __init AdvInitFrom38C0800EEP(ADV_DVC_VAR *asc_dvc) | |||
16492 | * | 12949 | * |
16493 | * Note: Chip is stopped on entry. | 12950 | * Note: Chip is stopped on entry. |
16494 | */ | 12951 | */ |
16495 | static int __init AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc) | 12952 | static int __devinit AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc) |
16496 | { | 12953 | { |
16497 | AdvPortAddr iop_base; | 12954 | AdvPortAddr iop_base; |
16498 | ushort warn_code; | 12955 | ushort warn_code; |
16499 | ADVEEP_38C1600_CONFIG eep_config; | 12956 | ADVEEP_38C1600_CONFIG eep_config; |
16500 | int i; | ||
16501 | uchar tid, termination; | 12957 | uchar tid, termination; |
16502 | ushort sdtr_speed = 0; | 12958 | ushort sdtr_speed = 0; |
16503 | 12959 | ||
@@ -16512,75 +12968,52 @@ static int __init AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc) | |||
16512 | */ | 12968 | */ |
16513 | if (AdvGet38C1600EEPConfig(iop_base, &eep_config) != | 12969 | if (AdvGet38C1600EEPConfig(iop_base, &eep_config) != |
16514 | eep_config.check_sum) { | 12970 | eep_config.check_sum) { |
12971 | struct pci_dev *pdev = adv_dvc_to_pdev(asc_dvc); | ||
16515 | warn_code |= ASC_WARN_EEPROM_CHKSUM; | 12972 | warn_code |= ASC_WARN_EEPROM_CHKSUM; |
16516 | 12973 | ||
16517 | /* | 12974 | /* |
16518 | * Set EEPROM default values. | 12975 | * Set EEPROM default values. |
16519 | */ | 12976 | */ |
16520 | for (i = 0; i < sizeof(ADVEEP_38C1600_CONFIG); i++) { | 12977 | memcpy(&eep_config, &Default_38C1600_EEPROM_Config, |
16521 | if (i == 1 | 12978 | sizeof(ADVEEP_38C1600_CONFIG)); |
16522 | && ASC_PCI_ID2FUNC(asc_dvc->cfg->pci_slot_info) != | ||
16523 | 0) { | ||
16524 | /* | ||
16525 | * Set Function 1 EEPROM Word 0 MSB | ||
16526 | * | ||
16527 | * Clear the BIOS_ENABLE (bit 14) and INTAB (bit 11) | ||
16528 | * EEPROM bits. | ||
16529 | * | ||
16530 | * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 and | ||
16531 | * old Mac system booting problem. The Expansion ROM must | ||
16532 | * be disabled in Function 1 for these systems. | ||
16533 | * | ||
16534 | */ | ||
16535 | *((uchar *)&eep_config + i) = | ||
16536 | ((* | ||
16537 | ((uchar *)&Default_38C1600_EEPROM_Config | ||
16538 | + | ||
16539 | i)) & | ||
16540 | (~ | ||
16541 | (((ADV_EEPROM_BIOS_ENABLE | | ||
16542 | ADV_EEPROM_INTAB) >> 8) & 0xFF))); | ||
16543 | 12979 | ||
16544 | /* | 12980 | if (PCI_FUNC(pdev->devfn) != 0) { |
16545 | * Set the INTAB (bit 11) if the GPIO 0 input indicates | 12981 | u8 ints; |
16546 | * the Function 1 interrupt line is wired to INTA. | 12982 | /* |
16547 | * | 12983 | * Disable Bit 14 (BIOS_ENABLE) to fix SPARC Ultra 60 |
16548 | * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input: | 12984 | * and old Mac system booting problem. The Expansion |
16549 | * 1 - Function 1 interrupt line wired to INT A. | 12985 | * ROM must be disabled in Function 1 for these systems |
16550 | * 0 - Function 1 interrupt line wired to INT B. | 12986 | */ |
16551 | * | 12987 | eep_config.cfg_lsw &= ~ADV_EEPROM_BIOS_ENABLE; |
16552 | * Note: Adapter boards always have Function 0 wired to INTA. | 12988 | /* |
16553 | * Put all 5 GPIO bits in input mode and then read | 12989 | * Clear the INTAB (bit 11) if the GPIO 0 input |
16554 | * their input values. | 12990 | * indicates the Function 1 interrupt line is wired |
16555 | */ | 12991 | * to INTB. |
16556 | AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, | 12992 | * |
16557 | 0); | 12993 | * Set/Clear Bit 11 (INTAB) from the GPIO bit 0 input: |
16558 | if (AdvReadByteRegister | 12994 | * 1 - Function 1 interrupt line wired to INT A. |
16559 | (iop_base, IOPB_GPIO_DATA) & 0x01) { | 12995 | * 0 - Function 1 interrupt line wired to INT B. |
16560 | /* Function 1 interrupt wired to INTA; Set EEPROM bit. */ | 12996 | * |
16561 | *((uchar *)&eep_config + i) |= | 12997 | * Note: Function 0 is always wired to INTA. |
16562 | ((ADV_EEPROM_INTAB >> 8) & 0xFF); | 12998 | * Put all 5 GPIO bits in input mode and then read |
16563 | } | 12999 | * their input values. |
16564 | } else { | 13000 | */ |
16565 | *((uchar *)&eep_config + i) = | 13001 | AdvWriteByteRegister(iop_base, IOPB_GPIO_CNTL, 0); |
16566 | *((uchar *)&Default_38C1600_EEPROM_Config | 13002 | ints = AdvReadByteRegister(iop_base, IOPB_GPIO_DATA); |
16567 | + i); | 13003 | if ((ints & 0x01) == 0) |
16568 | } | 13004 | eep_config.cfg_lsw &= ~ADV_EEPROM_INTAB; |
16569 | } | 13005 | } |
16570 | 13006 | ||
16571 | /* | 13007 | /* |
16572 | * Assume the 6 byte board serial number that was read | 13008 | * Assume the 6 byte board serial number that was read from |
16573 | * from EEPROM is correct even if the EEPROM checksum | 13009 | * EEPROM is correct even if the EEPROM checksum failed. |
16574 | * failed. | ||
16575 | */ | 13010 | */ |
16576 | eep_config.serial_number_word3 = | 13011 | eep_config.serial_number_word3 = |
16577 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); | 13012 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 1); |
16578 | |||
16579 | eep_config.serial_number_word2 = | 13013 | eep_config.serial_number_word2 = |
16580 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2); | 13014 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 2); |
16581 | |||
16582 | eep_config.serial_number_word1 = | 13015 | eep_config.serial_number_word1 = |
16583 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3); | 13016 | AdvReadEEPWord(iop_base, ADV_EEP_DVC_CFG_END - 3); |
16584 | 13017 | ||
16585 | AdvSet38C1600EEPConfig(iop_base, &eep_config); | 13018 | AdvSet38C1600EEPConfig(iop_base, &eep_config); |
16586 | } | 13019 | } |
@@ -16729,1176 +13162,281 @@ static int __init AdvInitFrom38C1600EEP(ADV_DVC_VAR *asc_dvc) | |||
16729 | } | 13162 | } |
16730 | 13163 | ||
16731 | /* | 13164 | /* |
16732 | * Read EEPROM configuration into the specified buffer. | 13165 | * Initialize the ADV_DVC_VAR structure. |
16733 | * | ||
16734 | * Return a checksum based on the EEPROM configuration read. | ||
16735 | */ | ||
16736 | static ushort __init | ||
16737 | AdvGet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) | ||
16738 | { | ||
16739 | ushort wval, chksum; | ||
16740 | ushort *wbuf; | ||
16741 | int eep_addr; | ||
16742 | ushort *charfields; | ||
16743 | |||
16744 | charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar; | ||
16745 | wbuf = (ushort *)cfg_buf; | ||
16746 | chksum = 0; | ||
16747 | |||
16748 | for (eep_addr = ADV_EEP_DVC_CFG_BEGIN; | ||
16749 | eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) { | ||
16750 | wval = AdvReadEEPWord(iop_base, eep_addr); | ||
16751 | chksum += wval; /* Checksum is calculated from word values. */ | ||
16752 | if (*charfields++) { | ||
16753 | *wbuf = le16_to_cpu(wval); | ||
16754 | } else { | ||
16755 | *wbuf = wval; | ||
16756 | } | ||
16757 | } | ||
16758 | /* Read checksum word. */ | ||
16759 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); | ||
16760 | wbuf++; | ||
16761 | charfields++; | ||
16762 | |||
16763 | /* Read rest of EEPROM not covered by the checksum. */ | ||
16764 | for (eep_addr = ADV_EEP_DVC_CTL_BEGIN; | ||
16765 | eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) { | ||
16766 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); | ||
16767 | if (*charfields++) { | ||
16768 | *wbuf = le16_to_cpu(*wbuf); | ||
16769 | } | ||
16770 | } | ||
16771 | return chksum; | ||
16772 | } | ||
16773 | |||
16774 | /* | ||
16775 | * Read EEPROM configuration into the specified buffer. | ||
16776 | * | 13166 | * |
16777 | * Return a checksum based on the EEPROM configuration read. | 13167 | * On failure set the ADV_DVC_VAR field 'err_code' and return ADV_ERROR. |
16778 | */ | ||
16779 | static ushort __init | ||
16780 | AdvGet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf) | ||
16781 | { | ||
16782 | ushort wval, chksum; | ||
16783 | ushort *wbuf; | ||
16784 | int eep_addr; | ||
16785 | ushort *charfields; | ||
16786 | |||
16787 | charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar; | ||
16788 | wbuf = (ushort *)cfg_buf; | ||
16789 | chksum = 0; | ||
16790 | |||
16791 | for (eep_addr = ADV_EEP_DVC_CFG_BEGIN; | ||
16792 | eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) { | ||
16793 | wval = AdvReadEEPWord(iop_base, eep_addr); | ||
16794 | chksum += wval; /* Checksum is calculated from word values. */ | ||
16795 | if (*charfields++) { | ||
16796 | *wbuf = le16_to_cpu(wval); | ||
16797 | } else { | ||
16798 | *wbuf = wval; | ||
16799 | } | ||
16800 | } | ||
16801 | /* Read checksum word. */ | ||
16802 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); | ||
16803 | wbuf++; | ||
16804 | charfields++; | ||
16805 | |||
16806 | /* Read rest of EEPROM not covered by the checksum. */ | ||
16807 | for (eep_addr = ADV_EEP_DVC_CTL_BEGIN; | ||
16808 | eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) { | ||
16809 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); | ||
16810 | if (*charfields++) { | ||
16811 | *wbuf = le16_to_cpu(*wbuf); | ||
16812 | } | ||
16813 | } | ||
16814 | return chksum; | ||
16815 | } | ||
16816 | |||
16817 | /* | ||
16818 | * Read EEPROM configuration into the specified buffer. | ||
16819 | * | 13168 | * |
16820 | * Return a checksum based on the EEPROM configuration read. | 13169 | * For a non-fatal error return a warning code. If there are no warnings |
16821 | */ | 13170 | * then 0 is returned. |
16822 | static ushort __init | ||
16823 | AdvGet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf) | ||
16824 | { | ||
16825 | ushort wval, chksum; | ||
16826 | ushort *wbuf; | ||
16827 | int eep_addr; | ||
16828 | ushort *charfields; | ||
16829 | |||
16830 | charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar; | ||
16831 | wbuf = (ushort *)cfg_buf; | ||
16832 | chksum = 0; | ||
16833 | |||
16834 | for (eep_addr = ADV_EEP_DVC_CFG_BEGIN; | ||
16835 | eep_addr < ADV_EEP_DVC_CFG_END; eep_addr++, wbuf++) { | ||
16836 | wval = AdvReadEEPWord(iop_base, eep_addr); | ||
16837 | chksum += wval; /* Checksum is calculated from word values. */ | ||
16838 | if (*charfields++) { | ||
16839 | *wbuf = le16_to_cpu(wval); | ||
16840 | } else { | ||
16841 | *wbuf = wval; | ||
16842 | } | ||
16843 | } | ||
16844 | /* Read checksum word. */ | ||
16845 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); | ||
16846 | wbuf++; | ||
16847 | charfields++; | ||
16848 | |||
16849 | /* Read rest of EEPROM not covered by the checksum. */ | ||
16850 | for (eep_addr = ADV_EEP_DVC_CTL_BEGIN; | ||
16851 | eep_addr < ADV_EEP_MAX_WORD_ADDR; eep_addr++, wbuf++) { | ||
16852 | *wbuf = AdvReadEEPWord(iop_base, eep_addr); | ||
16853 | if (*charfields++) { | ||
16854 | *wbuf = le16_to_cpu(*wbuf); | ||
16855 | } | ||
16856 | } | ||
16857 | return chksum; | ||
16858 | } | ||
16859 | |||
16860 | /* | ||
16861 | * Read the EEPROM from specified location | ||
16862 | */ | ||
16863 | static ushort __init AdvReadEEPWord(AdvPortAddr iop_base, int eep_word_addr) | ||
16864 | { | ||
16865 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, | ||
16866 | ASC_EEP_CMD_READ | eep_word_addr); | ||
16867 | AdvWaitEEPCmd(iop_base); | ||
16868 | return AdvReadWordRegister(iop_base, IOPW_EE_DATA); | ||
16869 | } | ||
16870 | |||
16871 | /* | ||
16872 | * Wait for EEPROM command to complete | ||
16873 | */ | ||
16874 | static void __init AdvWaitEEPCmd(AdvPortAddr iop_base) | ||
16875 | { | ||
16876 | int eep_delay_ms; | ||
16877 | |||
16878 | for (eep_delay_ms = 0; eep_delay_ms < ADV_EEP_DELAY_MS; eep_delay_ms++) { | ||
16879 | if (AdvReadWordRegister(iop_base, IOPW_EE_CMD) & | ||
16880 | ASC_EEP_CMD_DONE) { | ||
16881 | break; | ||
16882 | } | ||
16883 | DvcSleepMilliSecond(1); | ||
16884 | } | ||
16885 | if ((AdvReadWordRegister(iop_base, IOPW_EE_CMD) & ASC_EEP_CMD_DONE) == | ||
16886 | 0) { | ||
16887 | ASC_ASSERT(0); | ||
16888 | } | ||
16889 | return; | ||
16890 | } | ||
16891 | |||
16892 | /* | ||
16893 | * Write the EEPROM from 'cfg_buf'. | ||
16894 | */ | 13171 | */ |
16895 | void __init | 13172 | static int __devinit |
16896 | AdvSet3550EEPConfig(AdvPortAddr iop_base, ADVEEP_3550_CONFIG *cfg_buf) | 13173 | AdvInitGetConfig(struct pci_dev *pdev, struct Scsi_Host *shost) |
16897 | { | 13174 | { |
16898 | ushort *wbuf; | 13175 | struct asc_board *board = shost_priv(shost); |
16899 | ushort addr, chksum; | 13176 | ADV_DVC_VAR *asc_dvc = &board->dvc_var.adv_dvc_var; |
16900 | ushort *charfields; | 13177 | unsigned short warn_code = 0; |
16901 | 13178 | AdvPortAddr iop_base = asc_dvc->iop_base; | |
16902 | wbuf = (ushort *)cfg_buf; | 13179 | u16 cmd; |
16903 | charfields = (ushort *)&ADVEEP_3550_Config_Field_IsChar; | 13180 | int status; |
16904 | chksum = 0; | ||
16905 | |||
16906 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE); | ||
16907 | AdvWaitEEPCmd(iop_base); | ||
16908 | |||
16909 | /* | ||
16910 | * Write EEPROM from word 0 to word 20. | ||
16911 | */ | ||
16912 | for (addr = ADV_EEP_DVC_CFG_BEGIN; | ||
16913 | addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) { | ||
16914 | ushort word; | ||
16915 | |||
16916 | if (*charfields++) { | ||
16917 | word = cpu_to_le16(*wbuf); | ||
16918 | } else { | ||
16919 | word = *wbuf; | ||
16920 | } | ||
16921 | chksum += *wbuf; /* Checksum is calculated from word values. */ | ||
16922 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); | ||
16923 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, | ||
16924 | ASC_EEP_CMD_WRITE | addr); | ||
16925 | AdvWaitEEPCmd(iop_base); | ||
16926 | DvcSleepMilliSecond(ADV_EEP_DELAY_MS); | ||
16927 | } | ||
16928 | 13181 | ||
16929 | /* | 13182 | asc_dvc->err_code = 0; |
16930 | * Write EEPROM checksum at word 21. | ||
16931 | */ | ||
16932 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum); | ||
16933 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); | ||
16934 | AdvWaitEEPCmd(iop_base); | ||
16935 | wbuf++; | ||
16936 | charfields++; | ||
16937 | 13183 | ||
16938 | /* | 13184 | /* |
16939 | * Write EEPROM OEM name at words 22 to 29. | 13185 | * Save the state of the PCI Configuration Command Register |
13186 | * "Parity Error Response Control" Bit. If the bit is clear (0), | ||
13187 | * in AdvInitAsc3550/38C0800Driver() tell the microcode to ignore | ||
13188 | * DMA parity errors. | ||
16940 | */ | 13189 | */ |
16941 | for (addr = ADV_EEP_DVC_CTL_BEGIN; | 13190 | asc_dvc->cfg->control_flag = 0; |
16942 | addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) { | 13191 | pci_read_config_word(pdev, PCI_COMMAND, &cmd); |
16943 | ushort word; | 13192 | if ((cmd & PCI_COMMAND_PARITY) == 0) |
16944 | 13193 | asc_dvc->cfg->control_flag |= CONTROL_FLAG_IGNORE_PERR; | |
16945 | if (*charfields++) { | ||
16946 | word = cpu_to_le16(*wbuf); | ||
16947 | } else { | ||
16948 | word = *wbuf; | ||
16949 | } | ||
16950 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); | ||
16951 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, | ||
16952 | ASC_EEP_CMD_WRITE | addr); | ||
16953 | AdvWaitEEPCmd(iop_base); | ||
16954 | } | ||
16955 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE); | ||
16956 | AdvWaitEEPCmd(iop_base); | ||
16957 | return; | ||
16958 | } | ||
16959 | |||
16960 | /* | ||
16961 | * Write the EEPROM from 'cfg_buf'. | ||
16962 | */ | ||
16963 | void __init | ||
16964 | AdvSet38C0800EEPConfig(AdvPortAddr iop_base, ADVEEP_38C0800_CONFIG *cfg_buf) | ||
16965 | { | ||
16966 | ushort *wbuf; | ||
16967 | ushort *charfields; | ||
16968 | ushort addr, chksum; | ||
16969 | |||
16970 | wbuf = (ushort *)cfg_buf; | ||
16971 | charfields = (ushort *)&ADVEEP_38C0800_Config_Field_IsChar; | ||
16972 | chksum = 0; | ||
16973 | |||
16974 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE); | ||
16975 | AdvWaitEEPCmd(iop_base); | ||
16976 | 13194 | ||
16977 | /* | 13195 | asc_dvc->cfg->chip_version = |
16978 | * Write EEPROM from word 0 to word 20. | 13196 | AdvGetChipVersion(iop_base, asc_dvc->bus_type); |
16979 | */ | ||
16980 | for (addr = ADV_EEP_DVC_CFG_BEGIN; | ||
16981 | addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) { | ||
16982 | ushort word; | ||
16983 | 13197 | ||
16984 | if (*charfields++) { | 13198 | ASC_DBG(1, "iopb_chip_id_1: 0x%x 0x%x\n", |
16985 | word = cpu_to_le16(*wbuf); | 13199 | (ushort)AdvReadByteRegister(iop_base, IOPB_CHIP_ID_1), |
16986 | } else { | 13200 | (ushort)ADV_CHIP_ID_BYTE); |
16987 | word = *wbuf; | ||
16988 | } | ||
16989 | chksum += *wbuf; /* Checksum is calculated from word values. */ | ||
16990 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); | ||
16991 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, | ||
16992 | ASC_EEP_CMD_WRITE | addr); | ||
16993 | AdvWaitEEPCmd(iop_base); | ||
16994 | DvcSleepMilliSecond(ADV_EEP_DELAY_MS); | ||
16995 | } | ||
16996 | 13201 | ||
16997 | /* | 13202 | ASC_DBG(1, "iopw_chip_id_0: 0x%x 0x%x\n", |
16998 | * Write EEPROM checksum at word 21. | 13203 | (ushort)AdvReadWordRegister(iop_base, IOPW_CHIP_ID_0), |
16999 | */ | 13204 | (ushort)ADV_CHIP_ID_WORD); |
17000 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum); | ||
17001 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); | ||
17002 | AdvWaitEEPCmd(iop_base); | ||
17003 | wbuf++; | ||
17004 | charfields++; | ||
17005 | 13205 | ||
17006 | /* | 13206 | /* |
17007 | * Write EEPROM OEM name at words 22 to 29. | 13207 | * Reset the chip to start and allow register writes. |
17008 | */ | 13208 | */ |
17009 | for (addr = ADV_EEP_DVC_CTL_BEGIN; | 13209 | if (AdvFindSignature(iop_base) == 0) { |
17010 | addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) { | 13210 | asc_dvc->err_code = ASC_IERR_BAD_SIGNATURE; |
17011 | ushort word; | 13211 | return ADV_ERROR; |
17012 | 13212 | } else { | |
17013 | if (*charfields++) { | 13213 | /* |
17014 | word = cpu_to_le16(*wbuf); | 13214 | * The caller must set 'chip_type' to a valid setting. |
17015 | } else { | 13215 | */ |
17016 | word = *wbuf; | 13216 | if (asc_dvc->chip_type != ADV_CHIP_ASC3550 && |
13217 | asc_dvc->chip_type != ADV_CHIP_ASC38C0800 && | ||
13218 | asc_dvc->chip_type != ADV_CHIP_ASC38C1600) { | ||
13219 | asc_dvc->err_code |= ASC_IERR_BAD_CHIPTYPE; | ||
13220 | return ADV_ERROR; | ||
17017 | } | 13221 | } |
17018 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); | ||
17019 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, | ||
17020 | ASC_EEP_CMD_WRITE | addr); | ||
17021 | AdvWaitEEPCmd(iop_base); | ||
17022 | } | ||
17023 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE); | ||
17024 | AdvWaitEEPCmd(iop_base); | ||
17025 | return; | ||
17026 | } | ||
17027 | 13222 | ||
17028 | /* | 13223 | /* |
17029 | * Write the EEPROM from 'cfg_buf'. | 13224 | * Reset Chip. |
17030 | */ | 13225 | */ |
17031 | void __init | 13226 | AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, |
17032 | AdvSet38C1600EEPConfig(AdvPortAddr iop_base, ADVEEP_38C1600_CONFIG *cfg_buf) | 13227 | ADV_CTRL_REG_CMD_RESET); |
17033 | { | 13228 | mdelay(100); |
17034 | ushort *wbuf; | 13229 | AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, |
17035 | ushort *charfields; | 13230 | ADV_CTRL_REG_CMD_WR_IO_REG); |
17036 | ushort addr, chksum; | ||
17037 | |||
17038 | wbuf = (ushort *)cfg_buf; | ||
17039 | charfields = (ushort *)&ADVEEP_38C1600_Config_Field_IsChar; | ||
17040 | chksum = 0; | ||
17041 | |||
17042 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_ABLE); | ||
17043 | AdvWaitEEPCmd(iop_base); | ||
17044 | |||
17045 | /* | ||
17046 | * Write EEPROM from word 0 to word 20. | ||
17047 | */ | ||
17048 | for (addr = ADV_EEP_DVC_CFG_BEGIN; | ||
17049 | addr < ADV_EEP_DVC_CFG_END; addr++, wbuf++) { | ||
17050 | ushort word; | ||
17051 | 13231 | ||
17052 | if (*charfields++) { | 13232 | if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { |
17053 | word = cpu_to_le16(*wbuf); | 13233 | status = AdvInitFrom38C1600EEP(asc_dvc); |
13234 | } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) { | ||
13235 | status = AdvInitFrom38C0800EEP(asc_dvc); | ||
17054 | } else { | 13236 | } else { |
17055 | word = *wbuf; | 13237 | status = AdvInitFrom3550EEP(asc_dvc); |
17056 | } | 13238 | } |
17057 | chksum += *wbuf; /* Checksum is calculated from word values. */ | 13239 | warn_code |= status; |
17058 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); | ||
17059 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, | ||
17060 | ASC_EEP_CMD_WRITE | addr); | ||
17061 | AdvWaitEEPCmd(iop_base); | ||
17062 | DvcSleepMilliSecond(ADV_EEP_DELAY_MS); | ||
17063 | } | 13240 | } |
17064 | 13241 | ||
17065 | /* | 13242 | if (warn_code != 0) |
17066 | * Write EEPROM checksum at word 21. | 13243 | shost_printk(KERN_WARNING, shost, "warning: 0x%x\n", warn_code); |
17067 | */ | ||
17068 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, chksum); | ||
17069 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE | addr); | ||
17070 | AdvWaitEEPCmd(iop_base); | ||
17071 | wbuf++; | ||
17072 | charfields++; | ||
17073 | 13244 | ||
17074 | /* | 13245 | if (asc_dvc->err_code) |
17075 | * Write EEPROM OEM name at words 22 to 29. | 13246 | shost_printk(KERN_ERR, shost, "error code 0x%x\n", |
17076 | */ | 13247 | asc_dvc->err_code); |
17077 | for (addr = ADV_EEP_DVC_CTL_BEGIN; | ||
17078 | addr < ADV_EEP_MAX_WORD_ADDR; addr++, wbuf++) { | ||
17079 | ushort word; | ||
17080 | 13248 | ||
17081 | if (*charfields++) { | 13249 | return asc_dvc->err_code; |
17082 | word = cpu_to_le16(*wbuf); | ||
17083 | } else { | ||
17084 | word = *wbuf; | ||
17085 | } | ||
17086 | AdvWriteWordRegister(iop_base, IOPW_EE_DATA, word); | ||
17087 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, | ||
17088 | ASC_EEP_CMD_WRITE | addr); | ||
17089 | AdvWaitEEPCmd(iop_base); | ||
17090 | } | ||
17091 | AdvWriteWordRegister(iop_base, IOPW_EE_CMD, ASC_EEP_CMD_WRITE_DISABLE); | ||
17092 | AdvWaitEEPCmd(iop_base); | ||
17093 | return; | ||
17094 | } | 13250 | } |
13251 | #endif | ||
17095 | 13252 | ||
17096 | /* a_advlib.c */ | 13253 | static struct scsi_host_template advansys_template = { |
17097 | /* | 13254 | .proc_name = DRV_NAME, |
17098 | * AdvExeScsiQueue() - Send a request to the RISC microcode program. | 13255 | #ifdef CONFIG_PROC_FS |
17099 | * | 13256 | .proc_info = advansys_proc_info, |
17100 | * Allocate a carrier structure, point the carrier to the ADV_SCSI_REQ_Q, | 13257 | #endif |
17101 | * add the carrier to the ICQ (Initiator Command Queue), and tickle the | 13258 | .name = DRV_NAME, |
17102 | * RISC to notify it a new command is ready to be executed. | 13259 | .info = advansys_info, |
17103 | * | 13260 | .queuecommand = advansys_queuecommand, |
17104 | * If 'done_status' is not set to QD_DO_RETRY, then 'error_retry' will be | 13261 | .eh_bus_reset_handler = advansys_reset, |
17105 | * set to SCSI_MAX_RETRY. | 13262 | .bios_param = advansys_biosparam, |
17106 | * | 13263 | .slave_configure = advansys_slave_configure, |
17107 | * Multi-byte fields in the ASC_SCSI_REQ_Q that are used by the microcode | ||
17108 | * for DMA addresses or math operations are byte swapped to little-endian | ||
17109 | * order. | ||
17110 | * | ||
17111 | * Return: | ||
17112 | * ADV_SUCCESS(1) - The request was successfully queued. | ||
17113 | * ADV_BUSY(0) - Resource unavailable; Retry again after pending | ||
17114 | * request completes. | ||
17115 | * ADV_ERROR(-1) - Invalid ADV_SCSI_REQ_Q request structure | ||
17116 | * host IC error. | ||
17117 | */ | ||
17118 | static int AdvExeScsiQueue(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) | ||
17119 | { | ||
17120 | ulong last_int_level; | ||
17121 | AdvPortAddr iop_base; | ||
17122 | ADV_DCNT req_size; | ||
17123 | ADV_PADDR req_paddr; | ||
17124 | ADV_CARR_T *new_carrp; | ||
17125 | |||
17126 | ASC_ASSERT(scsiq != NULL); /* 'scsiq' should never be NULL. */ | ||
17127 | |||
17128 | /* | ||
17129 | * The ADV_SCSI_REQ_Q 'target_id' field should never exceed ADV_MAX_TID. | ||
17130 | */ | ||
17131 | if (scsiq->target_id > ADV_MAX_TID) { | ||
17132 | scsiq->host_status = QHSTA_M_INVALID_DEVICE; | ||
17133 | scsiq->done_status = QD_WITH_ERROR; | ||
17134 | return ADV_ERROR; | ||
17135 | } | ||
17136 | |||
17137 | iop_base = asc_dvc->iop_base; | ||
17138 | |||
17139 | last_int_level = DvcEnterCritical(); | ||
17140 | |||
17141 | /* | ||
17142 | * Allocate a carrier ensuring at least one carrier always | ||
17143 | * remains on the freelist and initialize fields. | ||
17144 | */ | ||
17145 | if ((new_carrp = asc_dvc->carr_freelist) == NULL) { | ||
17146 | DvcLeaveCritical(last_int_level); | ||
17147 | return ADV_BUSY; | ||
17148 | } | ||
17149 | asc_dvc->carr_freelist = (ADV_CARR_T *) | ||
17150 | ADV_U32_TO_VADDR(le32_to_cpu(new_carrp->next_vpa)); | ||
17151 | asc_dvc->carr_pending_cnt++; | ||
17152 | |||
17153 | /* | ||
17154 | * Set the carrier to be a stopper by setting 'next_vpa' | ||
17155 | * to the stopper value. The current stopper will be changed | ||
17156 | * below to point to the new stopper. | ||
17157 | */ | ||
17158 | new_carrp->next_vpa = cpu_to_le32(ASC_CQ_STOPPER); | ||
17159 | |||
17160 | /* | ||
17161 | * Clear the ADV_SCSI_REQ_Q done flag. | ||
17162 | */ | ||
17163 | scsiq->a_flag &= ~ADV_SCSIQ_DONE; | ||
17164 | |||
17165 | req_size = sizeof(ADV_SCSI_REQ_Q); | ||
17166 | req_paddr = DvcGetPhyAddr(asc_dvc, scsiq, (uchar *)scsiq, | ||
17167 | (ADV_SDCNT *)&req_size, ADV_IS_SCSIQ_FLAG); | ||
17168 | |||
17169 | ASC_ASSERT(ADV_32BALIGN(req_paddr) == req_paddr); | ||
17170 | ASC_ASSERT(req_size >= sizeof(ADV_SCSI_REQ_Q)); | ||
17171 | |||
17172 | /* Wait for assertion before making little-endian */ | ||
17173 | req_paddr = cpu_to_le32(req_paddr); | ||
17174 | |||
17175 | /* Save virtual and physical address of ADV_SCSI_REQ_Q and carrier. */ | ||
17176 | scsiq->scsiq_ptr = cpu_to_le32(ADV_VADDR_TO_U32(scsiq)); | ||
17177 | scsiq->scsiq_rptr = req_paddr; | ||
17178 | |||
17179 | scsiq->carr_va = cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->icq_sp)); | ||
17180 | /* | ||
17181 | * Every ADV_CARR_T.carr_pa is byte swapped to little-endian | ||
17182 | * order during initialization. | ||
17183 | */ | ||
17184 | scsiq->carr_pa = asc_dvc->icq_sp->carr_pa; | ||
17185 | |||
17186 | /* | ||
17187 | * Use the current stopper to send the ADV_SCSI_REQ_Q command to | ||
17188 | * the microcode. The newly allocated stopper will become the new | ||
17189 | * stopper. | ||
17190 | */ | ||
17191 | asc_dvc->icq_sp->areq_vpa = req_paddr; | ||
17192 | |||
17193 | /* | 13264 | /* |
17194 | * Set the 'next_vpa' pointer for the old stopper to be the | 13265 | * Because the driver may control an ISA adapter 'unchecked_isa_dma' |
17195 | * physical address of the new stopper. The RISC can only | 13266 | * must be set. The flag will be cleared in advansys_board_found |
17196 | * follow physical addresses. | 13267 | * for non-ISA adapters. |
17197 | */ | 13268 | */ |
17198 | asc_dvc->icq_sp->next_vpa = new_carrp->carr_pa; | 13269 | .unchecked_isa_dma = 1, |
17199 | |||
17200 | /* | 13270 | /* |
17201 | * Set the host adapter stopper pointer to point to the new carrier. | 13271 | * All adapters controlled by this driver are capable of large |
13272 | * scatter-gather lists. According to the mid-level SCSI documentation | ||
13273 | * this obviates any performance gain provided by setting | ||
13274 | * 'use_clustering'. But empirically while CPU utilization is increased | ||
13275 | * by enabling clustering, I/O throughput increases as well. | ||
17202 | */ | 13276 | */ |
17203 | asc_dvc->icq_sp = new_carrp; | 13277 | .use_clustering = ENABLE_CLUSTERING, |
17204 | 13278 | }; | |
17205 | if (asc_dvc->chip_type == ADV_CHIP_ASC3550 || | ||
17206 | asc_dvc->chip_type == ADV_CHIP_ASC38C0800) { | ||
17207 | /* | ||
17208 | * Tickle the RISC to tell it to read its Command Queue Head pointer. | ||
17209 | */ | ||
17210 | AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_A); | ||
17211 | if (asc_dvc->chip_type == ADV_CHIP_ASC3550) { | ||
17212 | /* | ||
17213 | * Clear the tickle value. In the ASC-3550 the RISC flag | ||
17214 | * command 'clr_tickle_a' does not work unless the host | ||
17215 | * value is cleared. | ||
17216 | */ | ||
17217 | AdvWriteByteRegister(iop_base, IOPB_TICKLE, | ||
17218 | ADV_TICKLE_NOP); | ||
17219 | } | ||
17220 | } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { | ||
17221 | /* | ||
17222 | * Notify the RISC a carrier is ready by writing the physical | ||
17223 | * address of the new carrier stopper to the COMMA register. | ||
17224 | */ | ||
17225 | AdvWriteDWordRegister(iop_base, IOPDW_COMMA, | ||
17226 | le32_to_cpu(new_carrp->carr_pa)); | ||
17227 | } | ||
17228 | |||
17229 | DvcLeaveCritical(last_int_level); | ||
17230 | |||
17231 | return ADV_SUCCESS; | ||
17232 | } | ||
17233 | 13279 | ||
17234 | /* | 13280 | static int __devinit advansys_wide_init_chip(struct Scsi_Host *shost) |
17235 | * Reset SCSI Bus and purge all outstanding requests. | ||
17236 | * | ||
17237 | * Return Value: | ||
17238 | * ADV_TRUE(1) - All requests are purged and SCSI Bus is reset. | ||
17239 | * ADV_FALSE(0) - Microcode command failed. | ||
17240 | * ADV_ERROR(-1) - Microcode command timed-out. Microcode or IC | ||
17241 | * may be hung which requires driver recovery. | ||
17242 | */ | ||
17243 | static int AdvResetSB(ADV_DVC_VAR *asc_dvc) | ||
17244 | { | 13281 | { |
17245 | int status; | 13282 | struct asc_board *board = shost_priv(shost); |
13283 | struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var; | ||
13284 | int req_cnt = 0; | ||
13285 | adv_req_t *reqp = NULL; | ||
13286 | int sg_cnt = 0; | ||
13287 | adv_sgblk_t *sgp; | ||
13288 | int warn_code, err_code; | ||
17246 | 13289 | ||
17247 | /* | 13290 | /* |
17248 | * Send the SCSI Bus Reset idle start idle command which asserts | 13291 | * Allocate buffer carrier structures. The total size |
17249 | * the SCSI Bus Reset signal. | 13292 | * is about 4 KB, so allocate all at once. |
17250 | */ | 13293 | */ |
17251 | status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_START, 0L); | 13294 | adv_dvc->carrier_buf = kmalloc(ADV_CARRIER_BUFSIZE, GFP_KERNEL); |
17252 | if (status != ADV_TRUE) { | 13295 | ASC_DBG(1, "carrier_buf 0x%p\n", adv_dvc->carrier_buf); |
17253 | return status; | ||
17254 | } | ||
17255 | 13296 | ||
17256 | /* | 13297 | if (!adv_dvc->carrier_buf) |
17257 | * Delay for the specified SCSI Bus Reset hold time. | 13298 | goto kmalloc_failed; |
17258 | * | ||
17259 | * The hold time delay is done on the host because the RISC has no | ||
17260 | * microsecond accurate timer. | ||
17261 | */ | ||
17262 | DvcDelayMicroSecond(asc_dvc, (ushort)ASC_SCSI_RESET_HOLD_TIME_US); | ||
17263 | 13299 | ||
17264 | /* | 13300 | /* |
17265 | * Send the SCSI Bus Reset end idle command which de-asserts | 13301 | * Allocate up to 'max_host_qng' request structures for the Wide |
17266 | * the SCSI Bus Reset signal and purges any pending requests. | 13302 | * board. The total size is about 16 KB, so allocate all at once. |
13303 | * If the allocation fails decrement and try again. | ||
17267 | */ | 13304 | */ |
17268 | status = AdvSendIdleCmd(asc_dvc, (ushort)IDLE_CMD_SCSI_RESET_END, 0L); | 13305 | for (req_cnt = adv_dvc->max_host_qng; req_cnt > 0; req_cnt--) { |
17269 | if (status != ADV_TRUE) { | 13306 | reqp = kmalloc(sizeof(adv_req_t) * req_cnt, GFP_KERNEL); |
17270 | return status; | ||
17271 | } | ||
17272 | |||
17273 | DvcSleepMilliSecond((ADV_DCNT)asc_dvc->scsi_reset_wait * 1000); | ||
17274 | |||
17275 | return status; | ||
17276 | } | ||
17277 | |||
17278 | /* | ||
17279 | * Reset chip and SCSI Bus. | ||
17280 | * | ||
17281 | * Return Value: | ||
17282 | * ADV_TRUE(1) - Chip re-initialization and SCSI Bus Reset successful. | ||
17283 | * ADV_FALSE(0) - Chip re-initialization and SCSI Bus Reset failure. | ||
17284 | */ | ||
17285 | static int AdvResetChipAndSB(ADV_DVC_VAR *asc_dvc) | ||
17286 | { | ||
17287 | int status; | ||
17288 | ushort wdtr_able, sdtr_able, tagqng_able; | ||
17289 | ushort ppr_able = 0; | ||
17290 | uchar tid, max_cmd[ADV_MAX_TID + 1]; | ||
17291 | AdvPortAddr iop_base; | ||
17292 | ushort bios_sig; | ||
17293 | 13307 | ||
17294 | iop_base = asc_dvc->iop_base; | 13308 | ASC_DBG(1, "reqp 0x%p, req_cnt %d, bytes %lu\n", reqp, req_cnt, |
13309 | (ulong)sizeof(adv_req_t) * req_cnt); | ||
17295 | 13310 | ||
17296 | /* | 13311 | if (reqp) |
17297 | * Save current per TID negotiated values. | 13312 | break; |
17298 | */ | ||
17299 | AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
17300 | AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
17301 | if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { | ||
17302 | AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); | ||
17303 | } | ||
17304 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | ||
17305 | for (tid = 0; tid <= ADV_MAX_TID; tid++) { | ||
17306 | AdvReadByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
17307 | max_cmd[tid]); | ||
17308 | } | 13313 | } |
17309 | 13314 | ||
17310 | /* | 13315 | if (!reqp) |
17311 | * Force the AdvInitAsc3550/38C0800Driver() function to | 13316 | goto kmalloc_failed; |
17312 | * perform a SCSI Bus Reset by clearing the BIOS signature word. | ||
17313 | * The initialization functions assumes a SCSI Bus Reset is not | ||
17314 | * needed if the BIOS signature word is present. | ||
17315 | */ | ||
17316 | AdvReadWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig); | ||
17317 | AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, 0); | ||
17318 | 13317 | ||
17319 | /* | 13318 | adv_dvc->orig_reqp = reqp; |
17320 | * Stop chip and reset it. | ||
17321 | */ | ||
17322 | AdvWriteWordRegister(iop_base, IOPW_RISC_CSR, ADV_RISC_CSR_STOP); | ||
17323 | AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, ADV_CTRL_REG_CMD_RESET); | ||
17324 | DvcSleepMilliSecond(100); | ||
17325 | AdvWriteWordRegister(iop_base, IOPW_CTRL_REG, | ||
17326 | ADV_CTRL_REG_CMD_WR_IO_REG); | ||
17327 | 13319 | ||
17328 | /* | 13320 | /* |
17329 | * Reset Adv Library error code, if any, and try | 13321 | * Allocate up to ADV_TOT_SG_BLOCK request structures for |
17330 | * re-initializing the chip. | 13322 | * the Wide board. Each structure is about 136 bytes. |
17331 | */ | 13323 | */ |
17332 | asc_dvc->err_code = 0; | 13324 | board->adv_sgblkp = NULL; |
17333 | if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { | 13325 | for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) { |
17334 | status = AdvInitAsc38C1600Driver(asc_dvc); | 13326 | sgp = kmalloc(sizeof(adv_sgblk_t), GFP_KERNEL); |
17335 | } else if (asc_dvc->chip_type == ADV_CHIP_ASC38C0800) { | ||
17336 | status = AdvInitAsc38C0800Driver(asc_dvc); | ||
17337 | } else { | ||
17338 | status = AdvInitAsc3550Driver(asc_dvc); | ||
17339 | } | ||
17340 | 13327 | ||
17341 | /* Translate initialization return value to status value. */ | 13328 | if (!sgp) |
17342 | if (status == 0) { | 13329 | break; |
17343 | status = ADV_TRUE; | ||
17344 | } else { | ||
17345 | status = ADV_FALSE; | ||
17346 | } | ||
17347 | 13330 | ||
17348 | /* | 13331 | sgp->next_sgblkp = board->adv_sgblkp; |
17349 | * Restore the BIOS signature word. | 13332 | board->adv_sgblkp = sgp; |
17350 | */ | ||
17351 | AdvWriteWordLram(iop_base, ASC_MC_BIOS_SIGNATURE, bios_sig); | ||
17352 | 13333 | ||
17353 | /* | ||
17354 | * Restore per TID negotiated values. | ||
17355 | */ | ||
17356 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, wdtr_able); | ||
17357 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, sdtr_able); | ||
17358 | if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600) { | ||
17359 | AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, ppr_able); | ||
17360 | } | 13334 | } |
17361 | AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, tagqng_able); | ||
17362 | for (tid = 0; tid <= ADV_MAX_TID; tid++) { | ||
17363 | AdvWriteByteLram(iop_base, ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
17364 | max_cmd[tid]); | ||
17365 | } | ||
17366 | |||
17367 | return status; | ||
17368 | } | ||
17369 | |||
17370 | /* | ||
17371 | * Adv Library Interrupt Service Routine | ||
17372 | * | ||
17373 | * This function is called by a driver's interrupt service routine. | ||
17374 | * The function disables and re-enables interrupts. | ||
17375 | * | ||
17376 | * When a microcode idle command is completed, the ADV_DVC_VAR | ||
17377 | * 'idle_cmd_done' field is set to ADV_TRUE. | ||
17378 | * | ||
17379 | * Note: AdvISR() can be called when interrupts are disabled or even | ||
17380 | * when there is no hardware interrupt condition present. It will | ||
17381 | * always check for completed idle commands and microcode requests. | ||
17382 | * This is an important feature that shouldn't be changed because it | ||
17383 | * allows commands to be completed from polling mode loops. | ||
17384 | * | ||
17385 | * Return: | ||
17386 | * ADV_TRUE(1) - interrupt was pending | ||
17387 | * ADV_FALSE(0) - no interrupt was pending | ||
17388 | */ | ||
17389 | static int AdvISR(ADV_DVC_VAR *asc_dvc) | ||
17390 | { | ||
17391 | AdvPortAddr iop_base; | ||
17392 | uchar int_stat; | ||
17393 | ushort target_bit; | ||
17394 | ADV_CARR_T *free_carrp; | ||
17395 | ADV_VADDR irq_next_vpa; | ||
17396 | int flags; | ||
17397 | ADV_SCSI_REQ_Q *scsiq; | ||
17398 | |||
17399 | flags = DvcEnterCritical(); | ||
17400 | |||
17401 | iop_base = asc_dvc->iop_base; | ||
17402 | 13335 | ||
17403 | /* Reading the register clears the interrupt. */ | 13336 | ASC_DBG(1, "sg_cnt %d * %lu = %lu bytes\n", sg_cnt, sizeof(adv_sgblk_t), |
17404 | int_stat = AdvReadByteRegister(iop_base, IOPB_INTR_STATUS_REG); | 13337 | sizeof(adv_sgblk_t) * sg_cnt); |
17405 | 13338 | ||
17406 | if ((int_stat & (ADV_INTR_STATUS_INTRA | ADV_INTR_STATUS_INTRB | | 13339 | if (!board->adv_sgblkp) |
17407 | ADV_INTR_STATUS_INTRC)) == 0) { | 13340 | goto kmalloc_failed; |
17408 | DvcLeaveCritical(flags); | ||
17409 | return ADV_FALSE; | ||
17410 | } | ||
17411 | 13341 | ||
17412 | /* | 13342 | /* |
17413 | * Notify the driver of an asynchronous microcode condition by | 13343 | * Point 'adv_reqp' to the request structures and |
17414 | * calling the ADV_DVC_VAR.async_callback function. The function | 13344 | * link them together. |
17415 | * is passed the microcode ASC_MC_INTRB_CODE byte value. | ||
17416 | */ | 13345 | */ |
17417 | if (int_stat & ADV_INTR_STATUS_INTRB) { | 13346 | req_cnt--; |
17418 | uchar intrb_code; | 13347 | reqp[req_cnt].next_reqp = NULL; |
17419 | 13348 | for (; req_cnt > 0; req_cnt--) { | |
17420 | AdvReadByteLram(iop_base, ASC_MC_INTRB_CODE, intrb_code); | 13349 | reqp[req_cnt - 1].next_reqp = &reqp[req_cnt]; |
17421 | |||
17422 | if (asc_dvc->chip_type == ADV_CHIP_ASC3550 || | ||
17423 | asc_dvc->chip_type == ADV_CHIP_ASC38C0800) { | ||
17424 | if (intrb_code == ADV_ASYNC_CARRIER_READY_FAILURE && | ||
17425 | asc_dvc->carr_pending_cnt != 0) { | ||
17426 | AdvWriteByteRegister(iop_base, IOPB_TICKLE, | ||
17427 | ADV_TICKLE_A); | ||
17428 | if (asc_dvc->chip_type == ADV_CHIP_ASC3550) { | ||
17429 | AdvWriteByteRegister(iop_base, | ||
17430 | IOPB_TICKLE, | ||
17431 | ADV_TICKLE_NOP); | ||
17432 | } | ||
17433 | } | ||
17434 | } | ||
17435 | |||
17436 | if (asc_dvc->async_callback != 0) { | ||
17437 | (*asc_dvc->async_callback) (asc_dvc, intrb_code); | ||
17438 | } | ||
17439 | } | 13350 | } |
13351 | board->adv_reqp = &reqp[0]; | ||
17440 | 13352 | ||
17441 | /* | 13353 | if (adv_dvc->chip_type == ADV_CHIP_ASC3550) { |
17442 | * Check if the IRQ stopper carrier contains a completed request. | 13354 | ASC_DBG(2, "AdvInitAsc3550Driver()\n"); |
17443 | */ | 13355 | warn_code = AdvInitAsc3550Driver(adv_dvc); |
17444 | while (((irq_next_vpa = | 13356 | } else if (adv_dvc->chip_type == ADV_CHIP_ASC38C0800) { |
17445 | le32_to_cpu(asc_dvc->irq_sp->next_vpa)) & ASC_RQ_DONE) != 0) { | 13357 | ASC_DBG(2, "AdvInitAsc38C0800Driver()\n"); |
17446 | /* | 13358 | warn_code = AdvInitAsc38C0800Driver(adv_dvc); |
17447 | * Get a pointer to the newly completed ADV_SCSI_REQ_Q structure. | 13359 | } else { |
17448 | * The RISC will have set 'areq_vpa' to a virtual address. | 13360 | ASC_DBG(2, "AdvInitAsc38C1600Driver()\n"); |
17449 | * | 13361 | warn_code = AdvInitAsc38C1600Driver(adv_dvc); |
17450 | * The firmware will have copied the ASC_SCSI_REQ_Q.scsiq_ptr | ||
17451 | * field to the carrier ADV_CARR_T.areq_vpa field. The conversion | ||
17452 | * below complements the conversion of ASC_SCSI_REQ_Q.scsiq_ptr' | ||
17453 | * in AdvExeScsiQueue(). | ||
17454 | */ | ||
17455 | scsiq = (ADV_SCSI_REQ_Q *) | ||
17456 | ADV_U32_TO_VADDR(le32_to_cpu(asc_dvc->irq_sp->areq_vpa)); | ||
17457 | |||
17458 | /* | ||
17459 | * Request finished with good status and the queue was not | ||
17460 | * DMAed to host memory by the firmware. Set all status fields | ||
17461 | * to indicate good status. | ||
17462 | */ | ||
17463 | if ((irq_next_vpa & ASC_RQ_GOOD) != 0) { | ||
17464 | scsiq->done_status = QD_NO_ERROR; | ||
17465 | scsiq->host_status = scsiq->scsi_status = 0; | ||
17466 | scsiq->data_cnt = 0L; | ||
17467 | } | ||
17468 | |||
17469 | /* | ||
17470 | * Advance the stopper pointer to the next carrier | ||
17471 | * ignoring the lower four bits. Free the previous | ||
17472 | * stopper carrier. | ||
17473 | */ | ||
17474 | free_carrp = asc_dvc->irq_sp; | ||
17475 | asc_dvc->irq_sp = (ADV_CARR_T *) | ||
17476 | ADV_U32_TO_VADDR(ASC_GET_CARRP(irq_next_vpa)); | ||
17477 | |||
17478 | free_carrp->next_vpa = | ||
17479 | cpu_to_le32(ADV_VADDR_TO_U32(asc_dvc->carr_freelist)); | ||
17480 | asc_dvc->carr_freelist = free_carrp; | ||
17481 | asc_dvc->carr_pending_cnt--; | ||
17482 | |||
17483 | ASC_ASSERT(scsiq != NULL); | ||
17484 | target_bit = ADV_TID_TO_TIDMASK(scsiq->target_id); | ||
17485 | |||
17486 | /* | ||
17487 | * Clear request microcode control flag. | ||
17488 | */ | ||
17489 | scsiq->cntl = 0; | ||
17490 | |||
17491 | /* | ||
17492 | * If the command that completed was a SCSI INQUIRY and | ||
17493 | * LUN 0 was sent the command, then process the INQUIRY | ||
17494 | * command information for the device. | ||
17495 | * | ||
17496 | * Note: If data returned were either VPD or CmdDt data, | ||
17497 | * don't process the INQUIRY command information for | ||
17498 | * the device, otherwise may erroneously set *_able bits. | ||
17499 | */ | ||
17500 | if (scsiq->done_status == QD_NO_ERROR && | ||
17501 | scsiq->cdb[0] == INQUIRY && | ||
17502 | scsiq->target_lun == 0 && | ||
17503 | (scsiq->cdb[1] & ADV_INQ_RTN_VPD_AND_CMDDT) | ||
17504 | == ADV_INQ_RTN_STD_INQUIRY_DATA) { | ||
17505 | AdvInquiryHandling(asc_dvc, scsiq); | ||
17506 | } | ||
17507 | |||
17508 | /* | ||
17509 | * Notify the driver of the completed request by passing | ||
17510 | * the ADV_SCSI_REQ_Q pointer to its callback function. | ||
17511 | */ | ||
17512 | scsiq->a_flag |= ADV_SCSIQ_DONE; | ||
17513 | (*asc_dvc->isr_callback) (asc_dvc, scsiq); | ||
17514 | /* | ||
17515 | * Note: After the driver callback function is called, 'scsiq' | ||
17516 | * can no longer be referenced. | ||
17517 | * | ||
17518 | * Fall through and continue processing other completed | ||
17519 | * requests... | ||
17520 | */ | ||
17521 | |||
17522 | /* | ||
17523 | * Disable interrupts again in case the driver inadvertently | ||
17524 | * enabled interrupts in its callback function. | ||
17525 | * | ||
17526 | * The DvcEnterCritical() return value is ignored, because | ||
17527 | * the 'flags' saved when AdvISR() was first entered will be | ||
17528 | * used to restore the interrupt flag on exit. | ||
17529 | */ | ||
17530 | (void)DvcEnterCritical(); | ||
17531 | } | 13362 | } |
17532 | DvcLeaveCritical(flags); | 13363 | err_code = adv_dvc->err_code; |
17533 | return ADV_TRUE; | ||
17534 | } | ||
17535 | 13364 | ||
17536 | /* | 13365 | if (warn_code || err_code) { |
17537 | * Send an idle command to the chip and wait for completion. | 13366 | shost_printk(KERN_WARNING, shost, "error: warn 0x%x, error " |
17538 | * | 13367 | "0x%x\n", warn_code, err_code); |
17539 | * Command completion is polled for once per microsecond. | ||
17540 | * | ||
17541 | * The function can be called from anywhere including an interrupt handler. | ||
17542 | * But the function is not re-entrant, so it uses the DvcEnter/LeaveCritical() | ||
17543 | * functions to prevent reentrancy. | ||
17544 | * | ||
17545 | * Return Values: | ||
17546 | * ADV_TRUE - command completed successfully | ||
17547 | * ADV_FALSE - command failed | ||
17548 | * ADV_ERROR - command timed out | ||
17549 | */ | ||
17550 | static int | ||
17551 | AdvSendIdleCmd(ADV_DVC_VAR *asc_dvc, | ||
17552 | ushort idle_cmd, ADV_DCNT idle_cmd_parameter) | ||
17553 | { | ||
17554 | ulong last_int_level; | ||
17555 | int result; | ||
17556 | ADV_DCNT i, j; | ||
17557 | AdvPortAddr iop_base; | ||
17558 | |||
17559 | last_int_level = DvcEnterCritical(); | ||
17560 | |||
17561 | iop_base = asc_dvc->iop_base; | ||
17562 | |||
17563 | /* | ||
17564 | * Clear the idle command status which is set by the microcode | ||
17565 | * to a non-zero value to indicate when the command is completed. | ||
17566 | * The non-zero result is one of the IDLE_CMD_STATUS_* values | ||
17567 | * defined in a_advlib.h. | ||
17568 | */ | ||
17569 | AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, (ushort)0); | ||
17570 | |||
17571 | /* | ||
17572 | * Write the idle command value after the idle command parameter | ||
17573 | * has been written to avoid a race condition. If the order is not | ||
17574 | * followed, the microcode may process the idle command before the | ||
17575 | * parameters have been written to LRAM. | ||
17576 | */ | ||
17577 | AdvWriteDWordLramNoSwap(iop_base, ASC_MC_IDLE_CMD_PARAMETER, | ||
17578 | cpu_to_le32(idle_cmd_parameter)); | ||
17579 | AdvWriteWordLram(iop_base, ASC_MC_IDLE_CMD, idle_cmd); | ||
17580 | |||
17581 | /* | ||
17582 | * Tickle the RISC to tell it to process the idle command. | ||
17583 | */ | ||
17584 | AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_B); | ||
17585 | if (asc_dvc->chip_type == ADV_CHIP_ASC3550) { | ||
17586 | /* | ||
17587 | * Clear the tickle value. In the ASC-3550 the RISC flag | ||
17588 | * command 'clr_tickle_b' does not work unless the host | ||
17589 | * value is cleared. | ||
17590 | */ | ||
17591 | AdvWriteByteRegister(iop_base, IOPB_TICKLE, ADV_TICKLE_NOP); | ||
17592 | } | 13368 | } |
17593 | 13369 | ||
17594 | /* Wait for up to 100 millisecond for the idle command to timeout. */ | 13370 | goto exit; |
17595 | for (i = 0; i < SCSI_WAIT_100_MSEC; i++) { | ||
17596 | /* Poll once each microsecond for command completion. */ | ||
17597 | for (j = 0; j < SCSI_US_PER_MSEC; j++) { | ||
17598 | AdvReadWordLram(iop_base, ASC_MC_IDLE_CMD_STATUS, | ||
17599 | result); | ||
17600 | if (result != 0) { | ||
17601 | DvcLeaveCritical(last_int_level); | ||
17602 | return result; | ||
17603 | } | ||
17604 | DvcDelayMicroSecond(asc_dvc, (ushort)1); | ||
17605 | } | ||
17606 | } | ||
17607 | 13371 | ||
17608 | ASC_ASSERT(0); /* The idle command should never timeout. */ | 13372 | kmalloc_failed: |
17609 | DvcLeaveCritical(last_int_level); | 13373 | shost_printk(KERN_ERR, shost, "error: kmalloc() failed\n"); |
17610 | return ADV_ERROR; | 13374 | err_code = ADV_ERROR; |
13375 | exit: | ||
13376 | return err_code; | ||
17611 | } | 13377 | } |
17612 | 13378 | ||
17613 | /* | 13379 | static void advansys_wide_free_mem(struct asc_board *board) |
17614 | * Inquiry Information Byte 7 Handling | ||
17615 | * | ||
17616 | * Handle SCSI Inquiry Command information for a device by setting | ||
17617 | * microcode operating variables that affect WDTR, SDTR, and Tag | ||
17618 | * Queuing. | ||
17619 | */ | ||
17620 | static void AdvInquiryHandling(ADV_DVC_VAR *asc_dvc, ADV_SCSI_REQ_Q *scsiq) | ||
17621 | { | 13380 | { |
17622 | AdvPortAddr iop_base; | 13381 | struct adv_dvc_var *adv_dvc = &board->dvc_var.adv_dvc_var; |
17623 | uchar tid; | 13382 | kfree(adv_dvc->carrier_buf); |
17624 | ADV_SCSI_INQUIRY *inq; | 13383 | adv_dvc->carrier_buf = NULL; |
17625 | ushort tidmask; | 13384 | kfree(adv_dvc->orig_reqp); |
17626 | ushort cfg_word; | 13385 | adv_dvc->orig_reqp = board->adv_reqp = NULL; |
17627 | 13386 | while (board->adv_sgblkp) { | |
17628 | /* | 13387 | adv_sgblk_t *sgp = board->adv_sgblkp; |
17629 | * AdvInquiryHandling() requires up to INQUIRY information Byte 7 | 13388 | board->adv_sgblkp = sgp->next_sgblkp; |
17630 | * to be available. | 13389 | kfree(sgp); |
17631 | * | ||
17632 | * If less than 8 bytes of INQUIRY information were requested or less | ||
17633 | * than 8 bytes were transferred, then return. cdb[4] is the request | ||
17634 | * length and the ADV_SCSI_REQ_Q 'data_cnt' field is set by the | ||
17635 | * microcode to the transfer residual count. | ||
17636 | */ | ||
17637 | |||
17638 | if (scsiq->cdb[4] < 8 || | ||
17639 | (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) < 8) { | ||
17640 | return; | ||
17641 | } | ||
17642 | |||
17643 | iop_base = asc_dvc->iop_base; | ||
17644 | tid = scsiq->target_id; | ||
17645 | |||
17646 | inq = (ADV_SCSI_INQUIRY *) scsiq->vdata_addr; | ||
17647 | |||
17648 | /* | ||
17649 | * WDTR, SDTR, and Tag Queuing cannot be enabled for old devices. | ||
17650 | */ | ||
17651 | if (ADV_INQ_RESPONSE_FMT(inq) < 2 && ADV_INQ_ANSI_VER(inq) < 2) { | ||
17652 | return; | ||
17653 | } else { | ||
17654 | /* | ||
17655 | * INQUIRY Byte 7 Handling | ||
17656 | * | ||
17657 | * Use a device's INQUIRY byte 7 to determine whether it | ||
17658 | * supports WDTR, SDTR, and Tag Queuing. If the feature | ||
17659 | * is enabled in the EEPROM and the device supports the | ||
17660 | * feature, then enable it in the microcode. | ||
17661 | */ | ||
17662 | |||
17663 | tidmask = ADV_TID_TO_TIDMASK(tid); | ||
17664 | |||
17665 | /* | ||
17666 | * Wide Transfers | ||
17667 | * | ||
17668 | * If the EEPROM enabled WDTR for the device and the device | ||
17669 | * supports wide bus (16 bit) transfers, then turn on the | ||
17670 | * device's 'wdtr_able' bit and write the new value to the | ||
17671 | * microcode. | ||
17672 | */ | ||
17673 | if ((asc_dvc->wdtr_able & tidmask) && ADV_INQ_WIDE16(inq)) { | ||
17674 | AdvReadWordLram(iop_base, ASC_MC_WDTR_ABLE, cfg_word); | ||
17675 | if ((cfg_word & tidmask) == 0) { | ||
17676 | cfg_word |= tidmask; | ||
17677 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_ABLE, | ||
17678 | cfg_word); | ||
17679 | |||
17680 | /* | ||
17681 | * Clear the microcode "SDTR negotiation" and "WDTR | ||
17682 | * negotiation" done indicators for the target to cause | ||
17683 | * it to negotiate with the new setting set above. | ||
17684 | * WDTR when accepted causes the target to enter | ||
17685 | * asynchronous mode, so SDTR must be negotiated. | ||
17686 | */ | ||
17687 | AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, | ||
17688 | cfg_word); | ||
17689 | cfg_word &= ~tidmask; | ||
17690 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, | ||
17691 | cfg_word); | ||
17692 | AdvReadWordLram(iop_base, ASC_MC_WDTR_DONE, | ||
17693 | cfg_word); | ||
17694 | cfg_word &= ~tidmask; | ||
17695 | AdvWriteWordLram(iop_base, ASC_MC_WDTR_DONE, | ||
17696 | cfg_word); | ||
17697 | } | ||
17698 | } | ||
17699 | |||
17700 | /* | ||
17701 | * Synchronous Transfers | ||
17702 | * | ||
17703 | * If the EEPROM enabled SDTR for the device and the device | ||
17704 | * supports synchronous transfers, then turn on the device's | ||
17705 | * 'sdtr_able' bit. Write the new value to the microcode. | ||
17706 | */ | ||
17707 | if ((asc_dvc->sdtr_able & tidmask) && ADV_INQ_SYNC(inq)) { | ||
17708 | AdvReadWordLram(iop_base, ASC_MC_SDTR_ABLE, cfg_word); | ||
17709 | if ((cfg_word & tidmask) == 0) { | ||
17710 | cfg_word |= tidmask; | ||
17711 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_ABLE, | ||
17712 | cfg_word); | ||
17713 | |||
17714 | /* | ||
17715 | * Clear the microcode "SDTR negotiation" done indicator | ||
17716 | * for the target to cause it to negotiate with the new | ||
17717 | * setting set above. | ||
17718 | */ | ||
17719 | AdvReadWordLram(iop_base, ASC_MC_SDTR_DONE, | ||
17720 | cfg_word); | ||
17721 | cfg_word &= ~tidmask; | ||
17722 | AdvWriteWordLram(iop_base, ASC_MC_SDTR_DONE, | ||
17723 | cfg_word); | ||
17724 | } | ||
17725 | } | ||
17726 | /* | ||
17727 | * If the Inquiry data included enough space for the SPI-3 | ||
17728 | * Clocking field, then check if DT mode is supported. | ||
17729 | */ | ||
17730 | if (asc_dvc->chip_type == ADV_CHIP_ASC38C1600 && | ||
17731 | (scsiq->cdb[4] >= 57 || | ||
17732 | (scsiq->cdb[4] - le32_to_cpu(scsiq->data_cnt)) >= 57)) { | ||
17733 | /* | ||
17734 | * PPR (Parallel Protocol Request) Capable | ||
17735 | * | ||
17736 | * If the device supports DT mode, then it must be PPR capable. | ||
17737 | * The PPR message will be used in place of the SDTR and WDTR | ||
17738 | * messages to negotiate synchronous speed and offset, transfer | ||
17739 | * width, and protocol options. | ||
17740 | */ | ||
17741 | if (ADV_INQ_CLOCKING(inq) & ADV_INQ_CLOCKING_DT_ONLY) { | ||
17742 | AdvReadWordLram(iop_base, ASC_MC_PPR_ABLE, | ||
17743 | asc_dvc->ppr_able); | ||
17744 | asc_dvc->ppr_able |= tidmask; | ||
17745 | AdvWriteWordLram(iop_base, ASC_MC_PPR_ABLE, | ||
17746 | asc_dvc->ppr_able); | ||
17747 | } | ||
17748 | } | ||
17749 | |||
17750 | /* | ||
17751 | * If the EEPROM enabled Tag Queuing for the device and the | ||
17752 | * device supports Tag Queueing, then turn on the device's | ||
17753 | * 'tagqng_enable' bit in the microcode and set the microcode | ||
17754 | * maximum command count to the ADV_DVC_VAR 'max_dvc_qng' | ||
17755 | * value. | ||
17756 | * | ||
17757 | * Tag Queuing is disabled for the BIOS which runs in polled | ||
17758 | * mode and would see no benefit from Tag Queuing. Also by | ||
17759 | * disabling Tag Queuing in the BIOS devices with Tag Queuing | ||
17760 | * bugs will at least work with the BIOS. | ||
17761 | */ | ||
17762 | if ((asc_dvc->tagqng_able & tidmask) && ADV_INQ_CMD_QUEUE(inq)) { | ||
17763 | AdvReadWordLram(iop_base, ASC_MC_TAGQNG_ABLE, cfg_word); | ||
17764 | cfg_word |= tidmask; | ||
17765 | AdvWriteWordLram(iop_base, ASC_MC_TAGQNG_ABLE, | ||
17766 | cfg_word); | ||
17767 | |||
17768 | AdvWriteByteLram(iop_base, | ||
17769 | ASC_MC_NUMBER_OF_MAX_CMD + tid, | ||
17770 | asc_dvc->max_dvc_qng); | ||
17771 | } | ||
17772 | } | 13390 | } |
17773 | } | 13391 | } |
17774 | 13392 | ||
17775 | MODULE_LICENSE("Dual BSD/GPL"); | 13393 | static int __devinit advansys_board_found(struct Scsi_Host *shost, |
17776 | 13394 | unsigned int iop, int bus_type) | |
17777 | static struct Scsi_Host *__devinit | ||
17778 | advansys_board_found(int iop, struct device *dev, int bus_type) | ||
17779 | { | 13395 | { |
17780 | struct Scsi_Host *shost; | 13396 | struct pci_dev *pdev; |
17781 | struct pci_dev *pdev = bus_type == ASC_IS_PCI ? to_pci_dev(dev) : NULL; | 13397 | struct asc_board *boardp = shost_priv(shost); |
17782 | asc_board_t *boardp; | ||
17783 | ASC_DVC_VAR *asc_dvc_varp = NULL; | 13398 | ASC_DVC_VAR *asc_dvc_varp = NULL; |
17784 | ADV_DVC_VAR *adv_dvc_varp = NULL; | 13399 | ADV_DVC_VAR *adv_dvc_varp = NULL; |
17785 | adv_sgblk_t *sgp = NULL; | 13400 | int share_irq, warn_code, ret; |
17786 | int share_irq = FALSE; | ||
17787 | int iolen = 0; | ||
17788 | ADV_PADDR pci_memory_address; | ||
17789 | int warn_code, err_code; | ||
17790 | int ret; | ||
17791 | 13401 | ||
17792 | /* | 13402 | pdev = (bus_type == ASC_IS_PCI) ? to_pci_dev(boardp->dev) : NULL; |
17793 | * Adapter found. | ||
17794 | * | ||
17795 | * Register the adapter, get its configuration, and | ||
17796 | * initialize it. | ||
17797 | */ | ||
17798 | ASC_DBG(2, "advansys_board_found: scsi_register()\n"); | ||
17799 | shost = scsi_register(&driver_template, sizeof(asc_board_t)); | ||
17800 | |||
17801 | if (!shost) | ||
17802 | return NULL; | ||
17803 | |||
17804 | /* Save a pointer to the Scsi_Host of each board found. */ | ||
17805 | asc_host[asc_board_count++] = shost; | ||
17806 | |||
17807 | /* Initialize private per board data */ | ||
17808 | boardp = ASC_BOARDP(shost); | ||
17809 | memset(boardp, 0, sizeof(asc_board_t)); | ||
17810 | boardp->id = asc_board_count - 1; | ||
17811 | |||
17812 | /* Initialize spinlock. */ | ||
17813 | spin_lock_init(&boardp->lock); | ||
17814 | |||
17815 | /* | ||
17816 | * Handle both narrow and wide boards. | ||
17817 | * | ||
17818 | * If a Wide board was detected, set the board structure | ||
17819 | * wide board flag. Set-up the board structure based on | ||
17820 | * the board type. | ||
17821 | */ | ||
17822 | #ifdef CONFIG_PCI | ||
17823 | if (bus_type == ASC_IS_PCI && | ||
17824 | (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW || | ||
17825 | pdev->device == PCI_DEVICE_ID_38C0800_REV1 || | ||
17826 | pdev->device == PCI_DEVICE_ID_38C1600_REV1)) { | ||
17827 | boardp->flags |= ASC_IS_WIDE_BOARD; | ||
17828 | } | ||
17829 | #endif /* CONFIG_PCI */ | ||
17830 | 13403 | ||
17831 | if (ASC_NARROW_BOARD(boardp)) { | 13404 | if (ASC_NARROW_BOARD(boardp)) { |
17832 | ASC_DBG(1, "advansys_board_found: narrow board\n"); | 13405 | ASC_DBG(1, "narrow board\n"); |
17833 | asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; | 13406 | asc_dvc_varp = &boardp->dvc_var.asc_dvc_var; |
17834 | asc_dvc_varp->bus_type = bus_type; | 13407 | asc_dvc_varp->bus_type = bus_type; |
17835 | asc_dvc_varp->drv_ptr = boardp; | 13408 | asc_dvc_varp->drv_ptr = boardp; |
17836 | asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg; | 13409 | asc_dvc_varp->cfg = &boardp->dvc_cfg.asc_dvc_cfg; |
17837 | asc_dvc_varp->cfg->overrun_buf = &overrun_buf[0]; | ||
17838 | asc_dvc_varp->iop_base = iop; | 13410 | asc_dvc_varp->iop_base = iop; |
17839 | asc_dvc_varp->isr_callback = asc_isr_callback; | ||
17840 | } else { | 13411 | } else { |
17841 | ASC_DBG(1, "advansys_board_found: wide board\n"); | 13412 | #ifdef CONFIG_PCI |
17842 | adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; | 13413 | adv_dvc_varp = &boardp->dvc_var.adv_dvc_var; |
17843 | adv_dvc_varp->drv_ptr = boardp; | 13414 | adv_dvc_varp->drv_ptr = boardp; |
17844 | adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg; | 13415 | adv_dvc_varp->cfg = &boardp->dvc_cfg.adv_dvc_cfg; |
17845 | adv_dvc_varp->isr_callback = adv_isr_callback; | ||
17846 | adv_dvc_varp->async_callback = adv_async_callback; | ||
17847 | #ifdef CONFIG_PCI | ||
17848 | if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) { | 13416 | if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW) { |
17849 | ASC_DBG(1, "advansys_board_found: ASC-3550\n"); | 13417 | ASC_DBG(1, "wide board ASC-3550\n"); |
17850 | adv_dvc_varp->chip_type = ADV_CHIP_ASC3550; | 13418 | adv_dvc_varp->chip_type = ADV_CHIP_ASC3550; |
17851 | } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) { | 13419 | } else if (pdev->device == PCI_DEVICE_ID_38C0800_REV1) { |
17852 | ASC_DBG(1, "advansys_board_found: ASC-38C0800\n"); | 13420 | ASC_DBG(1, "wide board ASC-38C0800\n"); |
17853 | adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800; | 13421 | adv_dvc_varp->chip_type = ADV_CHIP_ASC38C0800; |
17854 | } else { | 13422 | } else { |
17855 | ASC_DBG(1, "advansys_board_found: ASC-38C1600\n"); | 13423 | ASC_DBG(1, "wide board ASC-38C1600\n"); |
17856 | adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600; | 13424 | adv_dvc_varp->chip_type = ADV_CHIP_ASC38C1600; |
17857 | } | 13425 | } |
17858 | #endif /* CONFIG_PCI */ | ||
17859 | 13426 | ||
17860 | /* | 13427 | boardp->asc_n_io_port = pci_resource_len(pdev, 1); |
17861 | * Map the board's registers into virtual memory for | 13428 | boardp->ioremap_addr = ioremap(pci_resource_start(pdev, 1), |
17862 | * PCI slave access. Only memory accesses are used to | 13429 | boardp->asc_n_io_port); |
17863 | * access the board's registers. | 13430 | if (!boardp->ioremap_addr) { |
17864 | * | 13431 | shost_printk(KERN_ERR, shost, "ioremap(%lx, %d) " |
17865 | * Note: The PCI register base address is not always | 13432 | "returned NULL\n", |
17866 | * page aligned, but the address passed to ioremap() | 13433 | (long)pci_resource_start(pdev, 1), |
17867 | * must be page aligned. It is guaranteed that the | 13434 | boardp->asc_n_io_port); |
17868 | * PCI register base address will not cross a page | 13435 | ret = -ENODEV; |
17869 | * boundary. | 13436 | goto err_shost; |
17870 | */ | ||
17871 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { | ||
17872 | iolen = ADV_3550_IOLEN; | ||
17873 | } else if (adv_dvc_varp->chip_type == ADV_CHIP_ASC38C0800) { | ||
17874 | iolen = ADV_38C0800_IOLEN; | ||
17875 | } else { | ||
17876 | iolen = ADV_38C1600_IOLEN; | ||
17877 | } | ||
17878 | #ifdef CONFIG_PCI | ||
17879 | pci_memory_address = pci_resource_start(pdev, 1); | ||
17880 | ASC_DBG1(1, | ||
17881 | "advansys_board_found: pci_memory_address: 0x%lx\n", | ||
17882 | (ulong)pci_memory_address); | ||
17883 | if ((boardp->ioremap_addr = | ||
17884 | ioremap(pci_memory_address & PAGE_MASK, PAGE_SIZE)) == 0) { | ||
17885 | ASC_PRINT3 | ||
17886 | ("advansys_board_found: board %d: ioremap(%x, %d) returned NULL\n", | ||
17887 | boardp->id, pci_memory_address, iolen); | ||
17888 | scsi_unregister(shost); | ||
17889 | asc_board_count--; | ||
17890 | return NULL; | ||
17891 | } | 13437 | } |
17892 | ASC_DBG1(1, | 13438 | adv_dvc_varp->iop_base = (AdvPortAddr)boardp->ioremap_addr; |
17893 | "advansys_board_found: ioremap_addr: 0x%lx\n", | 13439 | ASC_DBG(1, "iop_base: 0x%p\n", adv_dvc_varp->iop_base); |
17894 | (ulong)boardp->ioremap_addr); | ||
17895 | adv_dvc_varp->iop_base = (AdvPortAddr) | ||
17896 | (boardp->ioremap_addr + | ||
17897 | (pci_memory_address - (pci_memory_address & PAGE_MASK))); | ||
17898 | ASC_DBG1(1, | ||
17899 | "advansys_board_found: iop_base: 0x%lx\n", | ||
17900 | adv_dvc_varp->iop_base); | ||
17901 | #endif /* CONFIG_PCI */ | ||
17902 | 13440 | ||
17903 | /* | 13441 | /* |
17904 | * Even though it isn't used to access wide boards, other | 13442 | * Even though it isn't used to access wide boards, other |
@@ -17907,9 +13445,9 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
17907 | */ | 13445 | */ |
17908 | boardp->ioport = iop; | 13446 | boardp->ioport = iop; |
17909 | 13447 | ||
17910 | ASC_DBG2(1, | 13448 | ASC_DBG(1, "iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n", |
17911 | "advansys_board_found: iopb_chip_id_1 0x%x, iopw_chip_id_0 0x%x\n", | 13449 | (ushort)inp(iop + 1), (ushort)inpw(iop)); |
17912 | (ushort)inp(iop + 1), (ushort)inpw(iop)); | 13450 | #endif /* CONFIG_PCI */ |
17913 | } | 13451 | } |
17914 | 13452 | ||
17915 | #ifdef CONFIG_PROC_FS | 13453 | #ifdef CONFIG_PROC_FS |
@@ -17917,18 +13455,16 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
17917 | * Allocate buffer for printing information from | 13455 | * Allocate buffer for printing information from |
17918 | * /proc/scsi/advansys/[0...]. | 13456 | * /proc/scsi/advansys/[0...]. |
17919 | */ | 13457 | */ |
17920 | if ((boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_ATOMIC)) == NULL) { | 13458 | boardp->prtbuf = kmalloc(ASC_PRTBUF_SIZE, GFP_KERNEL); |
17921 | ASC_PRINT3 | 13459 | if (!boardp->prtbuf) { |
17922 | ("advansys_board_found: board %d: kmalloc(%d, %d) returned NULL\n", | 13460 | shost_printk(KERN_ERR, shost, "kmalloc(%d) returned NULL\n", |
17923 | boardp->id, ASC_PRTBUF_SIZE, GFP_ATOMIC); | 13461 | ASC_PRTBUF_SIZE); |
17924 | scsi_unregister(shost); | 13462 | ret = -ENOMEM; |
17925 | asc_board_count--; | 13463 | goto err_unmap; |
17926 | return NULL; | ||
17927 | } | 13464 | } |
17928 | #endif /* CONFIG_PROC_FS */ | 13465 | #endif /* CONFIG_PROC_FS */ |
17929 | 13466 | ||
17930 | if (ASC_NARROW_BOARD(boardp)) { | 13467 | if (ASC_NARROW_BOARD(boardp)) { |
17931 | asc_dvc_varp->cfg->dev = dev; | ||
17932 | /* | 13468 | /* |
17933 | * Set the board bus type and PCI IRQ before | 13469 | * Set the board bus type and PCI IRQ before |
17934 | * calling AscInitGetConfig(). | 13470 | * calling AscInitGetConfig(). |
@@ -17937,127 +13473,56 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
17937 | #ifdef CONFIG_ISA | 13473 | #ifdef CONFIG_ISA |
17938 | case ASC_IS_ISA: | 13474 | case ASC_IS_ISA: |
17939 | shost->unchecked_isa_dma = TRUE; | 13475 | shost->unchecked_isa_dma = TRUE; |
17940 | share_irq = FALSE; | 13476 | share_irq = 0; |
17941 | break; | 13477 | break; |
17942 | case ASC_IS_VL: | 13478 | case ASC_IS_VL: |
17943 | shost->unchecked_isa_dma = FALSE; | 13479 | shost->unchecked_isa_dma = FALSE; |
17944 | share_irq = FALSE; | 13480 | share_irq = 0; |
17945 | break; | 13481 | break; |
17946 | case ASC_IS_EISA: | 13482 | case ASC_IS_EISA: |
17947 | shost->unchecked_isa_dma = FALSE; | 13483 | shost->unchecked_isa_dma = FALSE; |
17948 | share_irq = TRUE; | 13484 | share_irq = IRQF_SHARED; |
17949 | break; | 13485 | break; |
17950 | #endif /* CONFIG_ISA */ | 13486 | #endif /* CONFIG_ISA */ |
17951 | #ifdef CONFIG_PCI | 13487 | #ifdef CONFIG_PCI |
17952 | case ASC_IS_PCI: | 13488 | case ASC_IS_PCI: |
17953 | shost->irq = asc_dvc_varp->irq_no = pdev->irq; | ||
17954 | asc_dvc_varp->cfg->pci_slot_info = | ||
17955 | ASC_PCI_MKID(pdev->bus->number, | ||
17956 | PCI_SLOT(pdev->devfn), | ||
17957 | PCI_FUNC(pdev->devfn)); | ||
17958 | shost->unchecked_isa_dma = FALSE; | 13489 | shost->unchecked_isa_dma = FALSE; |
17959 | share_irq = TRUE; | 13490 | share_irq = IRQF_SHARED; |
17960 | break; | 13491 | break; |
17961 | #endif /* CONFIG_PCI */ | 13492 | #endif /* CONFIG_PCI */ |
17962 | default: | 13493 | default: |
17963 | ASC_PRINT2 | 13494 | shost_printk(KERN_ERR, shost, "unknown adapter type: " |
17964 | ("advansys_board_found: board %d: unknown adapter type: %d\n", | 13495 | "%d\n", asc_dvc_varp->bus_type); |
17965 | boardp->id, asc_dvc_varp->bus_type); | ||
17966 | shost->unchecked_isa_dma = TRUE; | 13496 | shost->unchecked_isa_dma = TRUE; |
17967 | share_irq = FALSE; | 13497 | share_irq = 0; |
17968 | break; | 13498 | break; |
17969 | } | 13499 | } |
17970 | } else { | ||
17971 | adv_dvc_varp->cfg->dev = dev; | ||
17972 | /* | ||
17973 | * For Wide boards set PCI information before calling | ||
17974 | * AdvInitGetConfig(). | ||
17975 | */ | ||
17976 | #ifdef CONFIG_PCI | ||
17977 | shost->irq = adv_dvc_varp->irq_no = pdev->irq; | ||
17978 | adv_dvc_varp->cfg->pci_slot_info = | ||
17979 | ASC_PCI_MKID(pdev->bus->number, | ||
17980 | PCI_SLOT(pdev->devfn), | ||
17981 | PCI_FUNC(pdev->devfn)); | ||
17982 | shost->unchecked_isa_dma = FALSE; | ||
17983 | share_irq = TRUE; | ||
17984 | #endif /* CONFIG_PCI */ | ||
17985 | } | ||
17986 | 13500 | ||
17987 | /* | ||
17988 | * Read the board configuration. | ||
17989 | */ | ||
17990 | if (ASC_NARROW_BOARD(boardp)) { | ||
17991 | /* | 13501 | /* |
17992 | * NOTE: AscInitGetConfig() may change the board's | 13502 | * NOTE: AscInitGetConfig() may change the board's |
17993 | * bus_type value. The bus_type value should no | 13503 | * bus_type value. The bus_type value should no |
17994 | * longer be used. If the bus_type field must be | 13504 | * longer be used. If the bus_type field must be |
17995 | * referenced only use the bit-wise AND operator "&". | 13505 | * referenced only use the bit-wise AND operator "&". |
17996 | */ | 13506 | */ |
17997 | ASC_DBG(2, "advansys_board_found: AscInitGetConfig()\n"); | 13507 | ASC_DBG(2, "AscInitGetConfig()\n"); |
17998 | switch (ret = AscInitGetConfig(asc_dvc_varp)) { | 13508 | ret = AscInitGetConfig(shost) ? -ENODEV : 0; |
17999 | case 0: /* No error */ | ||
18000 | break; | ||
18001 | case ASC_WARN_IO_PORT_ROTATE: | ||
18002 | ASC_PRINT1 | ||
18003 | ("AscInitGetConfig: board %d: I/O port address modified\n", | ||
18004 | boardp->id); | ||
18005 | break; | ||
18006 | case ASC_WARN_AUTO_CONFIG: | ||
18007 | ASC_PRINT1 | ||
18008 | ("AscInitGetConfig: board %d: I/O port increment switch enabled\n", | ||
18009 | boardp->id); | ||
18010 | break; | ||
18011 | case ASC_WARN_EEPROM_CHKSUM: | ||
18012 | ASC_PRINT1 | ||
18013 | ("AscInitGetConfig: board %d: EEPROM checksum error\n", | ||
18014 | boardp->id); | ||
18015 | break; | ||
18016 | case ASC_WARN_IRQ_MODIFIED: | ||
18017 | ASC_PRINT1 | ||
18018 | ("AscInitGetConfig: board %d: IRQ modified\n", | ||
18019 | boardp->id); | ||
18020 | break; | ||
18021 | case ASC_WARN_CMD_QNG_CONFLICT: | ||
18022 | ASC_PRINT1 | ||
18023 | ("AscInitGetConfig: board %d: tag queuing enabled w/o disconnects\n", | ||
18024 | boardp->id); | ||
18025 | break; | ||
18026 | default: | ||
18027 | ASC_PRINT2 | ||
18028 | ("AscInitGetConfig: board %d: unknown warning: 0x%x\n", | ||
18029 | boardp->id, ret); | ||
18030 | break; | ||
18031 | } | ||
18032 | if ((err_code = asc_dvc_varp->err_code) != 0) { | ||
18033 | ASC_PRINT3 | ||
18034 | ("AscInitGetConfig: board %d error: init_state 0x%x, err_code 0x%x\n", | ||
18035 | boardp->id, | ||
18036 | asc_dvc_varp->init_state, asc_dvc_varp->err_code); | ||
18037 | } | ||
18038 | } else { | 13509 | } else { |
18039 | ASC_DBG(2, "advansys_board_found: AdvInitGetConfig()\n"); | 13510 | #ifdef CONFIG_PCI |
18040 | if ((ret = AdvInitGetConfig(adv_dvc_varp)) != 0) { | 13511 | /* |
18041 | ASC_PRINT2 | 13512 | * For Wide boards set PCI information before calling |
18042 | ("AdvInitGetConfig: board %d: warning: 0x%x\n", | 13513 | * AdvInitGetConfig(). |
18043 | boardp->id, ret); | 13514 | */ |
18044 | } | 13515 | shost->unchecked_isa_dma = FALSE; |
18045 | if ((err_code = adv_dvc_varp->err_code) != 0) { | 13516 | share_irq = IRQF_SHARED; |
18046 | ASC_PRINT2 | 13517 | ASC_DBG(2, "AdvInitGetConfig()\n"); |
18047 | ("AdvInitGetConfig: board %d error: err_code 0x%x\n", | ||
18048 | boardp->id, adv_dvc_varp->err_code); | ||
18049 | } | ||
18050 | } | ||
18051 | 13518 | ||
18052 | if (err_code != 0) { | 13519 | ret = AdvInitGetConfig(pdev, shost) ? -ENODEV : 0; |
18053 | #ifdef CONFIG_PROC_FS | 13520 | #endif /* CONFIG_PCI */ |
18054 | kfree(boardp->prtbuf); | ||
18055 | #endif /* CONFIG_PROC_FS */ | ||
18056 | scsi_unregister(shost); | ||
18057 | asc_board_count--; | ||
18058 | return NULL; | ||
18059 | } | 13521 | } |
18060 | 13522 | ||
13523 | if (ret) | ||
13524 | goto err_free_proc; | ||
13525 | |||
18061 | /* | 13526 | /* |
18062 | * Save the EEPROM configuration so that it can be displayed | 13527 | * Save the EEPROM configuration so that it can be displayed |
18063 | * from /proc/scsi/advansys/[0...]. | 13528 | * from /proc/scsi/advansys/[0...]. |
@@ -18098,61 +13563,10 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
18098 | /* | 13563 | /* |
18099 | * Modify board configuration. | 13564 | * Modify board configuration. |
18100 | */ | 13565 | */ |
18101 | ASC_DBG(2, "advansys_board_found: AscInitSetConfig()\n"); | 13566 | ASC_DBG(2, "AscInitSetConfig()\n"); |
18102 | switch (ret = AscInitSetConfig(asc_dvc_varp)) { | 13567 | ret = AscInitSetConfig(pdev, shost) ? -ENODEV : 0; |
18103 | case 0: /* No error. */ | 13568 | if (ret) |
18104 | break; | 13569 | goto err_free_proc; |
18105 | case ASC_WARN_IO_PORT_ROTATE: | ||
18106 | ASC_PRINT1 | ||
18107 | ("AscInitSetConfig: board %d: I/O port address modified\n", | ||
18108 | boardp->id); | ||
18109 | break; | ||
18110 | case ASC_WARN_AUTO_CONFIG: | ||
18111 | ASC_PRINT1 | ||
18112 | ("AscInitSetConfig: board %d: I/O port increment switch enabled\n", | ||
18113 | boardp->id); | ||
18114 | break; | ||
18115 | case ASC_WARN_EEPROM_CHKSUM: | ||
18116 | ASC_PRINT1 | ||
18117 | ("AscInitSetConfig: board %d: EEPROM checksum error\n", | ||
18118 | boardp->id); | ||
18119 | break; | ||
18120 | case ASC_WARN_IRQ_MODIFIED: | ||
18121 | ASC_PRINT1 | ||
18122 | ("AscInitSetConfig: board %d: IRQ modified\n", | ||
18123 | boardp->id); | ||
18124 | break; | ||
18125 | case ASC_WARN_CMD_QNG_CONFLICT: | ||
18126 | ASC_PRINT1 | ||
18127 | ("AscInitSetConfig: board %d: tag queuing w/o disconnects\n", | ||
18128 | boardp->id); | ||
18129 | break; | ||
18130 | default: | ||
18131 | ASC_PRINT2 | ||
18132 | ("AscInitSetConfig: board %d: unknown warning: 0x%x\n", | ||
18133 | boardp->id, ret); | ||
18134 | break; | ||
18135 | } | ||
18136 | if (asc_dvc_varp->err_code != 0) { | ||
18137 | ASC_PRINT3 | ||
18138 | ("AscInitSetConfig: board %d error: init_state 0x%x, err_code 0x%x\n", | ||
18139 | boardp->id, | ||
18140 | asc_dvc_varp->init_state, asc_dvc_varp->err_code); | ||
18141 | #ifdef CONFIG_PROC_FS | ||
18142 | kfree(boardp->prtbuf); | ||
18143 | #endif /* CONFIG_PROC_FS */ | ||
18144 | scsi_unregister(shost); | ||
18145 | asc_board_count--; | ||
18146 | return NULL; | ||
18147 | } | ||
18148 | |||
18149 | /* | ||
18150 | * Finish initializing the 'Scsi_Host' structure. | ||
18151 | */ | ||
18152 | /* AscInitSetConfig() will set the IRQ for non-PCI boards. */ | ||
18153 | if ((asc_dvc_varp->bus_type & ASC_IS_PCI) == 0) { | ||
18154 | shost->irq = asc_dvc_varp->irq_no; | ||
18155 | } | ||
18156 | } else { | 13570 | } else { |
18157 | ADVEEP_3550_CONFIG *ep_3550; | 13571 | ADVEEP_3550_CONFIG *ep_3550; |
18158 | ADVEEP_38C0800_CONFIG *ep_38C0800; | 13572 | ADVEEP_38C0800_CONFIG *ep_38C0800; |
@@ -18246,11 +13660,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
18246 | */ | 13660 | */ |
18247 | boardp->init_tidmask |= | 13661 | boardp->init_tidmask |= |
18248 | ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id); | 13662 | ADV_TID_TO_TIDMASK(adv_dvc_varp->chip_scsi_id); |
18249 | |||
18250 | /* | ||
18251 | * Finish initializing the 'Scsi_Host' structure. | ||
18252 | */ | ||
18253 | shost->irq = adv_dvc_varp->irq_no; | ||
18254 | } | 13663 | } |
18255 | 13664 | ||
18256 | /* | 13665 | /* |
@@ -18262,6 +13671,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
18262 | if (ASC_NARROW_BOARD(boardp)) { | 13671 | if (ASC_NARROW_BOARD(boardp)) { |
18263 | shost->max_id = ASC_MAX_TID + 1; | 13672 | shost->max_id = ASC_MAX_TID + 1; |
18264 | shost->max_lun = ASC_MAX_LUN + 1; | 13673 | shost->max_lun = ASC_MAX_LUN + 1; |
13674 | shost->max_cmd_len = ASC_MAX_CDB_LEN; | ||
18265 | 13675 | ||
18266 | shost->io_port = asc_dvc_varp->iop_base; | 13676 | shost->io_port = asc_dvc_varp->iop_base; |
18267 | boardp->asc_n_io_port = ASC_IOADR_GAP; | 13677 | boardp->asc_n_io_port = ASC_IOADR_GAP; |
@@ -18272,6 +13682,7 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
18272 | } else { | 13682 | } else { |
18273 | shost->max_id = ADV_MAX_TID + 1; | 13683 | shost->max_id = ADV_MAX_TID + 1; |
18274 | shost->max_lun = ADV_MAX_LUN + 1; | 13684 | shost->max_lun = ADV_MAX_LUN + 1; |
13685 | shost->max_cmd_len = ADV_MAX_CDB_LEN; | ||
18275 | 13686 | ||
18276 | /* | 13687 | /* |
18277 | * Save the I/O Port address and length even though | 13688 | * Save the I/O Port address and length even though |
@@ -18280,7 +13691,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
18280 | * PCI Memory Mapped I/O. | 13691 | * PCI Memory Mapped I/O. |
18281 | */ | 13692 | */ |
18282 | shost->io_port = iop; | 13693 | shost->io_port = iop; |
18283 | boardp->asc_n_io_port = iolen; | ||
18284 | 13694 | ||
18285 | shost->this_id = adv_dvc_varp->chip_scsi_id; | 13695 | shost->this_id = adv_dvc_varp->chip_scsi_id; |
18286 | 13696 | ||
@@ -18289,15 +13699,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
18289 | } | 13699 | } |
18290 | 13700 | ||
18291 | /* | 13701 | /* |
18292 | * 'n_io_port' currently is one byte. | ||
18293 | * | ||
18294 | * Set a value to 'n_io_port', but never referenced it because | ||
18295 | * it may be truncated. | ||
18296 | */ | ||
18297 | shost->n_io_port = boardp->asc_n_io_port <= 255 ? | ||
18298 | boardp->asc_n_io_port : 255; | ||
18299 | |||
18300 | /* | ||
18301 | * Following v1.3.89, 'cmd_per_lun' is no longer needed | 13702 | * Following v1.3.89, 'cmd_per_lun' is no longer needed |
18302 | * and should be set to zero. | 13703 | * and should be set to zero. |
18303 | * | 13704 | * |
@@ -18343,14 +13744,12 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
18343 | shost->sg_tablesize = SG_ALL; | 13744 | shost->sg_tablesize = SG_ALL; |
18344 | } | 13745 | } |
18345 | 13746 | ||
18346 | ASC_DBG1(1, "advansys_board_found: sg_tablesize: %d\n", shost->sg_tablesize); | 13747 | ASC_DBG(1, "sg_tablesize: %d\n", shost->sg_tablesize); |
18347 | 13748 | ||
18348 | /* BIOS start address. */ | 13749 | /* BIOS start address. */ |
18349 | if (ASC_NARROW_BOARD(boardp)) { | 13750 | if (ASC_NARROW_BOARD(boardp)) { |
18350 | shost->base = ((ulong) | 13751 | shost->base = AscGetChipBiosAddress(asc_dvc_varp->iop_base, |
18351 | AscGetChipBiosAddress(asc_dvc_varp-> | 13752 | asc_dvc_varp->bus_type); |
18352 | iop_base, | ||
18353 | asc_dvc_varp->bus_type)); | ||
18354 | } else { | 13753 | } else { |
18355 | /* | 13754 | /* |
18356 | * Fill-in BIOS board variables. The Wide BIOS saves | 13755 | * Fill-in BIOS board variables. The Wide BIOS saves |
@@ -18365,12 +13764,10 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
18365 | AdvReadWordLram(adv_dvc_varp->iop_base, | 13764 | AdvReadWordLram(adv_dvc_varp->iop_base, |
18366 | BIOS_CODELEN, boardp->bios_codelen); | 13765 | BIOS_CODELEN, boardp->bios_codelen); |
18367 | 13766 | ||
18368 | ASC_DBG2(1, | 13767 | ASC_DBG(1, "bios_signature 0x%x, bios_version 0x%x\n", |
18369 | "advansys_board_found: bios_signature 0x%x, bios_version 0x%x\n", | ||
18370 | boardp->bios_signature, boardp->bios_version); | 13768 | boardp->bios_signature, boardp->bios_version); |
18371 | 13769 | ||
18372 | ASC_DBG2(1, | 13770 | ASC_DBG(1, "bios_codeseg 0x%x, bios_codelen 0x%x\n", |
18373 | "advansys_board_found: bios_codeseg 0x%x, bios_codelen 0x%x\n", | ||
18374 | boardp->bios_codeseg, boardp->bios_codelen); | 13771 | boardp->bios_codeseg, boardp->bios_codelen); |
18375 | 13772 | ||
18376 | /* | 13773 | /* |
@@ -18392,30 +13789,6 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
18392 | * Register Board Resources - I/O Port, DMA, IRQ | 13789 | * Register Board Resources - I/O Port, DMA, IRQ |
18393 | */ | 13790 | */ |
18394 | 13791 | ||
18395 | /* | ||
18396 | * Register I/O port range. | ||
18397 | * | ||
18398 | * For Wide boards the I/O ports are not used to access | ||
18399 | * the board, but request the region anyway. | ||
18400 | * | ||
18401 | * 'shost->n_io_port' is not referenced, because it may be truncated. | ||
18402 | */ | ||
18403 | ASC_DBG2(2, | ||
18404 | "advansys_board_found: request_region port 0x%lx, len 0x%x\n", | ||
18405 | (ulong)shost->io_port, boardp->asc_n_io_port); | ||
18406 | if (request_region(shost->io_port, boardp->asc_n_io_port, | ||
18407 | "advansys") == NULL) { | ||
18408 | ASC_PRINT3 | ||
18409 | ("advansys_board_found: board %d: request_region() failed, port 0x%lx, len 0x%x\n", | ||
18410 | boardp->id, (ulong)shost->io_port, boardp->asc_n_io_port); | ||
18411 | #ifdef CONFIG_PROC_FS | ||
18412 | kfree(boardp->prtbuf); | ||
18413 | #endif /* CONFIG_PROC_FS */ | ||
18414 | scsi_unregister(shost); | ||
18415 | asc_board_count--; | ||
18416 | return NULL; | ||
18417 | } | ||
18418 | |||
18419 | /* Register DMA Channel for Narrow boards. */ | 13792 | /* Register DMA Channel for Narrow boards. */ |
18420 | shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */ | 13793 | shost->dma_channel = NO_ISA_DMA; /* Default to no ISA DMA. */ |
18421 | #ifdef CONFIG_ISA | 13794 | #ifdef CONFIG_ISA |
@@ -18423,19 +13796,12 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
18423 | /* Register DMA channel for ISA bus. */ | 13796 | /* Register DMA channel for ISA bus. */ |
18424 | if (asc_dvc_varp->bus_type & ASC_IS_ISA) { | 13797 | if (asc_dvc_varp->bus_type & ASC_IS_ISA) { |
18425 | shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel; | 13798 | shost->dma_channel = asc_dvc_varp->cfg->isa_dma_channel; |
18426 | if ((ret = | 13799 | ret = request_dma(shost->dma_channel, DRV_NAME); |
18427 | request_dma(shost->dma_channel, "advansys")) != 0) { | 13800 | if (ret) { |
18428 | ASC_PRINT3 | 13801 | shost_printk(KERN_ERR, shost, "request_dma() " |
18429 | ("advansys_board_found: board %d: request_dma() %d failed %d\n", | 13802 | "%d failed %d\n", |
18430 | boardp->id, shost->dma_channel, ret); | 13803 | shost->dma_channel, ret); |
18431 | release_region(shost->io_port, | 13804 | goto err_free_proc; |
18432 | boardp->asc_n_io_port); | ||
18433 | #ifdef CONFIG_PROC_FS | ||
18434 | kfree(boardp->prtbuf); | ||
18435 | #endif /* CONFIG_PROC_FS */ | ||
18436 | scsi_unregister(shost); | ||
18437 | asc_board_count--; | ||
18438 | return NULL; | ||
18439 | } | 13805 | } |
18440 | AscEnableIsaDma(shost->dma_channel); | 13806 | AscEnableIsaDma(shost->dma_channel); |
18441 | } | 13807 | } |
@@ -18443,573 +13809,392 @@ advansys_board_found(int iop, struct device *dev, int bus_type) | |||
18443 | #endif /* CONFIG_ISA */ | 13809 | #endif /* CONFIG_ISA */ |
18444 | 13810 | ||
18445 | /* Register IRQ Number. */ | 13811 | /* Register IRQ Number. */ |
18446 | ASC_DBG1(2, "advansys_board_found: request_irq() %d\n", shost->irq); | 13812 | ASC_DBG(2, "request_irq(%d, %p)\n", boardp->irq, shost); |
18447 | /* | 13813 | |
18448 | * If request_irq() fails with the IRQF_DISABLED flag set, | 13814 | ret = request_irq(boardp->irq, advansys_interrupt, share_irq, |
18449 | * then try again without the IRQF_DISABLED flag set. This | 13815 | DRV_NAME, shost); |
18450 | * allows IRQ sharing to work even with other drivers that | 13816 | |
18451 | * do not set the IRQF_DISABLED flag. | 13817 | if (ret) { |
18452 | * | ||
18453 | * If IRQF_DISABLED is not set, then interrupts are enabled | ||
18454 | * before the driver interrupt function is called. | ||
18455 | */ | ||
18456 | if (((ret = request_irq(shost->irq, advansys_interrupt, | ||
18457 | IRQF_DISABLED | (share_irq == | ||
18458 | TRUE ? | ||
18459 | IRQF_SHARED : | ||
18460 | 0), "advansys", boardp)) != 0) | ||
18461 | && | ||
18462 | ((ret = | ||
18463 | request_irq(shost->irq, advansys_interrupt, | ||
18464 | (share_irq == TRUE ? IRQF_SHARED : 0), | ||
18465 | "advansys", boardp)) != 0)) { | ||
18466 | if (ret == -EBUSY) { | 13818 | if (ret == -EBUSY) { |
18467 | ASC_PRINT2 | 13819 | shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x " |
18468 | ("advansys_board_found: board %d: request_irq(): IRQ 0x%x already in use.\n", | 13820 | "already in use\n", boardp->irq); |
18469 | boardp->id, shost->irq); | ||
18470 | } else if (ret == -EINVAL) { | 13821 | } else if (ret == -EINVAL) { |
18471 | ASC_PRINT2 | 13822 | shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x " |
18472 | ("advansys_board_found: board %d: request_irq(): IRQ 0x%x not valid.\n", | 13823 | "not valid\n", boardp->irq); |
18473 | boardp->id, shost->irq); | ||
18474 | } else { | 13824 | } else { |
18475 | ASC_PRINT3 | 13825 | shost_printk(KERN_ERR, shost, "request_irq(): IRQ 0x%x " |
18476 | ("advansys_board_found: board %d: request_irq(): IRQ 0x%x failed with %d\n", | 13826 | "failed with %d\n", boardp->irq, ret); |
18477 | boardp->id, shost->irq, ret); | ||
18478 | } | 13827 | } |
18479 | release_region(shost->io_port, boardp->asc_n_io_port); | 13828 | goto err_free_dma; |
18480 | iounmap(boardp->ioremap_addr); | ||
18481 | if (shost->dma_channel != NO_ISA_DMA) { | ||
18482 | free_dma(shost->dma_channel); | ||
18483 | } | ||
18484 | #ifdef CONFIG_PROC_FS | ||
18485 | kfree(boardp->prtbuf); | ||
18486 | #endif /* CONFIG_PROC_FS */ | ||
18487 | scsi_unregister(shost); | ||
18488 | asc_board_count--; | ||
18489 | return NULL; | ||
18490 | } | 13829 | } |
18491 | 13830 | ||
18492 | /* | 13831 | /* |
18493 | * Initialize board RISC chip and enable interrupts. | 13832 | * Initialize board RISC chip and enable interrupts. |
18494 | */ | 13833 | */ |
18495 | if (ASC_NARROW_BOARD(boardp)) { | 13834 | if (ASC_NARROW_BOARD(boardp)) { |
18496 | ASC_DBG(2, "advansys_board_found: AscInitAsc1000Driver()\n"); | 13835 | ASC_DBG(2, "AscInitAsc1000Driver()\n"); |
18497 | warn_code = AscInitAsc1000Driver(asc_dvc_varp); | 13836 | warn_code = AscInitAsc1000Driver(asc_dvc_varp); |
18498 | err_code = asc_dvc_varp->err_code; | ||
18499 | 13837 | ||
18500 | if (warn_code || err_code) { | 13838 | if (warn_code || asc_dvc_varp->err_code) { |
18501 | ASC_PRINT4 | 13839 | shost_printk(KERN_ERR, shost, "error: init_state 0x%x, " |
18502 | ("advansys_board_found: board %d error: init_state 0x%x, warn 0x%x, error 0x%x\n", | 13840 | "warn 0x%x, error 0x%x\n", |
18503 | boardp->id, | 13841 | asc_dvc_varp->init_state, warn_code, |
18504 | asc_dvc_varp->init_state, warn_code, err_code); | 13842 | asc_dvc_varp->err_code); |
13843 | if (asc_dvc_varp->err_code) | ||
13844 | ret = -ENODEV; | ||
18505 | } | 13845 | } |
18506 | } else { | 13846 | } else { |
18507 | ADV_CARR_T *carrp; | 13847 | if (advansys_wide_init_chip(shost)) |
18508 | int req_cnt = 0; | 13848 | ret = -ENODEV; |
18509 | adv_req_t *reqp = NULL; | 13849 | } |
18510 | int sg_cnt = 0; | ||
18511 | |||
18512 | /* | ||
18513 | * Allocate buffer carrier structures. The total size | ||
18514 | * is about 4 KB, so allocate all at once. | ||
18515 | */ | ||
18516 | carrp = (ADV_CARR_T *) kmalloc(ADV_CARRIER_BUFSIZE, GFP_ATOMIC); | ||
18517 | ASC_DBG1(1, "advansys_board_found: carrp 0x%lx\n", (ulong)carrp); | ||
18518 | |||
18519 | if (carrp == NULL) { | ||
18520 | goto kmalloc_error; | ||
18521 | } | ||
18522 | 13850 | ||
18523 | /* | 13851 | if (ret) |
18524 | * Allocate up to 'max_host_qng' request structures for | 13852 | goto err_free_wide_mem; |
18525 | * the Wide board. The total size is about 16 KB, so | ||
18526 | * allocate all at once. If the allocation fails decrement | ||
18527 | * and try again. | ||
18528 | */ | ||
18529 | for (req_cnt = adv_dvc_varp->max_host_qng; | ||
18530 | req_cnt > 0; req_cnt--) { | ||
18531 | 13853 | ||
18532 | reqp = (adv_req_t *) | 13854 | ASC_DBG_PRT_SCSI_HOST(2, shost); |
18533 | kmalloc(sizeof(adv_req_t) * req_cnt, GFP_ATOMIC); | ||
18534 | 13855 | ||
18535 | ASC_DBG3(1, | 13856 | ret = scsi_add_host(shost, boardp->dev); |
18536 | "advansys_board_found: reqp 0x%lx, req_cnt %d, bytes %lu\n", | 13857 | if (ret) |
18537 | (ulong)reqp, req_cnt, | 13858 | goto err_free_wide_mem; |
18538 | (ulong)sizeof(adv_req_t) * req_cnt); | ||
18539 | 13859 | ||
18540 | if (reqp != NULL) { | 13860 | scsi_scan_host(shost); |
18541 | break; | 13861 | return 0; |
18542 | } | ||
18543 | } | ||
18544 | if (reqp == NULL) { | ||
18545 | goto kmalloc_error; | ||
18546 | } | ||
18547 | 13862 | ||
18548 | /* | 13863 | err_free_wide_mem: |
18549 | * Allocate up to ADV_TOT_SG_BLOCK request structures for | 13864 | advansys_wide_free_mem(boardp); |
18550 | * the Wide board. Each structure is about 136 bytes. | 13865 | free_irq(boardp->irq, shost); |
18551 | */ | 13866 | err_free_dma: |
18552 | boardp->adv_sgblkp = NULL; | 13867 | if (shost->dma_channel != NO_ISA_DMA) |
18553 | for (sg_cnt = 0; sg_cnt < ADV_TOT_SG_BLOCK; sg_cnt++) { | 13868 | free_dma(shost->dma_channel); |
13869 | err_free_proc: | ||
13870 | kfree(boardp->prtbuf); | ||
13871 | err_unmap: | ||
13872 | if (boardp->ioremap_addr) | ||
13873 | iounmap(boardp->ioremap_addr); | ||
13874 | err_shost: | ||
13875 | return ret; | ||
13876 | } | ||
18554 | 13877 | ||
18555 | sgp = (adv_sgblk_t *) | 13878 | /* |
18556 | kmalloc(sizeof(adv_sgblk_t), GFP_ATOMIC); | 13879 | * advansys_release() |
13880 | * | ||
13881 | * Release resources allocated for a single AdvanSys adapter. | ||
13882 | */ | ||
13883 | static int advansys_release(struct Scsi_Host *shost) | ||
13884 | { | ||
13885 | struct asc_board *board = shost_priv(shost); | ||
13886 | ASC_DBG(1, "begin\n"); | ||
13887 | scsi_remove_host(shost); | ||
13888 | free_irq(board->irq, shost); | ||
13889 | if (shost->dma_channel != NO_ISA_DMA) { | ||
13890 | ASC_DBG(1, "free_dma()\n"); | ||
13891 | free_dma(shost->dma_channel); | ||
13892 | } | ||
13893 | if (ASC_NARROW_BOARD(board)) { | ||
13894 | dma_unmap_single(board->dev, | ||
13895 | board->dvc_var.asc_dvc_var.overrun_dma, | ||
13896 | ASC_OVERRUN_BSIZE, DMA_FROM_DEVICE); | ||
13897 | } else { | ||
13898 | iounmap(board->ioremap_addr); | ||
13899 | advansys_wide_free_mem(board); | ||
13900 | } | ||
13901 | kfree(board->prtbuf); | ||
13902 | scsi_host_put(shost); | ||
13903 | ASC_DBG(1, "end\n"); | ||
13904 | return 0; | ||
13905 | } | ||
18557 | 13906 | ||
18558 | if (sgp == NULL) { | 13907 | #define ASC_IOADR_TABLE_MAX_IX 11 |
18559 | break; | ||
18560 | } | ||
18561 | 13908 | ||
18562 | sgp->next_sgblkp = boardp->adv_sgblkp; | 13909 | static PortAddr _asc_def_iop_base[ASC_IOADR_TABLE_MAX_IX] __devinitdata = { |
18563 | boardp->adv_sgblkp = sgp; | 13910 | 0x100, 0x0110, 0x120, 0x0130, 0x140, 0x0150, 0x0190, |
13911 | 0x0210, 0x0230, 0x0250, 0x0330 | ||
13912 | }; | ||
18564 | 13913 | ||
18565 | } | 13914 | /* |
18566 | ASC_DBG3(1, | 13915 | * The ISA IRQ number is found in bits 2 and 3 of the CfgLsw. It decodes as: |
18567 | "advansys_board_found: sg_cnt %d * %u = %u bytes\n", | 13916 | * 00: 10 |
18568 | sg_cnt, sizeof(adv_sgblk_t), | 13917 | * 01: 11 |
18569 | (unsigned)(sizeof(adv_sgblk_t) * sg_cnt)); | 13918 | * 10: 12 |
13919 | * 11: 15 | ||
13920 | */ | ||
13921 | static unsigned int __devinit advansys_isa_irq_no(PortAddr iop_base) | ||
13922 | { | ||
13923 | unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base); | ||
13924 | unsigned int chip_irq = ((cfg_lsw >> 2) & 0x03) + 10; | ||
13925 | if (chip_irq == 13) | ||
13926 | chip_irq = 15; | ||
13927 | return chip_irq; | ||
13928 | } | ||
18570 | 13929 | ||
18571 | /* | 13930 | static int __devinit advansys_isa_probe(struct device *dev, unsigned int id) |
18572 | * If no request structures or scatter-gather structures could | 13931 | { |
18573 | * be allocated, then return an error. Otherwise continue with | 13932 | int err = -ENODEV; |
18574 | * initialization. | 13933 | PortAddr iop_base = _asc_def_iop_base[id]; |
18575 | */ | 13934 | struct Scsi_Host *shost; |
18576 | kmalloc_error: | 13935 | struct asc_board *board; |
18577 | if (carrp == NULL) { | ||
18578 | ASC_PRINT1 | ||
18579 | ("advansys_board_found: board %d error: failed to kmalloc() carrier buffer.\n", | ||
18580 | boardp->id); | ||
18581 | err_code = ADV_ERROR; | ||
18582 | } else if (reqp == NULL) { | ||
18583 | kfree(carrp); | ||
18584 | ASC_PRINT1 | ||
18585 | ("advansys_board_found: board %d error: failed to kmalloc() adv_req_t buffer.\n", | ||
18586 | boardp->id); | ||
18587 | err_code = ADV_ERROR; | ||
18588 | } else if (boardp->adv_sgblkp == NULL) { | ||
18589 | kfree(carrp); | ||
18590 | kfree(reqp); | ||
18591 | ASC_PRINT1 | ||
18592 | ("advansys_board_found: board %d error: failed to kmalloc() adv_sgblk_t buffers.\n", | ||
18593 | boardp->id); | ||
18594 | err_code = ADV_ERROR; | ||
18595 | } else { | ||
18596 | 13936 | ||
18597 | /* Save carrier buffer pointer. */ | 13937 | if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) { |
18598 | boardp->orig_carrp = carrp; | 13938 | ASC_DBG(1, "I/O port 0x%x busy\n", iop_base); |
13939 | return -ENODEV; | ||
13940 | } | ||
13941 | ASC_DBG(1, "probing I/O port 0x%x\n", iop_base); | ||
13942 | if (!AscFindSignature(iop_base)) | ||
13943 | goto release_region; | ||
13944 | if (!(AscGetChipVersion(iop_base, ASC_IS_ISA) & ASC_CHIP_VER_ISA_BIT)) | ||
13945 | goto release_region; | ||
18599 | 13946 | ||
18600 | /* | 13947 | err = -ENOMEM; |
18601 | * Save original pointer for kfree() in case the | 13948 | shost = scsi_host_alloc(&advansys_template, sizeof(*board)); |
18602 | * driver is built as a module and can be unloaded. | 13949 | if (!shost) |
18603 | */ | 13950 | goto release_region; |
18604 | boardp->orig_reqp = reqp; | ||
18605 | 13951 | ||
18606 | adv_dvc_varp->carrier_buf = carrp; | 13952 | board = shost_priv(shost); |
13953 | board->irq = advansys_isa_irq_no(iop_base); | ||
13954 | board->dev = dev; | ||
18607 | 13955 | ||
18608 | /* | 13956 | err = advansys_board_found(shost, iop_base, ASC_IS_ISA); |
18609 | * Point 'adv_reqp' to the request structures and | 13957 | if (err) |
18610 | * link them together. | 13958 | goto free_host; |
18611 | */ | ||
18612 | req_cnt--; | ||
18613 | reqp[req_cnt].next_reqp = NULL; | ||
18614 | for (; req_cnt > 0; req_cnt--) { | ||
18615 | reqp[req_cnt - 1].next_reqp = &reqp[req_cnt]; | ||
18616 | } | ||
18617 | boardp->adv_reqp = &reqp[0]; | ||
18618 | |||
18619 | if (adv_dvc_varp->chip_type == ADV_CHIP_ASC3550) { | ||
18620 | ASC_DBG(2, | ||
18621 | "advansys_board_found: AdvInitAsc3550Driver()\n"); | ||
18622 | warn_code = AdvInitAsc3550Driver(adv_dvc_varp); | ||
18623 | } else if (adv_dvc_varp->chip_type == | ||
18624 | ADV_CHIP_ASC38C0800) { | ||
18625 | ASC_DBG(2, | ||
18626 | "advansys_board_found: AdvInitAsc38C0800Driver()\n"); | ||
18627 | warn_code = | ||
18628 | AdvInitAsc38C0800Driver(adv_dvc_varp); | ||
18629 | } else { | ||
18630 | ASC_DBG(2, | ||
18631 | "advansys_board_found: AdvInitAsc38C1600Driver()\n"); | ||
18632 | warn_code = | ||
18633 | AdvInitAsc38C1600Driver(adv_dvc_varp); | ||
18634 | } | ||
18635 | err_code = adv_dvc_varp->err_code; | ||
18636 | 13959 | ||
18637 | if (warn_code || err_code) { | 13960 | dev_set_drvdata(dev, shost); |
18638 | ASC_PRINT3 | 13961 | return 0; |
18639 | ("advansys_board_found: board %d error: warn 0x%x, error 0x%x\n", | ||
18640 | boardp->id, warn_code, err_code); | ||
18641 | } | ||
18642 | } | ||
18643 | } | ||
18644 | 13962 | ||
18645 | if (err_code != 0) { | 13963 | free_host: |
18646 | release_region(shost->io_port, boardp->asc_n_io_port); | 13964 | scsi_host_put(shost); |
18647 | if (ASC_WIDE_BOARD(boardp)) { | 13965 | release_region: |
18648 | iounmap(boardp->ioremap_addr); | 13966 | release_region(iop_base, ASC_IOADR_GAP); |
18649 | kfree(boardp->orig_carrp); | 13967 | return err; |
18650 | boardp->orig_carrp = NULL; | 13968 | } |
18651 | if (boardp->orig_reqp) { | ||
18652 | kfree(boardp->orig_reqp); | ||
18653 | boardp->orig_reqp = boardp->adv_reqp = NULL; | ||
18654 | } | ||
18655 | while ((sgp = boardp->adv_sgblkp) != NULL) { | ||
18656 | boardp->adv_sgblkp = sgp->next_sgblkp; | ||
18657 | kfree(sgp); | ||
18658 | } | ||
18659 | } | ||
18660 | if (shost->dma_channel != NO_ISA_DMA) { | ||
18661 | free_dma(shost->dma_channel); | ||
18662 | } | ||
18663 | #ifdef CONFIG_PROC_FS | ||
18664 | kfree(boardp->prtbuf); | ||
18665 | #endif /* CONFIG_PROC_FS */ | ||
18666 | free_irq(shost->irq, boardp); | ||
18667 | scsi_unregister(shost); | ||
18668 | asc_board_count--; | ||
18669 | return NULL; | ||
18670 | } | ||
18671 | ASC_DBG_PRT_SCSI_HOST(2, shost); | ||
18672 | 13969 | ||
18673 | return shost; | 13970 | static int __devexit advansys_isa_remove(struct device *dev, unsigned int id) |
13971 | { | ||
13972 | int ioport = _asc_def_iop_base[id]; | ||
13973 | advansys_release(dev_get_drvdata(dev)); | ||
13974 | release_region(ioport, ASC_IOADR_GAP); | ||
13975 | return 0; | ||
18674 | } | 13976 | } |
18675 | 13977 | ||
13978 | static struct isa_driver advansys_isa_driver = { | ||
13979 | .probe = advansys_isa_probe, | ||
13980 | .remove = __devexit_p(advansys_isa_remove), | ||
13981 | .driver = { | ||
13982 | .owner = THIS_MODULE, | ||
13983 | .name = DRV_NAME, | ||
13984 | }, | ||
13985 | }; | ||
13986 | |||
18676 | /* | 13987 | /* |
18677 | * advansys_detect() | 13988 | * The VLB IRQ number is found in bits 2 to 4 of the CfgLsw. It decodes as: |
18678 | * | 13989 | * 000: invalid |
18679 | * Detect function for AdvanSys adapters. | 13990 | * 001: 10 |
18680 | * | 13991 | * 010: 11 |
18681 | * Argument is a pointer to the host driver's scsi_hosts entry. | 13992 | * 011: 12 |
18682 | * | 13993 | * 100: invalid |
18683 | * Return number of adapters found. | 13994 | * 101: 14 |
18684 | * | 13995 | * 110: 15 |
18685 | * Note: Because this function is called during system initialization | 13996 | * 111: invalid |
18686 | * it must not call SCSI mid-level functions including scsi_malloc() | ||
18687 | * and scsi_free(). | ||
18688 | */ | 13997 | */ |
18689 | static int __init advansys_detect(struct scsi_host_template *tpnt) | 13998 | static unsigned int __devinit advansys_vlb_irq_no(PortAddr iop_base) |
18690 | { | 13999 | { |
18691 | static int detect_called = ASC_FALSE; | 14000 | unsigned short cfg_lsw = AscGetChipCfgLsw(iop_base); |
18692 | int iop; | 14001 | unsigned int chip_irq = ((cfg_lsw >> 2) & 0x07) + 9; |
18693 | int bus; | 14002 | if ((chip_irq < 10) || (chip_irq == 13) || (chip_irq > 15)) |
18694 | int ioport = 0; | ||
18695 | struct device *dev = NULL; | ||
18696 | #ifdef CONFIG_PCI | ||
18697 | int pci_init_search = 0; | ||
18698 | struct pci_dev *pci_devicep[ASC_NUM_BOARD_SUPPORTED]; | ||
18699 | int pci_card_cnt_max = 0; | ||
18700 | int pci_card_cnt = 0; | ||
18701 | struct pci_dev *pdev = NULL; | ||
18702 | int pci_device_id_cnt = 0; | ||
18703 | unsigned int pci_device_id[ASC_PCI_DEVICE_ID_CNT] = { | ||
18704 | PCI_DEVICE_ID_ASP_1200A, | ||
18705 | PCI_DEVICE_ID_ASP_ABP940, | ||
18706 | PCI_DEVICE_ID_ASP_ABP940U, | ||
18707 | PCI_DEVICE_ID_ASP_ABP940UW, | ||
18708 | PCI_DEVICE_ID_38C0800_REV1, | ||
18709 | PCI_DEVICE_ID_38C1600_REV1 | ||
18710 | }; | ||
18711 | #endif /* CONFIG_PCI */ | ||
18712 | |||
18713 | if (detect_called == ASC_FALSE) { | ||
18714 | detect_called = ASC_TRUE; | ||
18715 | } else { | ||
18716 | printk | ||
18717 | ("AdvanSys SCSI: advansys_detect() multiple calls ignored\n"); | ||
18718 | return 0; | 14003 | return 0; |
18719 | } | 14004 | return chip_irq; |
18720 | 14005 | } | |
18721 | ASC_DBG(1, "advansys_detect: begin\n"); | ||
18722 | 14006 | ||
18723 | asc_board_count = 0; | 14007 | static int __devinit advansys_vlb_probe(struct device *dev, unsigned int id) |
14008 | { | ||
14009 | int err = -ENODEV; | ||
14010 | PortAddr iop_base = _asc_def_iop_base[id]; | ||
14011 | struct Scsi_Host *shost; | ||
14012 | struct asc_board *board; | ||
18724 | 14013 | ||
14014 | if (!request_region(iop_base, ASC_IOADR_GAP, DRV_NAME)) { | ||
14015 | ASC_DBG(1, "I/O port 0x%x busy\n", iop_base); | ||
14016 | return -ENODEV; | ||
14017 | } | ||
14018 | ASC_DBG(1, "probing I/O port 0x%x\n", iop_base); | ||
14019 | if (!AscFindSignature(iop_base)) | ||
14020 | goto release_region; | ||
18725 | /* | 14021 | /* |
18726 | * If I/O port probing has been modified, then verify and | 14022 | * I don't think this condition can actually happen, but the old |
18727 | * clean-up the 'asc_ioport' list. | 14023 | * driver did it, and the chances of finding a VLB setup in 2007 |
14024 | * to do testing with is slight to none. | ||
18728 | */ | 14025 | */ |
18729 | if (asc_iopflag == ASC_TRUE) { | 14026 | if (AscGetChipVersion(iop_base, ASC_IS_VL) > ASC_CHIP_MAX_VER_VL) |
18730 | for (ioport = 0; ioport < ASC_NUM_IOPORT_PROBE; ioport++) { | 14027 | goto release_region; |
18731 | ASC_DBG2(1, "advansys_detect: asc_ioport[%d] 0x%x\n", | ||
18732 | ioport, asc_ioport[ioport]); | ||
18733 | if (asc_ioport[ioport] != 0) { | ||
18734 | for (iop = 0; iop < ASC_IOADR_TABLE_MAX_IX; | ||
18735 | iop++) { | ||
18736 | if (_asc_def_iop_base[iop] == | ||
18737 | asc_ioport[ioport]) { | ||
18738 | break; | ||
18739 | } | ||
18740 | } | ||
18741 | if (iop == ASC_IOADR_TABLE_MAX_IX) { | ||
18742 | printk | ||
18743 | ("AdvanSys SCSI: specified I/O Port 0x%X is invalid\n", | ||
18744 | asc_ioport[ioport]); | ||
18745 | asc_ioport[ioport] = 0; | ||
18746 | } | ||
18747 | } | ||
18748 | } | ||
18749 | ioport = 0; | ||
18750 | } | ||
18751 | 14028 | ||
18752 | for (bus = 0; bus < ASC_NUM_BUS; bus++) { | 14029 | err = -ENOMEM; |
14030 | shost = scsi_host_alloc(&advansys_template, sizeof(*board)); | ||
14031 | if (!shost) | ||
14032 | goto release_region; | ||
18753 | 14033 | ||
18754 | ASC_DBG2(1, "advansys_detect: bus search type %d (%s)\n", | 14034 | board = shost_priv(shost); |
18755 | bus, asc_bus_name[bus]); | 14035 | board->irq = advansys_vlb_irq_no(iop_base); |
18756 | iop = 0; | 14036 | board->dev = dev; |
18757 | 14037 | ||
18758 | while (asc_board_count < ASC_NUM_BOARD_SUPPORTED) { | 14038 | err = advansys_board_found(shost, iop_base, ASC_IS_VL); |
14039 | if (err) | ||
14040 | goto free_host; | ||
18759 | 14041 | ||
18760 | ASC_DBG1(2, "advansys_detect: asc_board_count %d\n", | 14042 | dev_set_drvdata(dev, shost); |
18761 | asc_board_count); | 14043 | return 0; |
18762 | 14044 | ||
18763 | switch (asc_bus[bus]) { | 14045 | free_host: |
18764 | case ASC_IS_ISA: | 14046 | scsi_host_put(shost); |
18765 | case ASC_IS_VL: | 14047 | release_region: |
18766 | #ifdef CONFIG_ISA | 14048 | release_region(iop_base, ASC_IOADR_GAP); |
18767 | if (asc_iopflag == ASC_FALSE) { | 14049 | return -ENODEV; |
18768 | iop = | 14050 | } |
18769 | AscSearchIOPortAddr(iop, | ||
18770 | asc_bus[bus]); | ||
18771 | } else { | ||
18772 | /* | ||
18773 | * ISA and VL I/O port scanning has either been | ||
18774 | * eliminated or limited to selected ports on | ||
18775 | * the LILO command line, /etc/lilo.conf, or | ||
18776 | * by setting variables when the module was loaded. | ||
18777 | */ | ||
18778 | ASC_DBG(1, | ||
18779 | "advansys_detect: I/O port scanning modified\n"); | ||
18780 | ioport_try_again: | ||
18781 | iop = 0; | ||
18782 | for (; ioport < ASC_NUM_IOPORT_PROBE; | ||
18783 | ioport++) { | ||
18784 | if ((iop = | ||
18785 | asc_ioport[ioport]) != 0) { | ||
18786 | break; | ||
18787 | } | ||
18788 | } | ||
18789 | if (iop) { | ||
18790 | ASC_DBG1(1, | ||
18791 | "advansys_detect: probing I/O port 0x%x...\n", | ||
18792 | iop); | ||
18793 | if (!request_region | ||
18794 | (iop, ASC_IOADR_GAP, | ||
18795 | "advansys")) { | ||
18796 | printk | ||
18797 | ("AdvanSys SCSI: specified I/O Port 0x%X is busy\n", | ||
18798 | iop); | ||
18799 | /* Don't try this I/O port twice. */ | ||
18800 | asc_ioport[ioport] = 0; | ||
18801 | goto ioport_try_again; | ||
18802 | } else if (AscFindSignature(iop) | ||
18803 | == ASC_FALSE) { | ||
18804 | printk | ||
18805 | ("AdvanSys SCSI: specified I/O Port 0x%X has no adapter\n", | ||
18806 | iop); | ||
18807 | /* Don't try this I/O port twice. */ | ||
18808 | release_region(iop, | ||
18809 | ASC_IOADR_GAP); | ||
18810 | asc_ioport[ioport] = 0; | ||
18811 | goto ioport_try_again; | ||
18812 | } else { | ||
18813 | /* | ||
18814 | * If this isn't an ISA board, then it must be | ||
18815 | * a VL board. If currently looking an ISA | ||
18816 | * board is being looked for then try for | ||
18817 | * another ISA board in 'asc_ioport'. | ||
18818 | */ | ||
18819 | if (asc_bus[bus] == | ||
18820 | ASC_IS_ISA | ||
18821 | && | ||
18822 | (AscGetChipVersion | ||
18823 | (iop, | ||
18824 | ASC_IS_ISA) & | ||
18825 | ASC_CHIP_VER_ISA_BIT) | ||
18826 | == 0) { | ||
18827 | /* | ||
18828 | * Don't clear 'asc_ioport[ioport]'. Try | ||
18829 | * this board again for VL. Increment | ||
18830 | * 'ioport' past this board. | ||
18831 | */ | ||
18832 | ioport++; | ||
18833 | release_region | ||
18834 | (iop, | ||
18835 | ASC_IOADR_GAP); | ||
18836 | goto ioport_try_again; | ||
18837 | } | ||
18838 | } | ||
18839 | /* | ||
18840 | * This board appears good, don't try the I/O port | ||
18841 | * again by clearing its value. Increment 'ioport' | ||
18842 | * for the next iteration. | ||
18843 | */ | ||
18844 | asc_ioport[ioport++] = 0; | ||
18845 | } | ||
18846 | } | ||
18847 | #endif /* CONFIG_ISA */ | ||
18848 | break; | ||
18849 | 14051 | ||
18850 | case ASC_IS_EISA: | 14052 | static struct isa_driver advansys_vlb_driver = { |
18851 | #ifdef CONFIG_ISA | 14053 | .probe = advansys_vlb_probe, |
18852 | iop = AscSearchIOPortAddr(iop, asc_bus[bus]); | 14054 | .remove = __devexit_p(advansys_isa_remove), |
18853 | #endif /* CONFIG_ISA */ | 14055 | .driver = { |
18854 | break; | 14056 | .owner = THIS_MODULE, |
14057 | .name = "advansys_vlb", | ||
14058 | }, | ||
14059 | }; | ||
18855 | 14060 | ||
18856 | case ASC_IS_PCI: | 14061 | static struct eisa_device_id advansys_eisa_table[] __devinitdata = { |
18857 | #ifdef CONFIG_PCI | 14062 | { "ABP7401" }, |
18858 | if (pci_init_search == 0) { | 14063 | { "ABP7501" }, |
18859 | int i, j; | 14064 | { "" } |
18860 | 14065 | }; | |
18861 | pci_init_search = 1; | ||
18862 | |||
18863 | /* Find all PCI cards. */ | ||
18864 | while (pci_device_id_cnt < | ||
18865 | ASC_PCI_DEVICE_ID_CNT) { | ||
18866 | if ((pdev = | ||
18867 | pci_find_device | ||
18868 | (PCI_VENDOR_ID_ASP, | ||
18869 | pci_device_id | ||
18870 | [pci_device_id_cnt], | ||
18871 | pdev)) == NULL) { | ||
18872 | pci_device_id_cnt++; | ||
18873 | } else { | ||
18874 | if (pci_enable_device | ||
18875 | (pdev) == 0) { | ||
18876 | pci_devicep | ||
18877 | [pci_card_cnt_max++] | ||
18878 | = pdev; | ||
18879 | } | ||
18880 | } | ||
18881 | } | ||
18882 | 14066 | ||
18883 | /* | 14067 | MODULE_DEVICE_TABLE(eisa, advansys_eisa_table); |
18884 | * Sort PCI cards in ascending order by PCI Bus, Slot, | ||
18885 | * and Device Number. | ||
18886 | */ | ||
18887 | for (i = 0; i < pci_card_cnt_max - 1; | ||
18888 | i++) { | ||
18889 | for (j = i + 1; | ||
18890 | j < pci_card_cnt_max; | ||
18891 | j++) { | ||
18892 | if ((pci_devicep[j]-> | ||
18893 | bus->number < | ||
18894 | pci_devicep[i]-> | ||
18895 | bus->number) | ||
18896 | || | ||
18897 | ((pci_devicep[j]-> | ||
18898 | bus->number == | ||
18899 | pci_devicep[i]-> | ||
18900 | bus->number) | ||
18901 | && | ||
18902 | (pci_devicep[j]-> | ||
18903 | devfn < | ||
18904 | pci_devicep[i]-> | ||
18905 | devfn))) { | ||
18906 | pdev = | ||
18907 | pci_devicep | ||
18908 | [i]; | ||
18909 | pci_devicep[i] = | ||
18910 | pci_devicep | ||
18911 | [j]; | ||
18912 | pci_devicep[j] = | ||
18913 | pdev; | ||
18914 | } | ||
18915 | } | ||
18916 | } | ||
18917 | 14068 | ||
18918 | pci_card_cnt = 0; | 14069 | /* |
18919 | } else { | 14070 | * EISA is a little more tricky than PCI; each EISA device may have two |
18920 | pci_card_cnt++; | 14071 | * channels, and this driver is written to make each channel its own Scsi_Host |
18921 | } | 14072 | */ |
14073 | struct eisa_scsi_data { | ||
14074 | struct Scsi_Host *host[2]; | ||
14075 | }; | ||
18922 | 14076 | ||
18923 | if (pci_card_cnt == pci_card_cnt_max) { | 14077 | /* |
18924 | iop = 0; | 14078 | * The EISA IRQ number is found in bits 8 to 10 of the CfgLsw. It decodes as: |
18925 | } else { | 14079 | * 000: 10 |
18926 | pdev = pci_devicep[pci_card_cnt]; | 14080 | * 001: 11 |
18927 | 14081 | * 010: 12 | |
18928 | ASC_DBG2(2, | 14082 | * 011: invalid |
18929 | "advansys_detect: devfn %d, bus number %d\n", | 14083 | * 100: 14 |
18930 | pdev->devfn, | 14084 | * 101: 15 |
18931 | pdev->bus->number); | 14085 | * 110: invalid |
18932 | iop = pci_resource_start(pdev, 0); | 14086 | * 111: invalid |
18933 | ASC_DBG2(1, | 14087 | */ |
18934 | "advansys_detect: vendorID %X, deviceID %X\n", | 14088 | static unsigned int __devinit advansys_eisa_irq_no(struct eisa_device *edev) |
18935 | pdev->vendor, | 14089 | { |
18936 | pdev->device); | 14090 | unsigned short cfg_lsw = inw(edev->base_addr + 0xc86); |
18937 | ASC_DBG2(2, | 14091 | unsigned int chip_irq = ((cfg_lsw >> 8) & 0x07) + 10; |
18938 | "advansys_detect: iop %X, irqLine %d\n", | 14092 | if ((chip_irq == 13) || (chip_irq > 15)) |
18939 | iop, pdev->irq); | 14093 | return 0; |
18940 | } | 14094 | return chip_irq; |
18941 | if (pdev) | 14095 | } |
18942 | dev = &pdev->dev; | ||
18943 | 14096 | ||
18944 | #endif /* CONFIG_PCI */ | 14097 | static int __devinit advansys_eisa_probe(struct device *dev) |
18945 | break; | 14098 | { |
14099 | int i, ioport, irq = 0; | ||
14100 | int err; | ||
14101 | struct eisa_device *edev = to_eisa_device(dev); | ||
14102 | struct eisa_scsi_data *data; | ||
18946 | 14103 | ||
18947 | default: | 14104 | err = -ENOMEM; |
18948 | ASC_PRINT1 | 14105 | data = kzalloc(sizeof(*data), GFP_KERNEL); |
18949 | ("advansys_detect: unknown bus type: %d\n", | 14106 | if (!data) |
18950 | asc_bus[bus]); | 14107 | goto fail; |
18951 | break; | 14108 | ioport = edev->base_addr + 0xc30; |
18952 | } | ||
18953 | ASC_DBG1(1, "advansys_detect: iop 0x%x\n", iop); | ||
18954 | 14109 | ||
18955 | /* | 14110 | err = -ENODEV; |
18956 | * Adapter not found, try next bus type. | 14111 | for (i = 0; i < 2; i++, ioport += 0x20) { |
18957 | */ | 14112 | struct asc_board *board; |
18958 | if (iop == 0) { | 14113 | struct Scsi_Host *shost; |
18959 | break; | 14114 | if (!request_region(ioport, ASC_IOADR_GAP, DRV_NAME)) { |
18960 | } | 14115 | printk(KERN_WARNING "Region %x-%x busy\n", ioport, |
14116 | ioport + ASC_IOADR_GAP - 1); | ||
14117 | continue; | ||
14118 | } | ||
14119 | if (!AscFindSignature(ioport)) { | ||
14120 | release_region(ioport, ASC_IOADR_GAP); | ||
14121 | continue; | ||
14122 | } | ||
18961 | 14123 | ||
18962 | advansys_board_found(iop, dev, asc_bus[bus]); | 14124 | /* |
14125 | * I don't know why we need to do this for EISA chips, but | ||
14126 | * not for any others. It looks to be equivalent to | ||
14127 | * AscGetChipCfgMsw, but I may have overlooked something, | ||
14128 | * so I'm not converting it until I get an EISA board to | ||
14129 | * test with. | ||
14130 | */ | ||
14131 | inw(ioport + 4); | ||
14132 | |||
14133 | if (!irq) | ||
14134 | irq = advansys_eisa_irq_no(edev); | ||
14135 | |||
14136 | err = -ENOMEM; | ||
14137 | shost = scsi_host_alloc(&advansys_template, sizeof(*board)); | ||
14138 | if (!shost) | ||
14139 | goto release_region; | ||
14140 | |||
14141 | board = shost_priv(shost); | ||
14142 | board->irq = irq; | ||
14143 | board->dev = dev; | ||
14144 | |||
14145 | err = advansys_board_found(shost, ioport, ASC_IS_EISA); | ||
14146 | if (!err) { | ||
14147 | data->host[i] = shost; | ||
14148 | continue; | ||
18963 | } | 14149 | } |
14150 | |||
14151 | scsi_host_put(shost); | ||
14152 | release_region: | ||
14153 | release_region(ioport, ASC_IOADR_GAP); | ||
14154 | break; | ||
18964 | } | 14155 | } |
18965 | 14156 | ||
18966 | ASC_DBG1(1, "advansys_detect: done: asc_board_count %d\n", | 14157 | if (err) |
18967 | asc_board_count); | 14158 | goto free_data; |
18968 | return asc_board_count; | 14159 | dev_set_drvdata(dev, data); |
14160 | return 0; | ||
14161 | |||
14162 | free_data: | ||
14163 | kfree(data->host[0]); | ||
14164 | kfree(data->host[1]); | ||
14165 | kfree(data); | ||
14166 | fail: | ||
14167 | return err; | ||
18969 | } | 14168 | } |
18970 | 14169 | ||
18971 | /* | 14170 | static __devexit int advansys_eisa_remove(struct device *dev) |
18972 | * advansys_release() | ||
18973 | * | ||
18974 | * Release resources allocated for a single AdvanSys adapter. | ||
18975 | */ | ||
18976 | static int advansys_release(struct Scsi_Host *shost) | ||
18977 | { | 14171 | { |
18978 | asc_board_t *boardp; | 14172 | int i; |
14173 | struct eisa_scsi_data *data = dev_get_drvdata(dev); | ||
18979 | 14174 | ||
18980 | ASC_DBG(1, "advansys_release: begin\n"); | 14175 | for (i = 0; i < 2; i++) { |
18981 | boardp = ASC_BOARDP(shost); | 14176 | int ioport; |
18982 | free_irq(shost->irq, boardp); | 14177 | struct Scsi_Host *shost = data->host[i]; |
18983 | if (shost->dma_channel != NO_ISA_DMA) { | 14178 | if (!shost) |
18984 | ASC_DBG(1, "advansys_release: free_dma()\n"); | 14179 | continue; |
18985 | free_dma(shost->dma_channel); | 14180 | ioport = shost->io_port; |
14181 | advansys_release(shost); | ||
14182 | release_region(ioport, ASC_IOADR_GAP); | ||
18986 | } | 14183 | } |
18987 | release_region(shost->io_port, boardp->asc_n_io_port); | ||
18988 | if (ASC_WIDE_BOARD(boardp)) { | ||
18989 | adv_sgblk_t *sgp = NULL; | ||
18990 | 14184 | ||
18991 | iounmap(boardp->ioremap_addr); | 14185 | kfree(data); |
18992 | kfree(boardp->orig_carrp); | ||
18993 | boardp->orig_carrp = NULL; | ||
18994 | if (boardp->orig_reqp) { | ||
18995 | kfree(boardp->orig_reqp); | ||
18996 | boardp->orig_reqp = boardp->adv_reqp = NULL; | ||
18997 | } | ||
18998 | while ((sgp = boardp->adv_sgblkp) != NULL) { | ||
18999 | boardp->adv_sgblkp = sgp->next_sgblkp; | ||
19000 | kfree(sgp); | ||
19001 | } | ||
19002 | } | ||
19003 | #ifdef CONFIG_PROC_FS | ||
19004 | ASC_ASSERT(boardp->prtbuf != NULL); | ||
19005 | kfree(boardp->prtbuf); | ||
19006 | #endif /* CONFIG_PROC_FS */ | ||
19007 | scsi_unregister(shost); | ||
19008 | ASC_DBG(1, "advansys_release: end\n"); | ||
19009 | return 0; | 14186 | return 0; |
19010 | } | 14187 | } |
19011 | 14188 | ||
19012 | #ifdef CONFIG_PCI | 14189 | static struct eisa_driver advansys_eisa_driver = { |
14190 | .id_table = advansys_eisa_table, | ||
14191 | .driver = { | ||
14192 | .name = DRV_NAME, | ||
14193 | .probe = advansys_eisa_probe, | ||
14194 | .remove = __devexit_p(advansys_eisa_remove), | ||
14195 | } | ||
14196 | }; | ||
14197 | |||
19013 | /* PCI Devices supported by this driver */ | 14198 | /* PCI Devices supported by this driver */ |
19014 | static struct pci_device_id advansys_pci_tbl[] __devinitdata = { | 14199 | static struct pci_device_id advansys_pci_tbl[] __devinitdata = { |
19015 | {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A, | 14200 | {PCI_VENDOR_ID_ASP, PCI_DEVICE_ID_ASP_1200A, |
@@ -19028,4 +14213,131 @@ static struct pci_device_id advansys_pci_tbl[] __devinitdata = { | |||
19028 | }; | 14213 | }; |
19029 | 14214 | ||
19030 | MODULE_DEVICE_TABLE(pci, advansys_pci_tbl); | 14215 | MODULE_DEVICE_TABLE(pci, advansys_pci_tbl); |
19031 | #endif /* CONFIG_PCI */ | 14216 | |
14217 | static void __devinit advansys_set_latency(struct pci_dev *pdev) | ||
14218 | { | ||
14219 | if ((pdev->device == PCI_DEVICE_ID_ASP_1200A) || | ||
14220 | (pdev->device == PCI_DEVICE_ID_ASP_ABP940)) { | ||
14221 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0); | ||
14222 | } else { | ||
14223 | u8 latency; | ||
14224 | pci_read_config_byte(pdev, PCI_LATENCY_TIMER, &latency); | ||
14225 | if (latency < 0x20) | ||
14226 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x20); | ||
14227 | } | ||
14228 | } | ||
14229 | |||
14230 | static int __devinit | ||
14231 | advansys_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | ||
14232 | { | ||
14233 | int err, ioport; | ||
14234 | struct Scsi_Host *shost; | ||
14235 | struct asc_board *board; | ||
14236 | |||
14237 | err = pci_enable_device(pdev); | ||
14238 | if (err) | ||
14239 | goto fail; | ||
14240 | err = pci_request_regions(pdev, DRV_NAME); | ||
14241 | if (err) | ||
14242 | goto disable_device; | ||
14243 | pci_set_master(pdev); | ||
14244 | advansys_set_latency(pdev); | ||
14245 | |||
14246 | err = -ENODEV; | ||
14247 | if (pci_resource_len(pdev, 0) == 0) | ||
14248 | goto release_region; | ||
14249 | |||
14250 | ioport = pci_resource_start(pdev, 0); | ||
14251 | |||
14252 | err = -ENOMEM; | ||
14253 | shost = scsi_host_alloc(&advansys_template, sizeof(*board)); | ||
14254 | if (!shost) | ||
14255 | goto release_region; | ||
14256 | |||
14257 | board = shost_priv(shost); | ||
14258 | board->irq = pdev->irq; | ||
14259 | board->dev = &pdev->dev; | ||
14260 | |||
14261 | if (pdev->device == PCI_DEVICE_ID_ASP_ABP940UW || | ||
14262 | pdev->device == PCI_DEVICE_ID_38C0800_REV1 || | ||
14263 | pdev->device == PCI_DEVICE_ID_38C1600_REV1) { | ||
14264 | board->flags |= ASC_IS_WIDE_BOARD; | ||
14265 | } | ||
14266 | |||
14267 | err = advansys_board_found(shost, ioport, ASC_IS_PCI); | ||
14268 | if (err) | ||
14269 | goto free_host; | ||
14270 | |||
14271 | pci_set_drvdata(pdev, shost); | ||
14272 | return 0; | ||
14273 | |||
14274 | free_host: | ||
14275 | scsi_host_put(shost); | ||
14276 | release_region: | ||
14277 | pci_release_regions(pdev); | ||
14278 | disable_device: | ||
14279 | pci_disable_device(pdev); | ||
14280 | fail: | ||
14281 | return err; | ||
14282 | } | ||
14283 | |||
14284 | static void __devexit advansys_pci_remove(struct pci_dev *pdev) | ||
14285 | { | ||
14286 | advansys_release(pci_get_drvdata(pdev)); | ||
14287 | pci_release_regions(pdev); | ||
14288 | pci_disable_device(pdev); | ||
14289 | } | ||
14290 | |||
14291 | static struct pci_driver advansys_pci_driver = { | ||
14292 | .name = DRV_NAME, | ||
14293 | .id_table = advansys_pci_tbl, | ||
14294 | .probe = advansys_pci_probe, | ||
14295 | .remove = __devexit_p(advansys_pci_remove), | ||
14296 | }; | ||
14297 | |||
14298 | static int __init advansys_init(void) | ||
14299 | { | ||
14300 | int error; | ||
14301 | |||
14302 | error = isa_register_driver(&advansys_isa_driver, | ||
14303 | ASC_IOADR_TABLE_MAX_IX); | ||
14304 | if (error) | ||
14305 | goto fail; | ||
14306 | |||
14307 | error = isa_register_driver(&advansys_vlb_driver, | ||
14308 | ASC_IOADR_TABLE_MAX_IX); | ||
14309 | if (error) | ||
14310 | goto unregister_isa; | ||
14311 | |||
14312 | error = eisa_driver_register(&advansys_eisa_driver); | ||
14313 | if (error) | ||
14314 | goto unregister_vlb; | ||
14315 | |||
14316 | error = pci_register_driver(&advansys_pci_driver); | ||
14317 | if (error) | ||
14318 | goto unregister_eisa; | ||
14319 | |||
14320 | return 0; | ||
14321 | |||
14322 | unregister_eisa: | ||
14323 | eisa_driver_unregister(&advansys_eisa_driver); | ||
14324 | unregister_vlb: | ||
14325 | isa_unregister_driver(&advansys_vlb_driver); | ||
14326 | unregister_isa: | ||
14327 | isa_unregister_driver(&advansys_isa_driver); | ||
14328 | fail: | ||
14329 | return error; | ||
14330 | } | ||
14331 | |||
14332 | static void __exit advansys_exit(void) | ||
14333 | { | ||
14334 | pci_unregister_driver(&advansys_pci_driver); | ||
14335 | eisa_driver_unregister(&advansys_eisa_driver); | ||
14336 | isa_unregister_driver(&advansys_vlb_driver); | ||
14337 | isa_unregister_driver(&advansys_isa_driver); | ||
14338 | } | ||
14339 | |||
14340 | module_init(advansys_init); | ||
14341 | module_exit(advansys_exit); | ||
14342 | |||
14343 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c index d30a30786dda..f08e71e0205a 100644 --- a/drivers/scsi/aha152x.c +++ b/drivers/scsi/aha152x.c | |||
@@ -907,9 +907,10 @@ out_host_put: | |||
907 | 907 | ||
908 | void aha152x_release(struct Scsi_Host *shpnt) | 908 | void aha152x_release(struct Scsi_Host *shpnt) |
909 | { | 909 | { |
910 | if(!shpnt) | 910 | if (!shpnt) |
911 | return; | 911 | return; |
912 | 912 | ||
913 | scsi_remove_host(shpnt); | ||
913 | if (shpnt->irq) | 914 | if (shpnt->irq) |
914 | free_irq(shpnt->irq, shpnt); | 915 | free_irq(shpnt->irq, shpnt); |
915 | 916 | ||
@@ -923,7 +924,6 @@ void aha152x_release(struct Scsi_Host *shpnt) | |||
923 | pnp_device_detach(HOSTDATA(shpnt)->pnpdev); | 924 | pnp_device_detach(HOSTDATA(shpnt)->pnpdev); |
924 | #endif | 925 | #endif |
925 | 926 | ||
926 | scsi_remove_host(shpnt); | ||
927 | list_del(&HOSTDATA(shpnt)->host_list); | 927 | list_del(&HOSTDATA(shpnt)->host_list); |
928 | scsi_host_put(shpnt); | 928 | scsi_host_put(shpnt); |
929 | } | 929 | } |
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c index 4998bb850c49..1a71b0236c97 100644 --- a/drivers/scsi/aic7xxx_old.c +++ b/drivers/scsi/aic7xxx_old.c | |||
@@ -8416,10 +8416,9 @@ aic7xxx_alloc(struct scsi_host_template *sht, struct aic7xxx_host *temp) | |||
8416 | *p = *temp; | 8416 | *p = *temp; |
8417 | p->host = host; | 8417 | p->host = host; |
8418 | 8418 | ||
8419 | p->scb_data = kmalloc(sizeof(scb_data_type), GFP_ATOMIC); | 8419 | p->scb_data = kzalloc(sizeof(scb_data_type), GFP_ATOMIC); |
8420 | if (p->scb_data != NULL) | 8420 | if (!p->scb_data) |
8421 | { | 8421 | { |
8422 | memset(p->scb_data, 0, sizeof(scb_data_type)); | ||
8423 | scbq_init (&p->scb_data->free_scbs); | 8422 | scbq_init (&p->scb_data->free_scbs); |
8424 | } | 8423 | } |
8425 | else | 8424 | else |
@@ -9196,10 +9195,9 @@ aic7xxx_detect(struct scsi_host_template *template) | |||
9196 | printk(KERN_INFO " this driver, we are ignoring it.\n"); | 9195 | printk(KERN_INFO " this driver, we are ignoring it.\n"); |
9197 | } | 9196 | } |
9198 | } | 9197 | } |
9199 | else if ( (temp_p = kmalloc(sizeof(struct aic7xxx_host), | 9198 | else if ( (temp_p = kzalloc(sizeof(struct aic7xxx_host), |
9200 | GFP_ATOMIC)) != NULL ) | 9199 | GFP_ATOMIC)) != NULL ) |
9201 | { | 9200 | { |
9202 | memset(temp_p, 0, sizeof(struct aic7xxx_host)); | ||
9203 | temp_p->chip = aic_pdevs[i].chip | AHC_PCI; | 9201 | temp_p->chip = aic_pdevs[i].chip | AHC_PCI; |
9204 | temp_p->flags = aic_pdevs[i].flags; | 9202 | temp_p->flags = aic_pdevs[i].flags; |
9205 | temp_p->features = aic_pdevs[i].features; | 9203 | temp_p->features = aic_pdevs[i].features; |
diff --git a/drivers/scsi/aic94xx/aic94xx_hwi.h b/drivers/scsi/aic94xx/aic94xx_hwi.h index c6c3d18222fa..491e5d8a98bc 100644 --- a/drivers/scsi/aic94xx/aic94xx_hwi.h +++ b/drivers/scsi/aic94xx/aic94xx_hwi.h | |||
@@ -40,18 +40,6 @@ | |||
40 | #define ASD_MAX_PHYS 8 | 40 | #define ASD_MAX_PHYS 8 |
41 | #define ASD_PCBA_SN_SIZE 12 | 41 | #define ASD_PCBA_SN_SIZE 12 |
42 | 42 | ||
43 | /* Those are to be further named properly, the "RAZORx" part, and | ||
44 | * subsequently included in include/linux/pci_ids.h. | ||
45 | */ | ||
46 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR10 0x410 | ||
47 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR12 0x412 | ||
48 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR1E 0x41E | ||
49 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR1F 0x41F | ||
50 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR30 0x430 | ||
51 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR32 0x432 | ||
52 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR3E 0x43E | ||
53 | #define PCI_DEVICE_ID_ADAPTEC2_RAZOR3F 0x43F | ||
54 | |||
55 | struct asd_ha_addrspace { | 43 | struct asd_ha_addrspace { |
56 | void __iomem *addr; | 44 | void __iomem *addr; |
57 | unsigned long start; /* pci resource start */ | 45 | unsigned long start; /* pci resource start */ |
diff --git a/drivers/scsi/aic94xx/aic94xx_init.c b/drivers/scsi/aic94xx/aic94xx_init.c index 63bcde246447..b70d6e7f96e9 100644 --- a/drivers/scsi/aic94xx/aic94xx_init.c +++ b/drivers/scsi/aic94xx/aic94xx_init.c | |||
@@ -583,7 +583,7 @@ static int __devinit asd_pci_probe(struct pci_dev *dev, | |||
583 | asd_ha = kzalloc(sizeof(*asd_ha), GFP_KERNEL); | 583 | asd_ha = kzalloc(sizeof(*asd_ha), GFP_KERNEL); |
584 | if (!asd_ha) { | 584 | if (!asd_ha) { |
585 | asd_printk("out of memory\n"); | 585 | asd_printk("out of memory\n"); |
586 | goto Err; | 586 | goto Err_put; |
587 | } | 587 | } |
588 | asd_ha->pcidev = dev; | 588 | asd_ha->pcidev = dev; |
589 | asd_ha->sas_ha.dev = &asd_ha->pcidev->dev; | 589 | asd_ha->sas_ha.dev = &asd_ha->pcidev->dev; |
@@ -600,14 +600,12 @@ static int __devinit asd_pci_probe(struct pci_dev *dev, | |||
600 | shost->max_cmd_len = 16; | 600 | shost->max_cmd_len = 16; |
601 | 601 | ||
602 | err = scsi_add_host(shost, &dev->dev); | 602 | err = scsi_add_host(shost, &dev->dev); |
603 | if (err) { | 603 | if (err) |
604 | scsi_host_put(shost); | ||
605 | goto Err_free; | 604 | goto Err_free; |
606 | } | ||
607 | 605 | ||
608 | err = asd_dev->setup(asd_ha); | 606 | err = asd_dev->setup(asd_ha); |
609 | if (err) | 607 | if (err) |
610 | goto Err_free; | 608 | goto Err_remove; |
611 | 609 | ||
612 | err = -ENODEV; | 610 | err = -ENODEV; |
613 | if (!pci_set_dma_mask(dev, DMA_64BIT_MASK) | 611 | if (!pci_set_dma_mask(dev, DMA_64BIT_MASK) |
@@ -618,14 +616,14 @@ static int __devinit asd_pci_probe(struct pci_dev *dev, | |||
618 | ; | 616 | ; |
619 | else { | 617 | else { |
620 | asd_printk("no suitable DMA mask for %s\n", pci_name(dev)); | 618 | asd_printk("no suitable DMA mask for %s\n", pci_name(dev)); |
621 | goto Err_free; | 619 | goto Err_remove; |
622 | } | 620 | } |
623 | 621 | ||
624 | pci_set_drvdata(dev, asd_ha); | 622 | pci_set_drvdata(dev, asd_ha); |
625 | 623 | ||
626 | err = asd_map_ha(asd_ha); | 624 | err = asd_map_ha(asd_ha); |
627 | if (err) | 625 | if (err) |
628 | goto Err_free; | 626 | goto Err_remove; |
629 | 627 | ||
630 | err = asd_create_ha_caches(asd_ha); | 628 | err = asd_create_ha_caches(asd_ha); |
631 | if (err) | 629 | if (err) |
@@ -692,9 +690,12 @@ Err_free_cache: | |||
692 | asd_destroy_ha_caches(asd_ha); | 690 | asd_destroy_ha_caches(asd_ha); |
693 | Err_unmap: | 691 | Err_unmap: |
694 | asd_unmap_ha(asd_ha); | 692 | asd_unmap_ha(asd_ha); |
693 | Err_remove: | ||
694 | scsi_remove_host(shost); | ||
695 | Err_free: | 695 | Err_free: |
696 | kfree(asd_ha); | 696 | kfree(asd_ha); |
697 | scsi_remove_host(shost); | 697 | Err_put: |
698 | scsi_host_put(shost); | ||
698 | Err: | 699 | Err: |
699 | pci_disable_device(dev); | 700 | pci_disable_device(dev); |
700 | return err; | 701 | return err; |
@@ -829,22 +830,15 @@ static struct sas_domain_function_template aic94xx_transport_functions = { | |||
829 | }; | 830 | }; |
830 | 831 | ||
831 | static const struct pci_device_id aic94xx_pci_table[] __devinitdata = { | 832 | static const struct pci_device_id aic94xx_pci_table[] __devinitdata = { |
832 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR10), | 833 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x410),0, 0, 1}, |
833 | 0, 0, 1}, | 834 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x412),0, 0, 1}, |
834 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR12), | 835 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x416),0, 0, 1}, |
835 | 0, 0, 1}, | 836 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x41E),0, 0, 1}, |
836 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1E), | 837 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x41F),0, 0, 1}, |
837 | 0, 0, 1}, | 838 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x430),0, 0, 2}, |
838 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR1F), | 839 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x432),0, 0, 2}, |
839 | 0, 0, 1}, | 840 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x43E),0, 0, 2}, |
840 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR30), | 841 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, 0x43F),0, 0, 2}, |
841 | 0, 0, 2}, | ||
842 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR32), | ||
843 | 0, 0, 2}, | ||
844 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR3E), | ||
845 | 0, 0, 2}, | ||
846 | {PCI_DEVICE(PCI_VENDOR_ID_ADAPTEC2, PCI_DEVICE_ID_ADAPTEC2_RAZOR3F), | ||
847 | 0, 0, 2}, | ||
848 | {} | 842 | {} |
849 | }; | 843 | }; |
850 | 844 | ||
diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c index ab13824df856..f2b23e01401a 100644 --- a/drivers/scsi/aic94xx/aic94xx_task.c +++ b/drivers/scsi/aic94xx/aic94xx_task.c | |||
@@ -207,7 +207,7 @@ static void asd_get_response_tasklet(struct asd_ascb *ascb, | |||
207 | "stat(0x%x) is not CHECK_CONDITION" | 207 | "stat(0x%x) is not CHECK_CONDITION" |
208 | "\n", | 208 | "\n", |
209 | SAS_ADDR(task->dev->sas_addr), | 209 | SAS_ADDR(task->dev->sas_addr), |
210 | ts->stat); | 210 | iu->status); |
211 | } | 211 | } |
212 | } | 212 | } |
213 | } else { | 213 | } else { |
diff --git a/drivers/scsi/arcmsr/arcmsr.h b/drivers/scsi/arcmsr/arcmsr.h index f0b8bf4534f0..ace7a15b413e 100644 --- a/drivers/scsi/arcmsr/arcmsr.h +++ b/drivers/scsi/arcmsr/arcmsr.h | |||
@@ -9,7 +9,7 @@ | |||
9 | ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved. | 9 | ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved. |
10 | ** | 10 | ** |
11 | ** Web site: www.areca.com.tw | 11 | ** Web site: www.areca.com.tw |
12 | ** E-mail: erich@areca.com.tw | 12 | ** E-mail: support@areca.com.tw |
13 | ** | 13 | ** |
14 | ** This program is free software; you can redistribute it and/or modify | 14 | ** This program is free software; you can redistribute it and/or modify |
15 | ** it under the terms of the GNU General Public License version 2 as | 15 | ** it under the terms of the GNU General Public License version 2 as |
@@ -45,19 +45,26 @@ | |||
45 | #include <linux/interrupt.h> | 45 | #include <linux/interrupt.h> |
46 | 46 | ||
47 | struct class_device_attribute; | 47 | struct class_device_attribute; |
48 | 48 | /*The limit of outstanding scsi command that firmware can handle*/ | |
49 | #define ARCMSR_MAX_OUTSTANDING_CMD 256 | 49 | #define ARCMSR_MAX_OUTSTANDING_CMD 256 |
50 | #define ARCMSR_MAX_FREECCB_NUM 288 | 50 | #define ARCMSR_MAX_FREECCB_NUM 320 |
51 | #define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.14" | 51 | #define ARCMSR_DRIVER_VERSION "Driver Version 1.20.00.15 2007/08/30" |
52 | #define ARCMSR_SCSI_INITIATOR_ID 255 | 52 | #define ARCMSR_SCSI_INITIATOR_ID 255 |
53 | #define ARCMSR_MAX_XFER_SECTORS 512 | 53 | #define ARCMSR_MAX_XFER_SECTORS 512 |
54 | #define ARCMSR_MAX_XFER_SECTORS_B 4096 | 54 | #define ARCMSR_MAX_XFER_SECTORS_B 4096 |
55 | #define ARCMSR_MAX_TARGETID 17 | 55 | #define ARCMSR_MAX_TARGETID 17 |
56 | #define ARCMSR_MAX_TARGETLUN 8 | 56 | #define ARCMSR_MAX_TARGETLUN 8 |
57 | #define ARCMSR_MAX_CMD_PERLUN ARCMSR_MAX_OUTSTANDING_CMD | 57 | #define ARCMSR_MAX_CMD_PERLUN ARCMSR_MAX_OUTSTANDING_CMD |
58 | #define ARCMSR_MAX_QBUFFER 4096 | 58 | #define ARCMSR_MAX_QBUFFER 4096 |
59 | #define ARCMSR_MAX_SG_ENTRIES 38 | 59 | #define ARCMSR_MAX_SG_ENTRIES 38 |
60 | 60 | #define ARCMSR_MAX_HBB_POSTQUEUE 264 | |
61 | /* | ||
62 | ********************************************************************************** | ||
63 | ** | ||
64 | ********************************************************************************** | ||
65 | */ | ||
66 | #define ARC_SUCCESS 0 | ||
67 | #define ARC_FAILURE 1 | ||
61 | /* | 68 | /* |
62 | ******************************************************************************* | 69 | ******************************************************************************* |
63 | ** split 64bits dma addressing | 70 | ** split 64bits dma addressing |
@@ -90,7 +97,7 @@ struct CMD_MESSAGE_FIELD | |||
90 | uint8_t messagedatabuffer[1032]; | 97 | uint8_t messagedatabuffer[1032]; |
91 | }; | 98 | }; |
92 | /* IOP message transfer */ | 99 | /* IOP message transfer */ |
93 | #define ARCMSR_MESSAGE_FAIL 0x0001 | 100 | #define ARCMSR_MESSAGE_FAIL 0x0001 |
94 | /* DeviceType */ | 101 | /* DeviceType */ |
95 | #define ARECA_SATA_RAID 0x90000000 | 102 | #define ARECA_SATA_RAID 0x90000000 |
96 | /* FunctionCode */ | 103 | /* FunctionCode */ |
@@ -163,27 +170,27 @@ struct QBUFFER | |||
163 | }; | 170 | }; |
164 | /* | 171 | /* |
165 | ******************************************************************************* | 172 | ******************************************************************************* |
166 | ** FIRMWARE INFO | 173 | ** FIRMWARE INFO for Intel IOP R 80331 processor (Type A) |
167 | ******************************************************************************* | 174 | ******************************************************************************* |
168 | */ | 175 | */ |
169 | struct FIRMWARE_INFO | 176 | struct FIRMWARE_INFO |
170 | { | 177 | { |
171 | uint32_t signature; /*0, 00-03*/ | 178 | uint32_t signature; /*0, 00-03*/ |
172 | uint32_t request_len; /*1, 04-07*/ | 179 | uint32_t request_len; /*1, 04-07*/ |
173 | uint32_t numbers_queue; /*2, 08-11*/ | 180 | uint32_t numbers_queue; /*2, 08-11*/ |
174 | uint32_t sdram_size; /*3, 12-15*/ | 181 | uint32_t sdram_size; /*3, 12-15*/ |
175 | uint32_t ide_channels; /*4, 16-19*/ | 182 | uint32_t ide_channels; /*4, 16-19*/ |
176 | char vendor[40]; /*5, 20-59*/ | 183 | char vendor[40]; /*5, 20-59*/ |
177 | char model[8]; /*15, 60-67*/ | 184 | char model[8]; /*15, 60-67*/ |
178 | char firmware_ver[16]; /*17, 68-83*/ | 185 | char firmware_ver[16]; /*17, 68-83*/ |
179 | char device_map[16]; /*21, 84-99*/ | 186 | char device_map[16]; /*21, 84-99*/ |
180 | }; | 187 | }; |
181 | /* signature of set and get firmware config */ | 188 | /* signature of set and get firmware config */ |
182 | #define ARCMSR_SIGNATURE_GET_CONFIG 0x87974060 | 189 | #define ARCMSR_SIGNATURE_GET_CONFIG 0x87974060 |
183 | #define ARCMSR_SIGNATURE_SET_CONFIG 0x87974063 | 190 | #define ARCMSR_SIGNATURE_SET_CONFIG 0x87974063 |
184 | /* message code of inbound message register */ | 191 | /* message code of inbound message register */ |
185 | #define ARCMSR_INBOUND_MESG0_NOP 0x00000000 | 192 | #define ARCMSR_INBOUND_MESG0_NOP 0x00000000 |
186 | #define ARCMSR_INBOUND_MESG0_GET_CONFIG 0x00000001 | 193 | #define ARCMSR_INBOUND_MESG0_GET_CONFIG 0x00000001 |
187 | #define ARCMSR_INBOUND_MESG0_SET_CONFIG 0x00000002 | 194 | #define ARCMSR_INBOUND_MESG0_SET_CONFIG 0x00000002 |
188 | #define ARCMSR_INBOUND_MESG0_ABORT_CMD 0x00000003 | 195 | #define ARCMSR_INBOUND_MESG0_ABORT_CMD 0x00000003 |
189 | #define ARCMSR_INBOUND_MESG0_STOP_BGRB 0x00000004 | 196 | #define ARCMSR_INBOUND_MESG0_STOP_BGRB 0x00000004 |
@@ -203,6 +210,60 @@ struct FIRMWARE_INFO | |||
203 | #define ARCMSR_CCBREPLY_FLAG_ERROR 0x10000000 | 210 | #define ARCMSR_CCBREPLY_FLAG_ERROR 0x10000000 |
204 | /* outbound firmware ok */ | 211 | /* outbound firmware ok */ |
205 | #define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK 0x80000000 | 212 | #define ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK 0x80000000 |
213 | |||
214 | /* | ||
215 | ************************************************************************ | ||
216 | ** SPEC. for Areca Type B adapter | ||
217 | ************************************************************************ | ||
218 | */ | ||
219 | /* ARECA HBB COMMAND for its FIRMWARE */ | ||
220 | /* window of "instruction flags" from driver to iop */ | ||
221 | #define ARCMSR_DRV2IOP_DOORBELL 0x00020400 | ||
222 | #define ARCMSR_DRV2IOP_DOORBELL_MASK 0x00020404 | ||
223 | /* window of "instruction flags" from iop to driver */ | ||
224 | #define ARCMSR_IOP2DRV_DOORBELL 0x00020408 | ||
225 | #define ARCMSR_IOP2DRV_DOORBELL_MASK 0x0002040C | ||
226 | /* ARECA FLAG LANGUAGE */ | ||
227 | /* ioctl transfer */ | ||
228 | #define ARCMSR_IOP2DRV_DATA_WRITE_OK 0x00000001 | ||
229 | /* ioctl transfer */ | ||
230 | #define ARCMSR_IOP2DRV_DATA_READ_OK 0x00000002 | ||
231 | #define ARCMSR_IOP2DRV_CDB_DONE 0x00000004 | ||
232 | #define ARCMSR_IOP2DRV_MESSAGE_CMD_DONE 0x00000008 | ||
233 | |||
234 | #define ARCMSR_DOORBELL_HANDLE_INT 0x0000000F | ||
235 | #define ARCMSR_DOORBELL_INT_CLEAR_PATTERN 0xFF00FFF0 | ||
236 | #define ARCMSR_MESSAGE_INT_CLEAR_PATTERN 0xFF00FFF7 | ||
237 | /* (ARCMSR_INBOUND_MESG0_GET_CONFIG<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */ | ||
238 | #define ARCMSR_MESSAGE_GET_CONFIG 0x00010008 | ||
239 | /* (ARCMSR_INBOUND_MESG0_SET_CONFIG<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */ | ||
240 | #define ARCMSR_MESSAGE_SET_CONFIG 0x00020008 | ||
241 | /* (ARCMSR_INBOUND_MESG0_ABORT_CMD<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */ | ||
242 | #define ARCMSR_MESSAGE_ABORT_CMD 0x00030008 | ||
243 | /* (ARCMSR_INBOUND_MESG0_STOP_BGRB<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */ | ||
244 | #define ARCMSR_MESSAGE_STOP_BGRB 0x00040008 | ||
245 | /* (ARCMSR_INBOUND_MESG0_FLUSH_CACHE<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */ | ||
246 | #define ARCMSR_MESSAGE_FLUSH_CACHE 0x00050008 | ||
247 | /* (ARCMSR_INBOUND_MESG0_START_BGRB<<16)|ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED) */ | ||
248 | #define ARCMSR_MESSAGE_START_BGRB 0x00060008 | ||
249 | #define ARCMSR_MESSAGE_START_DRIVER_MODE 0x000E0008 | ||
250 | #define ARCMSR_MESSAGE_SET_POST_WINDOW 0x000F0008 | ||
251 | /* ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK */ | ||
252 | #define ARCMSR_MESSAGE_FIRMWARE_OK 0x80000000 | ||
253 | /* ioctl transfer */ | ||
254 | #define ARCMSR_DRV2IOP_DATA_WRITE_OK 0x00000001 | ||
255 | /* ioctl transfer */ | ||
256 | #define ARCMSR_DRV2IOP_DATA_READ_OK 0x00000002 | ||
257 | #define ARCMSR_DRV2IOP_CDB_POSTED 0x00000004 | ||
258 | #define ARCMSR_DRV2IOP_MESSAGE_CMD_POSTED 0x00000008 | ||
259 | |||
260 | /* data tunnel buffer between user space program and its firmware */ | ||
261 | /* user space data to iop 128bytes */ | ||
262 | #define ARCMSR_IOCTL_WBUFFER 0x0000fe00 | ||
263 | /* iop data to user space 128bytes */ | ||
264 | #define ARCMSR_IOCTL_RBUFFER 0x0000ff00 | ||
265 | /* iop message_rwbuffer for message command */ | ||
266 | #define ARCMSR_MSGCODE_RWBUFFER 0x0000fa00 | ||
206 | /* | 267 | /* |
207 | ******************************************************************************* | 268 | ******************************************************************************* |
208 | ** ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504) | 269 | ** ARECA SCSI COMMAND DESCRIPTOR BLOCK size 0x1F8 (504) |
@@ -214,7 +275,6 @@ struct ARCMSR_CDB | |||
214 | uint8_t TargetID; | 275 | uint8_t TargetID; |
215 | uint8_t LUN; | 276 | uint8_t LUN; |
216 | uint8_t Function; | 277 | uint8_t Function; |
217 | |||
218 | uint8_t CdbLength; | 278 | uint8_t CdbLength; |
219 | uint8_t sgcount; | 279 | uint8_t sgcount; |
220 | uint8_t Flags; | 280 | uint8_t Flags; |
@@ -224,20 +284,18 @@ struct ARCMSR_CDB | |||
224 | #define ARCMSR_CDB_FLAG_SIMPLEQ 0x00 | 284 | #define ARCMSR_CDB_FLAG_SIMPLEQ 0x00 |
225 | #define ARCMSR_CDB_FLAG_HEADQ 0x08 | 285 | #define ARCMSR_CDB_FLAG_HEADQ 0x08 |
226 | #define ARCMSR_CDB_FLAG_ORDEREDQ 0x10 | 286 | #define ARCMSR_CDB_FLAG_ORDEREDQ 0x10 |
227 | uint8_t Reserved1; | ||
228 | 287 | ||
288 | uint8_t Reserved1; | ||
229 | uint32_t Context; | 289 | uint32_t Context; |
230 | uint32_t DataLength; | 290 | uint32_t DataLength; |
231 | |||
232 | uint8_t Cdb[16]; | 291 | uint8_t Cdb[16]; |
233 | |||
234 | uint8_t DeviceStatus; | 292 | uint8_t DeviceStatus; |
235 | #define ARCMSR_DEV_CHECK_CONDITION 0x02 | 293 | #define ARCMSR_DEV_CHECK_CONDITION 0x02 |
236 | #define ARCMSR_DEV_SELECT_TIMEOUT 0xF0 | 294 | #define ARCMSR_DEV_SELECT_TIMEOUT 0xF0 |
237 | #define ARCMSR_DEV_ABORTED 0xF1 | 295 | #define ARCMSR_DEV_ABORTED 0xF1 |
238 | #define ARCMSR_DEV_INIT_FAIL 0xF2 | 296 | #define ARCMSR_DEV_INIT_FAIL 0xF2 |
239 | uint8_t SenseData[15]; | ||
240 | 297 | ||
298 | uint8_t SenseData[15]; | ||
241 | union | 299 | union |
242 | { | 300 | { |
243 | struct SG32ENTRY sg32entry[ARCMSR_MAX_SG_ENTRIES]; | 301 | struct SG32ENTRY sg32entry[ARCMSR_MAX_SG_ENTRIES]; |
@@ -246,10 +304,10 @@ struct ARCMSR_CDB | |||
246 | }; | 304 | }; |
247 | /* | 305 | /* |
248 | ******************************************************************************* | 306 | ******************************************************************************* |
249 | ** Messaging Unit (MU) of the Intel R 80331 I/O processor (80331) | 307 | ** Messaging Unit (MU) of the Intel R 80331 I/O processor(Type A) and Type B processor |
250 | ******************************************************************************* | 308 | ******************************************************************************* |
251 | */ | 309 | */ |
252 | struct MessageUnit | 310 | struct MessageUnit_A |
253 | { | 311 | { |
254 | uint32_t resrved0[4]; /*0000 000F*/ | 312 | uint32_t resrved0[4]; /*0000 000F*/ |
255 | uint32_t inbound_msgaddr0; /*0010 0013*/ | 313 | uint32_t inbound_msgaddr0; /*0010 0013*/ |
@@ -274,6 +332,30 @@ struct MessageUnit | |||
274 | uint32_t message_rbuffer[32]; /*0F00 0F7F 32*/ | 332 | uint32_t message_rbuffer[32]; /*0F00 0F7F 32*/ |
275 | uint32_t reserved6[32]; /*0F80 0FFF 32*/ | 333 | uint32_t reserved6[32]; /*0F80 0FFF 32*/ |
276 | }; | 334 | }; |
335 | |||
336 | struct MessageUnit_B | ||
337 | { | ||
338 | uint32_t post_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; | ||
339 | uint32_t done_qbuffer[ARCMSR_MAX_HBB_POSTQUEUE]; | ||
340 | uint32_t postq_index; | ||
341 | uint32_t doneq_index; | ||
342 | uint32_t *drv2iop_doorbell_reg; | ||
343 | uint32_t *drv2iop_doorbell_mask_reg; | ||
344 | uint32_t *iop2drv_doorbell_reg; | ||
345 | uint32_t *iop2drv_doorbell_mask_reg; | ||
346 | uint32_t *msgcode_rwbuffer_reg; | ||
347 | uint32_t *ioctl_wbuffer_reg; | ||
348 | uint32_t *ioctl_rbuffer_reg; | ||
349 | }; | ||
350 | |||
351 | struct MessageUnit | ||
352 | { | ||
353 | union | ||
354 | { | ||
355 | struct MessageUnit_A pmu_A; | ||
356 | struct MessageUnit_B pmu_B; | ||
357 | } u; | ||
358 | }; | ||
277 | /* | 359 | /* |
278 | ******************************************************************************* | 360 | ******************************************************************************* |
279 | ** Adapter Control Block | 361 | ** Adapter Control Block |
@@ -281,37 +363,45 @@ struct MessageUnit | |||
281 | */ | 363 | */ |
282 | struct AdapterControlBlock | 364 | struct AdapterControlBlock |
283 | { | 365 | { |
366 | uint32_t adapter_type; /* adapter A,B..... */ | ||
367 | #define ACB_ADAPTER_TYPE_A 0x00000001 /* hba I IOP */ | ||
368 | #define ACB_ADAPTER_TYPE_B 0x00000002 /* hbb M IOP */ | ||
369 | #define ACB_ADAPTER_TYPE_C 0x00000004 /* hbc P IOP */ | ||
370 | #define ACB_ADAPTER_TYPE_D 0x00000008 /* hbd A IOP */ | ||
284 | struct pci_dev * pdev; | 371 | struct pci_dev * pdev; |
285 | struct Scsi_Host * host; | 372 | struct Scsi_Host * host; |
286 | unsigned long vir2phy_offset; | 373 | unsigned long vir2phy_offset; |
287 | /* Offset is used in making arc cdb physical to virtual calculations */ | 374 | /* Offset is used in making arc cdb physical to virtual calculations */ |
288 | uint32_t outbound_int_enable; | 375 | uint32_t outbound_int_enable; |
289 | 376 | ||
290 | struct MessageUnit __iomem * pmu; | 377 | struct MessageUnit * pmu; |
291 | /* message unit ATU inbound base address0 */ | 378 | /* message unit ATU inbound base address0 */ |
292 | 379 | ||
293 | uint32_t acb_flags; | 380 | uint32_t acb_flags; |
294 | #define ACB_F_SCSISTOPADAPTER 0x0001 | 381 | #define ACB_F_SCSISTOPADAPTER 0x0001 |
295 | #define ACB_F_MSG_STOP_BGRB 0x0002 | 382 | #define ACB_F_MSG_STOP_BGRB 0x0002 |
296 | /* stop RAID background rebuild */ | 383 | /* stop RAID background rebuild */ |
297 | #define ACB_F_MSG_START_BGRB 0x0004 | 384 | #define ACB_F_MSG_START_BGRB 0x0004 |
298 | /* stop RAID background rebuild */ | 385 | /* stop RAID background rebuild */ |
299 | #define ACB_F_IOPDATA_OVERFLOW 0x0008 | 386 | #define ACB_F_IOPDATA_OVERFLOW 0x0008 |
300 | /* iop message data rqbuffer overflow */ | 387 | /* iop message data rqbuffer overflow */ |
301 | #define ACB_F_MESSAGE_WQBUFFER_CLEARED 0x0010 | 388 | #define ACB_F_MESSAGE_WQBUFFER_CLEARED 0x0010 |
302 | /* message clear wqbuffer */ | 389 | /* message clear wqbuffer */ |
303 | #define ACB_F_MESSAGE_RQBUFFER_CLEARED 0x0020 | 390 | #define ACB_F_MESSAGE_RQBUFFER_CLEARED 0x0020 |
304 | /* message clear rqbuffer */ | 391 | /* message clear rqbuffer */ |
305 | #define ACB_F_MESSAGE_WQBUFFER_READED 0x0040 | 392 | #define ACB_F_MESSAGE_WQBUFFER_READED 0x0040 |
306 | #define ACB_F_BUS_RESET 0x0080 | 393 | #define ACB_F_BUS_RESET 0x0080 |
307 | #define ACB_F_IOP_INITED 0x0100 | 394 | #define ACB_F_IOP_INITED 0x0100 |
308 | /* iop init */ | 395 | /* iop init */ |
309 | 396 | ||
310 | struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM]; | 397 | struct CommandControlBlock * pccb_pool[ARCMSR_MAX_FREECCB_NUM]; |
311 | /* used for memory free */ | 398 | /* used for memory free */ |
312 | struct list_head ccb_free_list; | 399 | struct list_head ccb_free_list; |
313 | /* head of free ccb list */ | 400 | /* head of free ccb list */ |
401 | |||
314 | atomic_t ccboutstandingcount; | 402 | atomic_t ccboutstandingcount; |
403 | /*The present outstanding command number that in the IOP that | ||
404 | waiting for being handled by FW*/ | ||
315 | 405 | ||
316 | void * dma_coherent; | 406 | void * dma_coherent; |
317 | /* dma_coherent used for memory free */ | 407 | /* dma_coherent used for memory free */ |
@@ -353,7 +443,7 @@ struct CommandControlBlock | |||
353 | { | 443 | { |
354 | struct ARCMSR_CDB arcmsr_cdb; | 444 | struct ARCMSR_CDB arcmsr_cdb; |
355 | /* | 445 | /* |
356 | ** 0-503 (size of CDB=504): | 446 | ** 0-503 (size of CDB = 504): |
357 | ** arcmsr messenger scsi command descriptor size 504 bytes | 447 | ** arcmsr messenger scsi command descriptor size 504 bytes |
358 | */ | 448 | */ |
359 | uint32_t cdb_shifted_phyaddr; | 449 | uint32_t cdb_shifted_phyaddr; |
@@ -466,7 +556,9 @@ struct SENSE_DATA | |||
466 | #define ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE 0x01 | 556 | #define ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE 0x01 |
467 | #define ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE 0x1F | 557 | #define ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE 0x1F |
468 | 558 | ||
469 | extern void arcmsr_post_Qbuffer(struct AdapterControlBlock *acb); | 559 | extern void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *); |
560 | extern void arcmsr_iop_message_read(struct AdapterControlBlock *); | ||
561 | extern struct QBUFFER *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *); | ||
470 | extern struct class_device_attribute *arcmsr_host_attrs[]; | 562 | extern struct class_device_attribute *arcmsr_host_attrs[]; |
471 | extern int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *acb); | 563 | extern int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *); |
472 | void arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb); | 564 | void arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb); |
diff --git a/drivers/scsi/arcmsr/arcmsr_attr.c b/drivers/scsi/arcmsr/arcmsr_attr.c index 06c0dce3b839..d04d1aa28fa4 100644 --- a/drivers/scsi/arcmsr/arcmsr_attr.c +++ b/drivers/scsi/arcmsr/arcmsr_attr.c | |||
@@ -8,7 +8,7 @@ | |||
8 | ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved | 8 | ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved |
9 | ** | 9 | ** |
10 | ** Web site: www.areca.com.tw | 10 | ** Web site: www.areca.com.tw |
11 | ** E-mail: erich@areca.com.tw | 11 | ** E-mail: support@areca.com.tw |
12 | ** | 12 | ** |
13 | ** This program is free software; you can redistribute it and/or modify | 13 | ** This program is free software; you can redistribute it and/or modify |
14 | ** it under the terms of the GNU General Public License version 2 as | 14 | ** it under the terms of the GNU General Public License version 2 as |
@@ -49,6 +49,7 @@ | |||
49 | #include <linux/init.h> | 49 | #include <linux/init.h> |
50 | #include <linux/errno.h> | 50 | #include <linux/errno.h> |
51 | #include <linux/delay.h> | 51 | #include <linux/delay.h> |
52 | #include <linux/pci.h> | ||
52 | 53 | ||
53 | #include <scsi/scsi_cmnd.h> | 54 | #include <scsi/scsi_cmnd.h> |
54 | #include <scsi/scsi_device.h> | 55 | #include <scsi/scsi_device.h> |
@@ -58,15 +59,14 @@ | |||
58 | 59 | ||
59 | struct class_device_attribute *arcmsr_host_attrs[]; | 60 | struct class_device_attribute *arcmsr_host_attrs[]; |
60 | 61 | ||
61 | static ssize_t | 62 | static ssize_t arcmsr_sysfs_iop_message_read(struct kobject *kobj, |
62 | arcmsr_sysfs_iop_message_read(struct kobject *kobj, | 63 | struct bin_attribute *bin, |
63 | struct bin_attribute *bin_attr, | 64 | char *buf, loff_t off, |
64 | char *buf, loff_t off, size_t count) | 65 | size_t count) |
65 | { | 66 | { |
66 | struct class_device *cdev = container_of(kobj,struct class_device,kobj); | 67 | struct class_device *cdev = container_of(kobj,struct class_device,kobj); |
67 | struct Scsi_Host *host = class_to_shost(cdev); | 68 | struct Scsi_Host *host = class_to_shost(cdev); |
68 | struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; | 69 | struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; |
69 | struct MessageUnit __iomem *reg = acb->pmu; | ||
70 | uint8_t *pQbuffer,*ptmpQbuffer; | 70 | uint8_t *pQbuffer,*ptmpQbuffer; |
71 | int32_t allxfer_len = 0; | 71 | int32_t allxfer_len = 0; |
72 | 72 | ||
@@ -85,12 +85,13 @@ arcmsr_sysfs_iop_message_read(struct kobject *kobj, | |||
85 | allxfer_len++; | 85 | allxfer_len++; |
86 | } | 86 | } |
87 | if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { | 87 | if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { |
88 | struct QBUFFER __iomem * prbuffer = (struct QBUFFER __iomem *) | 88 | struct QBUFFER *prbuffer; |
89 | ®->message_rbuffer; | 89 | uint8_t *iop_data; |
90 | uint8_t __iomem * iop_data = (uint8_t __iomem *)prbuffer->data; | ||
91 | int32_t iop_len; | 90 | int32_t iop_len; |
92 | 91 | ||
93 | acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; | 92 | acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; |
93 | prbuffer = arcmsr_get_iop_rqbuffer(acb); | ||
94 | iop_data = (uint8_t *)prbuffer->data; | ||
94 | iop_len = readl(&prbuffer->data_len); | 95 | iop_len = readl(&prbuffer->data_len); |
95 | while (iop_len > 0) { | 96 | while (iop_len > 0) { |
96 | acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); | 97 | acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); |
@@ -99,16 +100,15 @@ arcmsr_sysfs_iop_message_read(struct kobject *kobj, | |||
99 | iop_data++; | 100 | iop_data++; |
100 | iop_len--; | 101 | iop_len--; |
101 | } | 102 | } |
102 | writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, | 103 | arcmsr_iop_message_read(acb); |
103 | ®->inbound_doorbell); | ||
104 | } | 104 | } |
105 | return (allxfer_len); | 105 | return (allxfer_len); |
106 | } | 106 | } |
107 | 107 | ||
108 | static ssize_t | 108 | static ssize_t arcmsr_sysfs_iop_message_write(struct kobject *kobj, |
109 | arcmsr_sysfs_iop_message_write(struct kobject *kobj, | 109 | struct bin_attribute *bin, |
110 | struct bin_attribute *bin_attr, | 110 | char *buf, loff_t off, |
111 | char *buf, loff_t off, size_t count) | 111 | size_t count) |
112 | { | 112 | { |
113 | struct class_device *cdev = container_of(kobj,struct class_device,kobj); | 113 | struct class_device *cdev = container_of(kobj,struct class_device,kobj); |
114 | struct Scsi_Host *host = class_to_shost(cdev); | 114 | struct Scsi_Host *host = class_to_shost(cdev); |
@@ -126,7 +126,7 @@ arcmsr_sysfs_iop_message_write(struct kobject *kobj, | |||
126 | wqbuf_lastindex = acb->wqbuf_lastindex; | 126 | wqbuf_lastindex = acb->wqbuf_lastindex; |
127 | wqbuf_firstindex = acb->wqbuf_firstindex; | 127 | wqbuf_firstindex = acb->wqbuf_firstindex; |
128 | if (wqbuf_lastindex != wqbuf_firstindex) { | 128 | if (wqbuf_lastindex != wqbuf_firstindex) { |
129 | arcmsr_post_Qbuffer(acb); | 129 | arcmsr_post_ioctldata2iop(acb); |
130 | return 0; /*need retry*/ | 130 | return 0; /*need retry*/ |
131 | } else { | 131 | } else { |
132 | my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) | 132 | my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) |
@@ -144,7 +144,7 @@ arcmsr_sysfs_iop_message_write(struct kobject *kobj, | |||
144 | if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { | 144 | if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { |
145 | acb->acb_flags &= | 145 | acb->acb_flags &= |
146 | ~ACB_F_MESSAGE_WQBUFFER_CLEARED; | 146 | ~ACB_F_MESSAGE_WQBUFFER_CLEARED; |
147 | arcmsr_post_Qbuffer(acb); | 147 | arcmsr_post_ioctldata2iop(acb); |
148 | } | 148 | } |
149 | return count; | 149 | return count; |
150 | } else { | 150 | } else { |
@@ -153,15 +153,14 @@ arcmsr_sysfs_iop_message_write(struct kobject *kobj, | |||
153 | } | 153 | } |
154 | } | 154 | } |
155 | 155 | ||
156 | static ssize_t | 156 | static ssize_t arcmsr_sysfs_iop_message_clear(struct kobject *kobj, |
157 | arcmsr_sysfs_iop_message_clear(struct kobject *kobj, | 157 | struct bin_attribute *bin, |
158 | struct bin_attribute *bin_attr, | 158 | char *buf, loff_t off, |
159 | char *buf, loff_t off, size_t count) | 159 | size_t count) |
160 | { | 160 | { |
161 | struct class_device *cdev = container_of(kobj,struct class_device,kobj); | 161 | struct class_device *cdev = container_of(kobj,struct class_device,kobj); |
162 | struct Scsi_Host *host = class_to_shost(cdev); | 162 | struct Scsi_Host *host = class_to_shost(cdev); |
163 | struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; | 163 | struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; |
164 | struct MessageUnit __iomem *reg = acb->pmu; | ||
165 | uint8_t *pQbuffer; | 164 | uint8_t *pQbuffer; |
166 | 165 | ||
167 | if (!capable(CAP_SYS_ADMIN)) | 166 | if (!capable(CAP_SYS_ADMIN)) |
@@ -169,8 +168,7 @@ arcmsr_sysfs_iop_message_clear(struct kobject *kobj, | |||
169 | 168 | ||
170 | if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { | 169 | if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { |
171 | acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; | 170 | acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; |
172 | writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK | 171 | arcmsr_iop_message_read(acb); |
173 | , ®->inbound_doorbell); | ||
174 | } | 172 | } |
175 | acb->acb_flags |= | 173 | acb->acb_flags |= |
176 | (ACB_F_MESSAGE_WQBUFFER_CLEARED | 174 | (ACB_F_MESSAGE_WQBUFFER_CLEARED |
@@ -191,6 +189,7 @@ static struct bin_attribute arcmsr_sysfs_message_read_attr = { | |||
191 | .attr = { | 189 | .attr = { |
192 | .name = "mu_read", | 190 | .name = "mu_read", |
193 | .mode = S_IRUSR , | 191 | .mode = S_IRUSR , |
192 | .owner = THIS_MODULE, | ||
194 | }, | 193 | }, |
195 | .size = 1032, | 194 | .size = 1032, |
196 | .read = arcmsr_sysfs_iop_message_read, | 195 | .read = arcmsr_sysfs_iop_message_read, |
@@ -200,6 +199,7 @@ static struct bin_attribute arcmsr_sysfs_message_write_attr = { | |||
200 | .attr = { | 199 | .attr = { |
201 | .name = "mu_write", | 200 | .name = "mu_write", |
202 | .mode = S_IWUSR, | 201 | .mode = S_IWUSR, |
202 | .owner = THIS_MODULE, | ||
203 | }, | 203 | }, |
204 | .size = 1032, | 204 | .size = 1032, |
205 | .write = arcmsr_sysfs_iop_message_write, | 205 | .write = arcmsr_sysfs_iop_message_write, |
@@ -209,6 +209,7 @@ static struct bin_attribute arcmsr_sysfs_message_clear_attr = { | |||
209 | .attr = { | 209 | .attr = { |
210 | .name = "mu_clear", | 210 | .name = "mu_clear", |
211 | .mode = S_IWUSR, | 211 | .mode = S_IWUSR, |
212 | .owner = THIS_MODULE, | ||
212 | }, | 213 | }, |
213 | .size = 1, | 214 | .size = 1, |
214 | .write = arcmsr_sysfs_iop_message_clear, | 215 | .write = arcmsr_sysfs_iop_message_clear, |
@@ -219,31 +220,26 @@ int arcmsr_alloc_sysfs_attr(struct AdapterControlBlock *acb) | |||
219 | struct Scsi_Host *host = acb->host; | 220 | struct Scsi_Host *host = acb->host; |
220 | int error; | 221 | int error; |
221 | 222 | ||
222 | error = sysfs_create_bin_file(&host->shost_classdev.kobj, | 223 | error = sysfs_create_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_read_attr); |
223 | &arcmsr_sysfs_message_read_attr); | ||
224 | if (error) { | 224 | if (error) { |
225 | printk(KERN_ERR "arcmsr: alloc sysfs mu_read failed\n"); | 225 | printk(KERN_ERR "arcmsr: alloc sysfs mu_read failed\n"); |
226 | goto error_bin_file_message_read; | 226 | goto error_bin_file_message_read; |
227 | } | 227 | } |
228 | error = sysfs_create_bin_file(&host->shost_classdev.kobj, | 228 | error = sysfs_create_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_write_attr); |
229 | &arcmsr_sysfs_message_write_attr); | ||
230 | if (error) { | 229 | if (error) { |
231 | printk(KERN_ERR "arcmsr: alloc sysfs mu_write failed\n"); | 230 | printk(KERN_ERR "arcmsr: alloc sysfs mu_write failed\n"); |
232 | goto error_bin_file_message_write; | 231 | goto error_bin_file_message_write; |
233 | } | 232 | } |
234 | error = sysfs_create_bin_file(&host->shost_classdev.kobj, | 233 | error = sysfs_create_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_clear_attr); |
235 | &arcmsr_sysfs_message_clear_attr); | ||
236 | if (error) { | 234 | if (error) { |
237 | printk(KERN_ERR "arcmsr: alloc sysfs mu_clear failed\n"); | 235 | printk(KERN_ERR "arcmsr: alloc sysfs mu_clear failed\n"); |
238 | goto error_bin_file_message_clear; | 236 | goto error_bin_file_message_clear; |
239 | } | 237 | } |
240 | return 0; | 238 | return 0; |
241 | error_bin_file_message_clear: | 239 | error_bin_file_message_clear: |
242 | sysfs_remove_bin_file(&host->shost_classdev.kobj, | 240 | sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_write_attr); |
243 | &arcmsr_sysfs_message_write_attr); | ||
244 | error_bin_file_message_write: | 241 | error_bin_file_message_write: |
245 | sysfs_remove_bin_file(&host->shost_classdev.kobj, | 242 | sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_read_attr); |
246 | &arcmsr_sysfs_message_read_attr); | ||
247 | error_bin_file_message_read: | 243 | error_bin_file_message_read: |
248 | return error; | 244 | return error; |
249 | } | 245 | } |
@@ -252,12 +248,9 @@ void | |||
252 | arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb) { | 248 | arcmsr_free_sysfs_attr(struct AdapterControlBlock *acb) { |
253 | struct Scsi_Host *host = acb->host; | 249 | struct Scsi_Host *host = acb->host; |
254 | 250 | ||
255 | sysfs_remove_bin_file(&host->shost_classdev.kobj, | 251 | sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_clear_attr); |
256 | &arcmsr_sysfs_message_clear_attr); | 252 | sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_write_attr); |
257 | sysfs_remove_bin_file(&host->shost_classdev.kobj, | 253 | sysfs_remove_bin_file(&host->shost_classdev.kobj, &arcmsr_sysfs_message_read_attr); |
258 | &arcmsr_sysfs_message_write_attr); | ||
259 | sysfs_remove_bin_file(&host->shost_classdev.kobj, | ||
260 | &arcmsr_sysfs_message_read_attr); | ||
261 | } | 254 | } |
262 | 255 | ||
263 | 256 | ||
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c index 0ddfc21e9f7d..cfcf40159eab 100644 --- a/drivers/scsi/arcmsr/arcmsr_hba.c +++ b/drivers/scsi/arcmsr/arcmsr_hba.c | |||
@@ -9,7 +9,7 @@ | |||
9 | ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved | 9 | ** Copyright (C) 2002 - 2005, Areca Technology Corporation All rights reserved |
10 | ** | 10 | ** |
11 | ** Web site: www.areca.com.tw | 11 | ** Web site: www.areca.com.tw |
12 | ** E-mail: erich@areca.com.tw | 12 | ** E-mail: support@areca.com.tw |
13 | ** | 13 | ** |
14 | ** This program is free software; you can redistribute it and/or modify | 14 | ** This program is free software; you can redistribute it and/or modify |
15 | ** it under the terms of the GNU General Public License version 2 as | 15 | ** it under the terms of the GNU General Public License version 2 as |
@@ -71,33 +71,34 @@ | |||
71 | #include <scsi/scsicam.h> | 71 | #include <scsi/scsicam.h> |
72 | #include "arcmsr.h" | 72 | #include "arcmsr.h" |
73 | 73 | ||
74 | MODULE_AUTHOR("Erich Chen <erich@areca.com.tw>"); | 74 | MODULE_AUTHOR("Erich Chen <support@areca.com.tw>"); |
75 | MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/13xx/16xx) SATA/SAS RAID HOST Adapter"); | 75 | MODULE_DESCRIPTION("ARECA (ARC11xx/12xx/13xx/16xx) SATA/SAS RAID HOST Adapter"); |
76 | MODULE_LICENSE("Dual BSD/GPL"); | 76 | MODULE_LICENSE("Dual BSD/GPL"); |
77 | MODULE_VERSION(ARCMSR_DRIVER_VERSION); | 77 | MODULE_VERSION(ARCMSR_DRIVER_VERSION); |
78 | 78 | ||
79 | static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_cmnd *cmd); | 79 | static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, |
80 | struct scsi_cmnd *cmd); | ||
81 | static int arcmsr_iop_confirm(struct AdapterControlBlock *acb); | ||
80 | static int arcmsr_abort(struct scsi_cmnd *); | 82 | static int arcmsr_abort(struct scsi_cmnd *); |
81 | static int arcmsr_bus_reset(struct scsi_cmnd *); | 83 | static int arcmsr_bus_reset(struct scsi_cmnd *); |
82 | static int arcmsr_bios_param(struct scsi_device *sdev, | 84 | static int arcmsr_bios_param(struct scsi_device *sdev, |
83 | struct block_device *bdev, sector_t capacity, int *info); | 85 | struct block_device *bdev, sector_t capacity, int *info); |
84 | static int arcmsr_queue_command(struct scsi_cmnd * cmd, | 86 | static int arcmsr_queue_command(struct scsi_cmnd *cmd, |
85 | void (*done) (struct scsi_cmnd *)); | 87 | void (*done) (struct scsi_cmnd *)); |
86 | static int arcmsr_probe(struct pci_dev *pdev, | 88 | static int arcmsr_probe(struct pci_dev *pdev, |
87 | const struct pci_device_id *id); | 89 | const struct pci_device_id *id); |
88 | static void arcmsr_remove(struct pci_dev *pdev); | 90 | static void arcmsr_remove(struct pci_dev *pdev); |
89 | static void arcmsr_shutdown(struct pci_dev *pdev); | 91 | static void arcmsr_shutdown(struct pci_dev *pdev); |
90 | static void arcmsr_iop_init(struct AdapterControlBlock *acb); | 92 | static void arcmsr_iop_init(struct AdapterControlBlock *acb); |
91 | static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb); | 93 | static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb); |
94 | static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb); | ||
92 | static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb); | 95 | static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb); |
93 | static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb); | 96 | static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb); |
94 | static uint8_t arcmsr_wait_msgint_ready(struct AdapterControlBlock *acb); | 97 | static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb); |
95 | static const char *arcmsr_info(struct Scsi_Host *); | 98 | static const char *arcmsr_info(struct Scsi_Host *); |
96 | static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb); | 99 | static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb); |
97 | static pci_ers_result_t arcmsr_pci_error_detected(struct pci_dev *pdev, | 100 | static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, |
98 | pci_channel_state_t state); | 101 | int queue_depth) |
99 | static pci_ers_result_t arcmsr_pci_slot_reset(struct pci_dev *pdev); | ||
100 | static int arcmsr_adjust_disk_queue_depth(struct scsi_device *sdev, int queue_depth) | ||
101 | { | 102 | { |
102 | if (queue_depth > ARCMSR_MAX_CMD_PERLUN) | 103 | if (queue_depth > ARCMSR_MAX_CMD_PERLUN) |
103 | queue_depth = ARCMSR_MAX_CMD_PERLUN; | 104 | queue_depth = ARCMSR_MAX_CMD_PERLUN; |
@@ -123,17 +124,25 @@ static struct scsi_host_template arcmsr_scsi_host_template = { | |||
123 | .use_clustering = ENABLE_CLUSTERING, | 124 | .use_clustering = ENABLE_CLUSTERING, |
124 | .shost_attrs = arcmsr_host_attrs, | 125 | .shost_attrs = arcmsr_host_attrs, |
125 | }; | 126 | }; |
127 | #ifdef CONFIG_SCSI_ARCMSR_AER | ||
128 | static pci_ers_result_t arcmsr_pci_slot_reset(struct pci_dev *pdev); | ||
129 | static pci_ers_result_t arcmsr_pci_error_detected(struct pci_dev *pdev, | ||
130 | pci_channel_state_t state); | ||
131 | |||
126 | static struct pci_error_handlers arcmsr_pci_error_handlers = { | 132 | static struct pci_error_handlers arcmsr_pci_error_handlers = { |
127 | .error_detected = arcmsr_pci_error_detected, | 133 | .error_detected = arcmsr_pci_error_detected, |
128 | .slot_reset = arcmsr_pci_slot_reset, | 134 | .slot_reset = arcmsr_pci_slot_reset, |
129 | }; | 135 | }; |
130 | 136 | #endif | |
131 | static struct pci_device_id arcmsr_device_id_table[] = { | 137 | static struct pci_device_id arcmsr_device_id_table[] = { |
132 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110)}, | 138 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1110)}, |
133 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1120)}, | 139 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1120)}, |
134 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1130)}, | 140 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1130)}, |
135 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1160)}, | 141 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1160)}, |
136 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1170)}, | 142 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1170)}, |
143 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1200)}, | ||
144 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1201)}, | ||
145 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1202)}, | ||
137 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1210)}, | 146 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1210)}, |
138 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1220)}, | 147 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1220)}, |
139 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1230)}, | 148 | {PCI_DEVICE(PCI_VENDOR_ID_ARECA, PCI_DEVICE_ID_ARECA_1230)}, |
@@ -153,20 +162,20 @@ static struct pci_driver arcmsr_pci_driver = { | |||
153 | .probe = arcmsr_probe, | 162 | .probe = arcmsr_probe, |
154 | .remove = arcmsr_remove, | 163 | .remove = arcmsr_remove, |
155 | .shutdown = arcmsr_shutdown, | 164 | .shutdown = arcmsr_shutdown, |
165 | #ifdef CONFIG_SCSI_ARCMSR_AER | ||
156 | .err_handler = &arcmsr_pci_error_handlers, | 166 | .err_handler = &arcmsr_pci_error_handlers, |
167 | #endif | ||
157 | }; | 168 | }; |
158 | 169 | ||
159 | static irqreturn_t arcmsr_do_interrupt(int irq, void *dev_id) | 170 | static irqreturn_t arcmsr_do_interrupt(int irq, void *dev_id) |
160 | { | 171 | { |
161 | irqreturn_t handle_state; | 172 | irqreturn_t handle_state; |
162 | struct AdapterControlBlock *acb; | 173 | struct AdapterControlBlock *acb = dev_id; |
163 | unsigned long flags; | ||
164 | 174 | ||
165 | acb = (struct AdapterControlBlock *)dev_id; | 175 | spin_lock(acb->host->host_lock); |
166 | |||
167 | spin_lock_irqsave(acb->host->host_lock, flags); | ||
168 | handle_state = arcmsr_interrupt(acb); | 176 | handle_state = arcmsr_interrupt(acb); |
169 | spin_unlock_irqrestore(acb->host->host_lock, flags); | 177 | spin_unlock(acb->host->host_lock); |
178 | |||
170 | return handle_state; | 179 | return handle_state; |
171 | } | 180 | } |
172 | 181 | ||
@@ -198,68 +207,159 @@ static int arcmsr_bios_param(struct scsi_device *sdev, | |||
198 | return 0; | 207 | return 0; |
199 | } | 208 | } |
200 | 209 | ||
201 | static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) | 210 | static void arcmsr_define_adapter_type(struct AdapterControlBlock *acb) |
202 | { | 211 | { |
203 | struct pci_dev *pdev = acb->pdev; | 212 | struct pci_dev *pdev = acb->pdev; |
204 | struct MessageUnit __iomem *reg = acb->pmu; | 213 | u16 dev_id; |
205 | u32 ccb_phyaddr_hi32; | 214 | pci_read_config_word(pdev, PCI_DEVICE_ID, &dev_id); |
206 | void *dma_coherent; | 215 | switch (dev_id) { |
207 | dma_addr_t dma_coherent_handle, dma_addr; | 216 | case 0x1201 : { |
208 | struct CommandControlBlock *ccb_tmp; | 217 | acb->adapter_type = ACB_ADAPTER_TYPE_B; |
209 | int i, j; | 218 | } |
219 | break; | ||
220 | |||
221 | default : acb->adapter_type = ACB_ADAPTER_TYPE_A; | ||
222 | } | ||
223 | } | ||
224 | |||
225 | static int arcmsr_alloc_ccb_pool(struct AdapterControlBlock *acb) | ||
226 | { | ||
227 | |||
228 | switch (acb->adapter_type) { | ||
229 | |||
230 | case ACB_ADAPTER_TYPE_A: { | ||
231 | struct pci_dev *pdev = acb->pdev; | ||
232 | void *dma_coherent; | ||
233 | dma_addr_t dma_coherent_handle, dma_addr; | ||
234 | struct CommandControlBlock *ccb_tmp; | ||
235 | uint32_t intmask_org; | ||
236 | int i, j; | ||
237 | |||
238 | acb->pmu = ioremap(pci_resource_start(pdev, 0), pci_resource_len(pdev, 0)); | ||
239 | if (!acb->pmu) { | ||
240 | printk(KERN_NOTICE "arcmsr%d: memory mapping region fail \n", | ||
241 | acb->host->host_no); | ||
242 | } | ||
210 | 243 | ||
211 | dma_coherent = dma_alloc_coherent(&pdev->dev, | 244 | dma_coherent = dma_alloc_coherent(&pdev->dev, |
212 | ARCMSR_MAX_FREECCB_NUM * | 245 | ARCMSR_MAX_FREECCB_NUM * |
213 | sizeof (struct CommandControlBlock) + 0x20, | 246 | sizeof (struct CommandControlBlock) + 0x20, |
214 | &dma_coherent_handle, GFP_KERNEL); | 247 | &dma_coherent_handle, GFP_KERNEL); |
215 | if (!dma_coherent) | 248 | if (!dma_coherent) |
216 | return -ENOMEM; | 249 | return -ENOMEM; |
217 | 250 | ||
218 | acb->dma_coherent = dma_coherent; | 251 | acb->dma_coherent = dma_coherent; |
219 | acb->dma_coherent_handle = dma_coherent_handle; | 252 | acb->dma_coherent_handle = dma_coherent_handle; |
220 | 253 | ||
221 | if (((unsigned long)dma_coherent & 0x1F)) { | 254 | if (((unsigned long)dma_coherent & 0x1F)) { |
222 | dma_coherent = dma_coherent + | 255 | dma_coherent = dma_coherent + |
223 | (0x20 - ((unsigned long)dma_coherent & 0x1F)); | 256 | (0x20 - ((unsigned long)dma_coherent & 0x1F)); |
224 | dma_coherent_handle = dma_coherent_handle + | 257 | dma_coherent_handle = dma_coherent_handle + |
225 | (0x20 - ((unsigned long)dma_coherent_handle & 0x1F)); | 258 | (0x20 - ((unsigned long)dma_coherent_handle & 0x1F)); |
226 | } | 259 | } |
227 | 260 | ||
228 | dma_addr = dma_coherent_handle; | 261 | dma_addr = dma_coherent_handle; |
229 | ccb_tmp = (struct CommandControlBlock *)dma_coherent; | 262 | ccb_tmp = (struct CommandControlBlock *)dma_coherent; |
230 | for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { | 263 | for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { |
231 | ccb_tmp->cdb_shifted_phyaddr = dma_addr >> 5; | 264 | ccb_tmp->cdb_shifted_phyaddr = dma_addr >> 5; |
232 | ccb_tmp->acb = acb; | 265 | ccb_tmp->acb = acb; |
233 | acb->pccb_pool[i] = ccb_tmp; | 266 | acb->pccb_pool[i] = ccb_tmp; |
234 | list_add_tail(&ccb_tmp->list, &acb->ccb_free_list); | 267 | list_add_tail(&ccb_tmp->list, &acb->ccb_free_list); |
235 | dma_addr = dma_addr + sizeof (struct CommandControlBlock); | 268 | dma_addr = dma_addr + sizeof(struct CommandControlBlock); |
236 | ccb_tmp++; | 269 | ccb_tmp++; |
237 | } | 270 | } |
238 | 271 | ||
239 | acb->vir2phy_offset = (unsigned long)ccb_tmp - | 272 | acb->vir2phy_offset = (unsigned long)ccb_tmp -(unsigned long)dma_addr; |
240 | (unsigned long)dma_addr; | 273 | for (i = 0; i < ARCMSR_MAX_TARGETID; i++) |
241 | for (i = 0; i < ARCMSR_MAX_TARGETID; i++) | 274 | for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++) |
242 | for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++) | 275 | acb->devstate[i][j] = ARECA_RAID_GONE; |
243 | acb->devstate[i][j] = ARECA_RAID_GOOD; | ||
244 | 276 | ||
245 | /* | 277 | /* |
246 | ** here we need to tell iop 331 our ccb_tmp.HighPart | 278 | ** here we need to tell iop 331 our ccb_tmp.HighPart |
247 | ** if ccb_tmp.HighPart is not zero | 279 | ** if ccb_tmp.HighPart is not zero |
248 | */ | 280 | */ |
249 | ccb_phyaddr_hi32 = (uint32_t) ((dma_coherent_handle >> 16) >> 16); | 281 | intmask_org = arcmsr_disable_outbound_ints(acb); |
250 | if (ccb_phyaddr_hi32 != 0) { | 282 | } |
251 | writel(ARCMSR_SIGNATURE_SET_CONFIG, ®->message_rwbuffer[0]); | 283 | break; |
252 | writel(ccb_phyaddr_hi32, ®->message_rwbuffer[1]); | 284 | |
253 | writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, ®->inbound_msgaddr0); | 285 | case ACB_ADAPTER_TYPE_B: { |
254 | if (arcmsr_wait_msgint_ready(acb)) | 286 | |
255 | printk(KERN_NOTICE "arcmsr%d: " | 287 | struct pci_dev *pdev = acb->pdev; |
256 | "'set ccb high part physical address' timeout\n", | 288 | struct MessageUnit_B *reg; |
257 | acb->host->host_no); | 289 | void *mem_base0, *mem_base1; |
258 | } | 290 | void *dma_coherent; |
291 | dma_addr_t dma_coherent_handle, dma_addr; | ||
292 | uint32_t intmask_org; | ||
293 | struct CommandControlBlock *ccb_tmp; | ||
294 | int i, j; | ||
295 | |||
296 | dma_coherent = dma_alloc_coherent(&pdev->dev, | ||
297 | ((ARCMSR_MAX_FREECCB_NUM * | ||
298 | sizeof(struct CommandControlBlock) + 0x20) + | ||
299 | sizeof(struct MessageUnit_B)), | ||
300 | &dma_coherent_handle, GFP_KERNEL); | ||
301 | if (!dma_coherent) | ||
302 | return -ENOMEM; | ||
259 | 303 | ||
260 | writel(readl(®->outbound_intmask) | | 304 | acb->dma_coherent = dma_coherent; |
261 | ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, | 305 | acb->dma_coherent_handle = dma_coherent_handle; |
262 | ®->outbound_intmask); | 306 | |
307 | if (((unsigned long)dma_coherent & 0x1F)) { | ||
308 | dma_coherent = dma_coherent + | ||
309 | (0x20 - ((unsigned long)dma_coherent & 0x1F)); | ||
310 | dma_coherent_handle = dma_coherent_handle + | ||
311 | (0x20 - ((unsigned long)dma_coherent_handle & 0x1F)); | ||
312 | } | ||
313 | |||
314 | reg = (struct MessageUnit_B *)(dma_coherent + | ||
315 | ARCMSR_MAX_FREECCB_NUM * sizeof(struct CommandControlBlock)); | ||
316 | |||
317 | dma_addr = dma_coherent_handle; | ||
318 | ccb_tmp = (struct CommandControlBlock *)dma_coherent; | ||
319 | for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { | ||
320 | ccb_tmp->cdb_shifted_phyaddr = dma_addr >> 5; | ||
321 | ccb_tmp->acb = acb; | ||
322 | acb->pccb_pool[i] = ccb_tmp; | ||
323 | list_add_tail(&ccb_tmp->list, &acb->ccb_free_list); | ||
324 | dma_addr = dma_addr + sizeof(struct CommandControlBlock); | ||
325 | ccb_tmp++; | ||
326 | } | ||
327 | |||
328 | reg = (struct MessageUnit_B *)(dma_coherent + | ||
329 | ARCMSR_MAX_FREECCB_NUM * sizeof(struct CommandControlBlock)); | ||
330 | acb->pmu = (struct MessageUnit *)reg; | ||
331 | mem_base0 = ioremap(pci_resource_start(pdev, 0), | ||
332 | pci_resource_len(pdev, 0)); | ||
333 | mem_base1 = ioremap(pci_resource_start(pdev, 2), | ||
334 | pci_resource_len(pdev, 2)); | ||
335 | reg->drv2iop_doorbell_reg = (uint32_t *)((char *)mem_base0 + | ||
336 | ARCMSR_DRV2IOP_DOORBELL); | ||
337 | reg->drv2iop_doorbell_mask_reg = (uint32_t *)((char *)mem_base0 + | ||
338 | ARCMSR_DRV2IOP_DOORBELL_MASK); | ||
339 | reg->iop2drv_doorbell_reg = (uint32_t *)((char *)mem_base0 + | ||
340 | ARCMSR_IOP2DRV_DOORBELL); | ||
341 | reg->iop2drv_doorbell_mask_reg = (uint32_t *)((char *)mem_base0 + | ||
342 | ARCMSR_IOP2DRV_DOORBELL_MASK); | ||
343 | reg->ioctl_wbuffer_reg = (uint32_t *)((char *)mem_base1 + | ||
344 | ARCMSR_IOCTL_WBUFFER); | ||
345 | reg->ioctl_rbuffer_reg = (uint32_t *)((char *)mem_base1 + | ||
346 | ARCMSR_IOCTL_RBUFFER); | ||
347 | reg->msgcode_rwbuffer_reg = (uint32_t *)((char *)mem_base1 + | ||
348 | ARCMSR_MSGCODE_RWBUFFER); | ||
349 | |||
350 | acb->vir2phy_offset = (unsigned long)ccb_tmp -(unsigned long)dma_addr; | ||
351 | for (i = 0; i < ARCMSR_MAX_TARGETID; i++) | ||
352 | for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++) | ||
353 | acb->devstate[i][j] = ARECA_RAID_GOOD; | ||
354 | |||
355 | /* | ||
356 | ** here we need to tell iop 331 our ccb_tmp.HighPart | ||
357 | ** if ccb_tmp.HighPart is not zero | ||
358 | */ | ||
359 | intmask_org = arcmsr_disable_outbound_ints(acb); | ||
360 | } | ||
361 | break; | ||
362 | } | ||
263 | return 0; | 363 | return 0; |
264 | } | 364 | } |
265 | 365 | ||
@@ -310,16 +410,11 @@ static int arcmsr_probe(struct pci_dev *pdev, | |||
310 | host->unique_id = (bus << 8) | dev_fun; | 410 | host->unique_id = (bus << 8) | dev_fun; |
311 | host->irq = pdev->irq; | 411 | host->irq = pdev->irq; |
312 | error = pci_request_regions(pdev, "arcmsr"); | 412 | error = pci_request_regions(pdev, "arcmsr"); |
313 | if (error) | 413 | if (error) { |
314 | goto out_host_put; | 414 | goto out_host_put; |
315 | |||
316 | acb->pmu = ioremap(pci_resource_start(pdev, 0), | ||
317 | pci_resource_len(pdev, 0)); | ||
318 | if (!acb->pmu) { | ||
319 | printk(KERN_NOTICE "arcmsr%d: memory" | ||
320 | " mapping region fail \n", acb->host->host_no); | ||
321 | goto out_release_regions; | ||
322 | } | 415 | } |
416 | arcmsr_define_adapter_type(acb); | ||
417 | |||
323 | acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED | | 418 | acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED | |
324 | ACB_F_MESSAGE_RQBUFFER_CLEARED | | 419 | ACB_F_MESSAGE_RQBUFFER_CLEARED | |
325 | ACB_F_MESSAGE_WQBUFFER_READED); | 420 | ACB_F_MESSAGE_WQBUFFER_READED); |
@@ -328,10 +423,10 @@ static int arcmsr_probe(struct pci_dev *pdev, | |||
328 | 423 | ||
329 | error = arcmsr_alloc_ccb_pool(acb); | 424 | error = arcmsr_alloc_ccb_pool(acb); |
330 | if (error) | 425 | if (error) |
331 | goto out_iounmap; | 426 | goto out_release_regions; |
332 | 427 | ||
333 | error = request_irq(pdev->irq, arcmsr_do_interrupt, | 428 | error = request_irq(pdev->irq, arcmsr_do_interrupt, |
334 | IRQF_DISABLED | IRQF_SHARED, "arcmsr", acb); | 429 | IRQF_SHARED, "arcmsr", acb); |
335 | if (error) | 430 | if (error) |
336 | goto out_free_ccb_pool; | 431 | goto out_free_ccb_pool; |
337 | 432 | ||
@@ -349,14 +444,15 @@ static int arcmsr_probe(struct pci_dev *pdev, | |||
349 | goto out_free_sysfs; | 444 | goto out_free_sysfs; |
350 | 445 | ||
351 | scsi_scan_host(host); | 446 | scsi_scan_host(host); |
447 | #ifdef CONFIG_SCSI_ARCMSR_AER | ||
352 | pci_enable_pcie_error_reporting(pdev); | 448 | pci_enable_pcie_error_reporting(pdev); |
449 | #endif | ||
353 | return 0; | 450 | return 0; |
354 | out_free_sysfs: | 451 | out_free_sysfs: |
355 | out_free_irq: | 452 | out_free_irq: |
356 | free_irq(pdev->irq, acb); | 453 | free_irq(pdev->irq, acb); |
357 | out_free_ccb_pool: | 454 | out_free_ccb_pool: |
358 | arcmsr_free_ccb_pool(acb); | 455 | arcmsr_free_ccb_pool(acb); |
359 | out_iounmap: | ||
360 | iounmap(acb->pmu); | 456 | iounmap(acb->pmu); |
361 | out_release_regions: | 457 | out_release_regions: |
362 | pci_release_regions(pdev); | 458 | pci_release_regions(pdev); |
@@ -368,17 +464,84 @@ static int arcmsr_probe(struct pci_dev *pdev, | |||
368 | return error; | 464 | return error; |
369 | } | 465 | } |
370 | 466 | ||
371 | static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb) | 467 | static uint8_t arcmsr_hba_wait_msgint_ready(struct AdapterControlBlock *acb) |
468 | { | ||
469 | struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; | ||
470 | uint32_t Index; | ||
471 | uint8_t Retries = 0x00; | ||
472 | |||
473 | do { | ||
474 | for (Index = 0; Index < 100; Index++) { | ||
475 | if (readl(®->outbound_intstatus) & | ||
476 | ARCMSR_MU_OUTBOUND_MESSAGE0_INT) { | ||
477 | writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT, | ||
478 | ®->outbound_intstatus); | ||
479 | return 0x00; | ||
480 | } | ||
481 | msleep(10); | ||
482 | }/*max 1 seconds*/ | ||
483 | |||
484 | } while (Retries++ < 20);/*max 20 sec*/ | ||
485 | return 0xff; | ||
486 | } | ||
487 | |||
488 | static uint8_t arcmsr_hbb_wait_msgint_ready(struct AdapterControlBlock *acb) | ||
372 | { | 489 | { |
373 | struct MessageUnit __iomem *reg = acb->pmu; | 490 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; |
491 | uint32_t Index; | ||
492 | uint8_t Retries = 0x00; | ||
493 | |||
494 | do { | ||
495 | for (Index = 0; Index < 100; Index++) { | ||
496 | if (readl(reg->iop2drv_doorbell_reg) | ||
497 | & ARCMSR_IOP2DRV_MESSAGE_CMD_DONE) { | ||
498 | writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN | ||
499 | , reg->iop2drv_doorbell_reg); | ||
500 | return 0x00; | ||
501 | } | ||
502 | msleep(10); | ||
503 | }/*max 1 seconds*/ | ||
504 | |||
505 | } while (Retries++ < 20);/*max 20 sec*/ | ||
506 | return 0xff; | ||
507 | } | ||
508 | |||
509 | static void arcmsr_abort_hba_allcmd(struct AdapterControlBlock *acb) | ||
510 | { | ||
511 | struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; | ||
374 | 512 | ||
375 | writel(ARCMSR_INBOUND_MESG0_ABORT_CMD, ®->inbound_msgaddr0); | 513 | writel(ARCMSR_INBOUND_MESG0_ABORT_CMD, ®->inbound_msgaddr0); |
376 | if (arcmsr_wait_msgint_ready(acb)) | 514 | if (arcmsr_hba_wait_msgint_ready(acb)) |
515 | printk(KERN_NOTICE | ||
516 | "arcmsr%d: wait 'abort all outstanding command' timeout \n" | ||
517 | , acb->host->host_no); | ||
518 | } | ||
519 | |||
520 | static void arcmsr_abort_hbb_allcmd(struct AdapterControlBlock *acb) | ||
521 | { | ||
522 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; | ||
523 | |||
524 | writel(ARCMSR_MESSAGE_ABORT_CMD, reg->drv2iop_doorbell_reg); | ||
525 | if (arcmsr_hbb_wait_msgint_ready(acb)) | ||
377 | printk(KERN_NOTICE | 526 | printk(KERN_NOTICE |
378 | "arcmsr%d: wait 'abort all outstanding command' timeout \n" | 527 | "arcmsr%d: wait 'abort all outstanding command' timeout \n" |
379 | , acb->host->host_no); | 528 | , acb->host->host_no); |
380 | } | 529 | } |
381 | 530 | ||
531 | static void arcmsr_abort_allcmd(struct AdapterControlBlock *acb) | ||
532 | { | ||
533 | switch (acb->adapter_type) { | ||
534 | case ACB_ADAPTER_TYPE_A: { | ||
535 | arcmsr_abort_hba_allcmd(acb); | ||
536 | } | ||
537 | break; | ||
538 | |||
539 | case ACB_ADAPTER_TYPE_B: { | ||
540 | arcmsr_abort_hbb_allcmd(acb); | ||
541 | } | ||
542 | } | ||
543 | } | ||
544 | |||
382 | static void arcmsr_pci_unmap_dma(struct CommandControlBlock *ccb) | 545 | static void arcmsr_pci_unmap_dma(struct CommandControlBlock *ccb) |
383 | { | 546 | { |
384 | struct scsi_cmnd *pcmd = ccb->pcmd; | 547 | struct scsi_cmnd *pcmd = ccb->pcmd; |
@@ -400,28 +563,239 @@ static void arcmsr_ccb_complete(struct CommandControlBlock *ccb, int stand_flag) | |||
400 | pcmd->scsi_done(pcmd); | 563 | pcmd->scsi_done(pcmd); |
401 | } | 564 | } |
402 | 565 | ||
566 | static void arcmsr_flush_hba_cache(struct AdapterControlBlock *acb) | ||
567 | { | ||
568 | struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; | ||
569 | int retry_count = 30; | ||
570 | |||
571 | writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, ®->inbound_msgaddr0); | ||
572 | do { | ||
573 | if (!arcmsr_hba_wait_msgint_ready(acb)) | ||
574 | break; | ||
575 | else { | ||
576 | retry_count--; | ||
577 | printk(KERN_NOTICE "arcmsr%d: wait 'flush adapter cache' \ | ||
578 | timeout, retry count down = %d \n", acb->host->host_no, retry_count); | ||
579 | } | ||
580 | } while (retry_count != 0); | ||
581 | } | ||
582 | |||
583 | static void arcmsr_flush_hbb_cache(struct AdapterControlBlock *acb) | ||
584 | { | ||
585 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; | ||
586 | int retry_count = 30; | ||
587 | |||
588 | writel(ARCMSR_MESSAGE_FLUSH_CACHE, reg->drv2iop_doorbell_reg); | ||
589 | do { | ||
590 | if (!arcmsr_hbb_wait_msgint_ready(acb)) | ||
591 | break; | ||
592 | else { | ||
593 | retry_count--; | ||
594 | printk(KERN_NOTICE "arcmsr%d: wait 'flush adapter cache' \ | ||
595 | timeout,retry count down = %d \n", acb->host->host_no, retry_count); | ||
596 | } | ||
597 | } while (retry_count != 0); | ||
598 | } | ||
599 | |||
600 | static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb) | ||
601 | { | ||
602 | switch (acb->adapter_type) { | ||
603 | |||
604 | case ACB_ADAPTER_TYPE_A: { | ||
605 | arcmsr_flush_hba_cache(acb); | ||
606 | } | ||
607 | break; | ||
608 | |||
609 | case ACB_ADAPTER_TYPE_B: { | ||
610 | arcmsr_flush_hbb_cache(acb); | ||
611 | } | ||
612 | } | ||
613 | } | ||
614 | |||
615 | static void arcmsr_report_sense_info(struct CommandControlBlock *ccb) | ||
616 | { | ||
617 | |||
618 | struct scsi_cmnd *pcmd = ccb->pcmd; | ||
619 | struct SENSE_DATA *sensebuffer = (struct SENSE_DATA *)pcmd->sense_buffer; | ||
620 | |||
621 | pcmd->result = DID_OK << 16; | ||
622 | if (sensebuffer) { | ||
623 | int sense_data_length = | ||
624 | sizeof(struct SENSE_DATA) < sizeof(pcmd->sense_buffer) | ||
625 | ? sizeof(struct SENSE_DATA) : sizeof(pcmd->sense_buffer); | ||
626 | memset(sensebuffer, 0, sizeof(pcmd->sense_buffer)); | ||
627 | memcpy(sensebuffer, ccb->arcmsr_cdb.SenseData, sense_data_length); | ||
628 | sensebuffer->ErrorCode = SCSI_SENSE_CURRENT_ERRORS; | ||
629 | sensebuffer->Valid = 1; | ||
630 | } | ||
631 | } | ||
632 | |||
633 | static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb) | ||
634 | { | ||
635 | u32 orig_mask = 0; | ||
636 | switch (acb->adapter_type) { | ||
637 | |||
638 | case ACB_ADAPTER_TYPE_A : { | ||
639 | struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; | ||
640 | orig_mask = readl(®->outbound_intmask)|\ | ||
641 | ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE; | ||
642 | writel(orig_mask|ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, \ | ||
643 | ®->outbound_intmask); | ||
644 | } | ||
645 | break; | ||
646 | |||
647 | case ACB_ADAPTER_TYPE_B : { | ||
648 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; | ||
649 | orig_mask = readl(reg->iop2drv_doorbell_mask_reg) & \ | ||
650 | (~ARCMSR_IOP2DRV_MESSAGE_CMD_DONE); | ||
651 | writel(0, reg->iop2drv_doorbell_mask_reg); | ||
652 | } | ||
653 | break; | ||
654 | } | ||
655 | return orig_mask; | ||
656 | } | ||
657 | |||
658 | static void arcmsr_report_ccb_state(struct AdapterControlBlock *acb, \ | ||
659 | struct CommandControlBlock *ccb, uint32_t flag_ccb) | ||
660 | { | ||
661 | |||
662 | uint8_t id, lun; | ||
663 | id = ccb->pcmd->device->id; | ||
664 | lun = ccb->pcmd->device->lun; | ||
665 | if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) { | ||
666 | if (acb->devstate[id][lun] == ARECA_RAID_GONE) | ||
667 | acb->devstate[id][lun] = ARECA_RAID_GOOD; | ||
668 | ccb->pcmd->result = DID_OK << 16; | ||
669 | arcmsr_ccb_complete(ccb, 1); | ||
670 | } else { | ||
671 | switch (ccb->arcmsr_cdb.DeviceStatus) { | ||
672 | case ARCMSR_DEV_SELECT_TIMEOUT: { | ||
673 | acb->devstate[id][lun] = ARECA_RAID_GONE; | ||
674 | ccb->pcmd->result = DID_NO_CONNECT << 16; | ||
675 | arcmsr_ccb_complete(ccb, 1); | ||
676 | } | ||
677 | break; | ||
678 | |||
679 | case ARCMSR_DEV_ABORTED: | ||
680 | |||
681 | case ARCMSR_DEV_INIT_FAIL: { | ||
682 | acb->devstate[id][lun] = ARECA_RAID_GONE; | ||
683 | ccb->pcmd->result = DID_BAD_TARGET << 16; | ||
684 | arcmsr_ccb_complete(ccb, 1); | ||
685 | } | ||
686 | break; | ||
687 | |||
688 | case ARCMSR_DEV_CHECK_CONDITION: { | ||
689 | acb->devstate[id][lun] = ARECA_RAID_GOOD; | ||
690 | arcmsr_report_sense_info(ccb); | ||
691 | arcmsr_ccb_complete(ccb, 1); | ||
692 | } | ||
693 | break; | ||
694 | |||
695 | default: | ||
696 | printk(KERN_NOTICE | ||
697 | "arcmsr%d: scsi id = %d lun = %d" | ||
698 | " isr get command error done, " | ||
699 | "but got unknown DeviceStatus = 0x%x \n" | ||
700 | , acb->host->host_no | ||
701 | , id | ||
702 | , lun | ||
703 | , ccb->arcmsr_cdb.DeviceStatus); | ||
704 | acb->devstate[id][lun] = ARECA_RAID_GONE; | ||
705 | ccb->pcmd->result = DID_NO_CONNECT << 16; | ||
706 | arcmsr_ccb_complete(ccb, 1); | ||
707 | break; | ||
708 | } | ||
709 | } | ||
710 | } | ||
711 | |||
712 | static void arcmsr_drain_donequeue(struct AdapterControlBlock *acb, uint32_t flag_ccb) | ||
713 | |||
714 | { | ||
715 | struct CommandControlBlock *ccb; | ||
716 | |||
717 | ccb = (struct CommandControlBlock *)(acb->vir2phy_offset + (flag_ccb << 5)); | ||
718 | if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) { | ||
719 | if (ccb->startdone == ARCMSR_CCB_ABORTED) { | ||
720 | struct scsi_cmnd *abortcmd = ccb->pcmd; | ||
721 | if (abortcmd) { | ||
722 | abortcmd->result |= DID_ABORT << 16; | ||
723 | arcmsr_ccb_complete(ccb, 1); | ||
724 | printk(KERN_NOTICE "arcmsr%d: ccb ='0x%p' \ | ||
725 | isr got aborted command \n", acb->host->host_no, ccb); | ||
726 | } | ||
727 | } | ||
728 | printk(KERN_NOTICE "arcmsr%d: isr get an illegal ccb command \ | ||
729 | done acb = '0x%p'" | ||
730 | "ccb = '0x%p' ccbacb = '0x%p' startdone = 0x%x" | ||
731 | " ccboutstandingcount = %d \n" | ||
732 | , acb->host->host_no | ||
733 | , acb | ||
734 | , ccb | ||
735 | , ccb->acb | ||
736 | , ccb->startdone | ||
737 | , atomic_read(&acb->ccboutstandingcount)); | ||
738 | } | ||
739 | arcmsr_report_ccb_state(acb, ccb, flag_ccb); | ||
740 | } | ||
741 | |||
742 | static void arcmsr_done4abort_postqueue(struct AdapterControlBlock *acb) | ||
743 | { | ||
744 | int i = 0; | ||
745 | uint32_t flag_ccb; | ||
746 | |||
747 | switch (acb->adapter_type) { | ||
748 | |||
749 | case ACB_ADAPTER_TYPE_A: { | ||
750 | struct MessageUnit_A __iomem *reg = \ | ||
751 | (struct MessageUnit_A *)acb->pmu; | ||
752 | uint32_t outbound_intstatus; | ||
753 | outbound_intstatus = readl(®->outbound_intstatus) & \ | ||
754 | acb->outbound_int_enable; | ||
755 | /*clear and abort all outbound posted Q*/ | ||
756 | writel(outbound_intstatus, ®->outbound_intstatus);/*clear interrupt*/ | ||
757 | while (((flag_ccb = readl(®->outbound_queueport)) != 0xFFFFFFFF) \ | ||
758 | && (i++ < ARCMSR_MAX_OUTSTANDING_CMD)) { | ||
759 | arcmsr_drain_donequeue(acb, flag_ccb); | ||
760 | } | ||
761 | } | ||
762 | break; | ||
763 | |||
764 | case ACB_ADAPTER_TYPE_B: { | ||
765 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; | ||
766 | /*clear all outbound posted Q*/ | ||
767 | for (i = 0; i < ARCMSR_MAX_HBB_POSTQUEUE; i++) { | ||
768 | if ((flag_ccb = readl(®->done_qbuffer[i])) != 0) { | ||
769 | writel(0, ®->done_qbuffer[i]); | ||
770 | arcmsr_drain_donequeue(acb, flag_ccb); | ||
771 | } | ||
772 | writel(0, ®->post_qbuffer[i]); | ||
773 | } | ||
774 | reg->doneq_index = 0; | ||
775 | reg->postq_index = 0; | ||
776 | } | ||
777 | break; | ||
778 | } | ||
779 | } | ||
403 | static void arcmsr_remove(struct pci_dev *pdev) | 780 | static void arcmsr_remove(struct pci_dev *pdev) |
404 | { | 781 | { |
405 | struct Scsi_Host *host = pci_get_drvdata(pdev); | 782 | struct Scsi_Host *host = pci_get_drvdata(pdev); |
406 | struct AdapterControlBlock *acb = | 783 | struct AdapterControlBlock *acb = |
407 | (struct AdapterControlBlock *) host->hostdata; | 784 | (struct AdapterControlBlock *) host->hostdata; |
408 | struct MessageUnit __iomem *reg = acb->pmu; | ||
409 | int poll_count = 0; | 785 | int poll_count = 0; |
410 | 786 | ||
411 | arcmsr_free_sysfs_attr(acb); | 787 | arcmsr_free_sysfs_attr(acb); |
412 | scsi_remove_host(host); | 788 | scsi_remove_host(host); |
413 | arcmsr_stop_adapter_bgrb(acb); | 789 | arcmsr_stop_adapter_bgrb(acb); |
414 | arcmsr_flush_adapter_cache(acb); | 790 | arcmsr_flush_adapter_cache(acb); |
415 | writel(readl(®->outbound_intmask) | | 791 | arcmsr_disable_outbound_ints(acb); |
416 | ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, | ||
417 | ®->outbound_intmask); | ||
418 | acb->acb_flags |= ACB_F_SCSISTOPADAPTER; | 792 | acb->acb_flags |= ACB_F_SCSISTOPADAPTER; |
419 | acb->acb_flags &= ~ACB_F_IOP_INITED; | 793 | acb->acb_flags &= ~ACB_F_IOP_INITED; |
420 | 794 | ||
421 | for (poll_count = 0; poll_count < 256; poll_count++) { | 795 | for (poll_count = 0; poll_count < ARCMSR_MAX_OUTSTANDING_CMD; poll_count++) { |
422 | if (!atomic_read(&acb->ccboutstandingcount)) | 796 | if (!atomic_read(&acb->ccboutstandingcount)) |
423 | break; | 797 | break; |
424 | arcmsr_interrupt(acb); | 798 | arcmsr_interrupt(acb);/* FIXME: need spinlock */ |
425 | msleep(25); | 799 | msleep(25); |
426 | } | 800 | } |
427 | 801 | ||
@@ -429,8 +803,7 @@ static void arcmsr_remove(struct pci_dev *pdev) | |||
429 | int i; | 803 | int i; |
430 | 804 | ||
431 | arcmsr_abort_allcmd(acb); | 805 | arcmsr_abort_allcmd(acb); |
432 | for (i = 0; i < ARCMSR_MAX_OUTSTANDING_CMD; i++) | 806 | arcmsr_done4abort_postqueue(acb); |
433 | readl(®->outbound_queueport); | ||
434 | for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { | 807 | for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { |
435 | struct CommandControlBlock *ccb = acb->pccb_pool[i]; | 808 | struct CommandControlBlock *ccb = acb->pccb_pool[i]; |
436 | if (ccb->startdone == ARCMSR_CCB_START) { | 809 | if (ccb->startdone == ARCMSR_CCB_START) { |
@@ -477,75 +850,32 @@ static void arcmsr_module_exit(void) | |||
477 | module_init(arcmsr_module_init); | 850 | module_init(arcmsr_module_init); |
478 | module_exit(arcmsr_module_exit); | 851 | module_exit(arcmsr_module_exit); |
479 | 852 | ||
480 | static u32 arcmsr_disable_outbound_ints(struct AdapterControlBlock *acb) | 853 | static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, \ |
481 | { | 854 | u32 intmask_org) |
482 | struct MessageUnit __iomem *reg = acb->pmu; | ||
483 | u32 orig_mask = readl(®->outbound_intmask); | ||
484 | |||
485 | writel(orig_mask | ARCMSR_MU_OUTBOUND_ALL_INTMASKENABLE, | ||
486 | ®->outbound_intmask); | ||
487 | return orig_mask; | ||
488 | } | ||
489 | |||
490 | static void arcmsr_enable_outbound_ints(struct AdapterControlBlock *acb, | ||
491 | u32 orig_mask) | ||
492 | { | 855 | { |
493 | struct MessageUnit __iomem *reg = acb->pmu; | ||
494 | u32 mask; | 856 | u32 mask; |
495 | 857 | ||
496 | mask = orig_mask & ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE | | 858 | switch (acb->adapter_type) { |
497 | ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE); | ||
498 | writel(mask, ®->outbound_intmask); | ||
499 | } | ||
500 | 859 | ||
501 | static void arcmsr_flush_adapter_cache(struct AdapterControlBlock *acb) | 860 | case ACB_ADAPTER_TYPE_A : { |
502 | { | 861 | struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; |
503 | struct MessageUnit __iomem *reg = acb->pmu; | 862 | mask = intmask_org & ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE | |
504 | 863 | ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE); | |
505 | writel(ARCMSR_INBOUND_MESG0_FLUSH_CACHE, ®->inbound_msgaddr0); | 864 | writel(mask, ®->outbound_intmask); |
506 | if (arcmsr_wait_msgint_ready(acb)) | 865 | acb->outbound_int_enable = ~(intmask_org & mask) & 0x000000ff; |
507 | printk(KERN_NOTICE | 866 | } |
508 | "arcmsr%d: wait 'flush adapter cache' timeout \n" | 867 | break; |
509 | , acb->host->host_no); | ||
510 | } | ||
511 | |||
512 | static void arcmsr_report_sense_info(struct CommandControlBlock *ccb) | ||
513 | { | ||
514 | struct scsi_cmnd *pcmd = ccb->pcmd; | ||
515 | struct SENSE_DATA *sensebuffer = (struct SENSE_DATA *)pcmd->sense_buffer; | ||
516 | 868 | ||
517 | pcmd->result = DID_OK << 16; | 869 | case ACB_ADAPTER_TYPE_B : { |
518 | if (sensebuffer) { | 870 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; |
519 | int sense_data_length = | 871 | mask = intmask_org | (ARCMSR_IOP2DRV_DATA_WRITE_OK | \ |
520 | sizeof (struct SENSE_DATA) < sizeof (pcmd->sense_buffer) | 872 | ARCMSR_IOP2DRV_DATA_READ_OK | ARCMSR_IOP2DRV_CDB_DONE); |
521 | ? sizeof (struct SENSE_DATA) : sizeof (pcmd->sense_buffer); | 873 | writel(mask, reg->iop2drv_doorbell_mask_reg); |
522 | memset(sensebuffer, 0, sizeof (pcmd->sense_buffer)); | 874 | acb->outbound_int_enable = (intmask_org | mask) & 0x0000000f; |
523 | memcpy(sensebuffer, ccb->arcmsr_cdb.SenseData, sense_data_length); | 875 | } |
524 | sensebuffer->ErrorCode = SCSI_SENSE_CURRENT_ERRORS; | ||
525 | sensebuffer->Valid = 1; | ||
526 | } | 876 | } |
527 | } | 877 | } |
528 | 878 | ||
529 | static uint8_t arcmsr_wait_msgint_ready(struct AdapterControlBlock *acb) | ||
530 | { | ||
531 | struct MessageUnit __iomem *reg = acb->pmu; | ||
532 | uint32_t Index; | ||
533 | uint8_t Retries = 0x00; | ||
534 | |||
535 | do { | ||
536 | for (Index = 0; Index < 100; Index++) { | ||
537 | if (readl(®->outbound_intstatus) | ||
538 | & ARCMSR_MU_OUTBOUND_MESSAGE0_INT) { | ||
539 | writel(ARCMSR_MU_OUTBOUND_MESSAGE0_INT | ||
540 | , ®->outbound_intstatus); | ||
541 | return 0x00; | ||
542 | } | ||
543 | msleep_interruptible(10); | ||
544 | }/*max 1 seconds*/ | ||
545 | } while (Retries++ < 20);/*max 20 sec*/ | ||
546 | return 0xff; | ||
547 | } | ||
548 | |||
549 | static void arcmsr_build_ccb(struct AdapterControlBlock *acb, | 879 | static void arcmsr_build_ccb(struct AdapterControlBlock *acb, |
550 | struct CommandControlBlock *ccb, struct scsi_cmnd *pcmd) | 880 | struct CommandControlBlock *ccb, struct scsi_cmnd *pcmd) |
551 | { | 881 | { |
@@ -556,7 +886,7 @@ static void arcmsr_build_ccb(struct AdapterControlBlock *acb, | |||
556 | int nseg; | 886 | int nseg; |
557 | 887 | ||
558 | ccb->pcmd = pcmd; | 888 | ccb->pcmd = pcmd; |
559 | memset(arcmsr_cdb, 0, sizeof (struct ARCMSR_CDB)); | 889 | memset(arcmsr_cdb, 0, sizeof(struct ARCMSR_CDB)); |
560 | arcmsr_cdb->Bus = 0; | 890 | arcmsr_cdb->Bus = 0; |
561 | arcmsr_cdb->TargetID = pcmd->device->id; | 891 | arcmsr_cdb->TargetID = pcmd->device->id; |
562 | arcmsr_cdb->LUN = pcmd->device->lun; | 892 | arcmsr_cdb->LUN = pcmd->device->lun; |
@@ -609,52 +939,85 @@ static void arcmsr_build_ccb(struct AdapterControlBlock *acb, | |||
609 | 939 | ||
610 | static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandControlBlock *ccb) | 940 | static void arcmsr_post_ccb(struct AdapterControlBlock *acb, struct CommandControlBlock *ccb) |
611 | { | 941 | { |
612 | struct MessageUnit __iomem *reg = acb->pmu; | ||
613 | uint32_t cdb_shifted_phyaddr = ccb->cdb_shifted_phyaddr; | 942 | uint32_t cdb_shifted_phyaddr = ccb->cdb_shifted_phyaddr; |
614 | struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb; | 943 | struct ARCMSR_CDB *arcmsr_cdb = (struct ARCMSR_CDB *)&ccb->arcmsr_cdb; |
615 | |||
616 | atomic_inc(&acb->ccboutstandingcount); | 944 | atomic_inc(&acb->ccboutstandingcount); |
617 | ccb->startdone = ARCMSR_CCB_START; | 945 | ccb->startdone = ARCMSR_CCB_START; |
618 | if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) | 946 | |
619 | writel(cdb_shifted_phyaddr | ARCMSR_CCBPOST_FLAG_SGL_BSIZE, | 947 | switch (acb->adapter_type) { |
948 | case ACB_ADAPTER_TYPE_A: { | ||
949 | struct MessageUnit_A *reg = (struct MessageUnit_A *)acb->pmu; | ||
950 | |||
951 | if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) | ||
952 | writel(cdb_shifted_phyaddr | ARCMSR_CCBPOST_FLAG_SGL_BSIZE, | ||
620 | ®->inbound_queueport); | 953 | ®->inbound_queueport); |
621 | else | 954 | else { |
622 | writel(cdb_shifted_phyaddr, ®->inbound_queueport); | 955 | writel(cdb_shifted_phyaddr, ®->inbound_queueport); |
623 | } | 956 | } |
957 | } | ||
958 | break; | ||
624 | 959 | ||
625 | void arcmsr_post_Qbuffer(struct AdapterControlBlock *acb) | 960 | case ACB_ADAPTER_TYPE_B: { |
626 | { | 961 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; |
627 | struct MessageUnit __iomem *reg = acb->pmu; | 962 | uint32_t ending_index, index = reg->postq_index; |
628 | struct QBUFFER __iomem *pwbuffer = (struct QBUFFER __iomem *) ®->message_wbuffer; | ||
629 | uint8_t __iomem *iop_data = (uint8_t __iomem *) pwbuffer->data; | ||
630 | int32_t allxfer_len = 0; | ||
631 | 963 | ||
632 | if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READED) { | 964 | ending_index = ((index + 1) % ARCMSR_MAX_HBB_POSTQUEUE); |
633 | acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED); | 965 | writel(0, ®->post_qbuffer[ending_index]); |
634 | while ((acb->wqbuf_firstindex != acb->wqbuf_lastindex) | 966 | if (arcmsr_cdb->Flags & ARCMSR_CDB_FLAG_SGL_BSIZE) { |
635 | && (allxfer_len < 124)) { | 967 | writel(cdb_shifted_phyaddr | ARCMSR_CCBPOST_FLAG_SGL_BSIZE,\ |
636 | writeb(acb->wqbuffer[acb->wqbuf_firstindex], iop_data); | 968 | ®->post_qbuffer[index]); |
637 | acb->wqbuf_firstindex++; | 969 | } |
638 | acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; | 970 | else { |
639 | iop_data++; | 971 | writel(cdb_shifted_phyaddr, ®->post_qbuffer[index]); |
640 | allxfer_len++; | ||
641 | } | 972 | } |
642 | writel(allxfer_len, &pwbuffer->data_len); | 973 | index++; |
643 | writel(ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK | 974 | index %= ARCMSR_MAX_HBB_POSTQUEUE;/*if last index number set it to 0 */ |
644 | , ®->inbound_doorbell); | 975 | reg->postq_index = index; |
976 | writel(ARCMSR_DRV2IOP_CDB_POSTED, reg->drv2iop_doorbell_reg); | ||
977 | } | ||
978 | break; | ||
645 | } | 979 | } |
646 | } | 980 | } |
647 | 981 | ||
648 | static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb) | 982 | static void arcmsr_stop_hba_bgrb(struct AdapterControlBlock *acb) |
649 | { | 983 | { |
650 | struct MessageUnit __iomem *reg = acb->pmu; | 984 | struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; |
651 | |||
652 | acb->acb_flags &= ~ACB_F_MSG_START_BGRB; | 985 | acb->acb_flags &= ~ACB_F_MSG_START_BGRB; |
653 | writel(ARCMSR_INBOUND_MESG0_STOP_BGRB, ®->inbound_msgaddr0); | 986 | writel(ARCMSR_INBOUND_MESG0_STOP_BGRB, ®->inbound_msgaddr0); |
654 | if (arcmsr_wait_msgint_ready(acb)) | 987 | |
988 | if (arcmsr_hba_wait_msgint_ready(acb)) { | ||
655 | printk(KERN_NOTICE | 989 | printk(KERN_NOTICE |
656 | "arcmsr%d: wait 'stop adapter background rebulid' timeout \n" | 990 | "arcmsr%d: wait 'stop adapter background rebulid' timeout \n" |
657 | , acb->host->host_no); | 991 | , acb->host->host_no); |
992 | } | ||
993 | } | ||
994 | |||
995 | static void arcmsr_stop_hbb_bgrb(struct AdapterControlBlock *acb) | ||
996 | { | ||
997 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; | ||
998 | acb->acb_flags &= ~ACB_F_MSG_START_BGRB; | ||
999 | writel(ARCMSR_MESSAGE_STOP_BGRB, reg->drv2iop_doorbell_reg); | ||
1000 | |||
1001 | if (arcmsr_hbb_wait_msgint_ready(acb)) { | ||
1002 | printk(KERN_NOTICE | ||
1003 | "arcmsr%d: wait 'stop adapter background rebulid' timeout \n" | ||
1004 | , acb->host->host_no); | ||
1005 | } | ||
1006 | } | ||
1007 | |||
1008 | static void arcmsr_stop_adapter_bgrb(struct AdapterControlBlock *acb) | ||
1009 | { | ||
1010 | switch (acb->adapter_type) { | ||
1011 | case ACB_ADAPTER_TYPE_A: { | ||
1012 | arcmsr_stop_hba_bgrb(acb); | ||
1013 | } | ||
1014 | break; | ||
1015 | |||
1016 | case ACB_ADAPTER_TYPE_B: { | ||
1017 | arcmsr_stop_hbb_bgrb(acb); | ||
1018 | } | ||
1019 | break; | ||
1020 | } | ||
658 | } | 1021 | } |
659 | 1022 | ||
660 | static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb) | 1023 | static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb) |
@@ -665,151 +1028,260 @@ static void arcmsr_free_ccb_pool(struct AdapterControlBlock *acb) | |||
665 | acb->dma_coherent_handle); | 1028 | acb->dma_coherent_handle); |
666 | } | 1029 | } |
667 | 1030 | ||
668 | static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb) | 1031 | void arcmsr_iop_message_read(struct AdapterControlBlock *acb) |
669 | { | 1032 | { |
670 | struct MessageUnit __iomem *reg = acb->pmu; | 1033 | switch (acb->adapter_type) { |
671 | struct CommandControlBlock *ccb; | 1034 | case ACB_ADAPTER_TYPE_A: { |
672 | uint32_t flag_ccb, outbound_intstatus, outbound_doorbell; | 1035 | struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; |
1036 | writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, ®->inbound_doorbell); | ||
1037 | } | ||
1038 | break; | ||
673 | 1039 | ||
674 | outbound_intstatus = readl(®->outbound_intstatus) | 1040 | case ACB_ADAPTER_TYPE_B: { |
675 | & acb->outbound_int_enable; | 1041 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; |
676 | writel(outbound_intstatus, ®->outbound_intstatus); | 1042 | writel(ARCMSR_DRV2IOP_DATA_READ_OK, reg->drv2iop_doorbell_reg); |
677 | if (outbound_intstatus & ARCMSR_MU_OUTBOUND_DOORBELL_INT) { | ||
678 | outbound_doorbell = readl(®->outbound_doorbell); | ||
679 | writel(outbound_doorbell, ®->outbound_doorbell); | ||
680 | if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) { | ||
681 | struct QBUFFER __iomem * prbuffer = | ||
682 | (struct QBUFFER __iomem *) ®->message_rbuffer; | ||
683 | uint8_t __iomem * iop_data = (uint8_t __iomem *)prbuffer->data; | ||
684 | int32_t my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex; | ||
685 | |||
686 | rqbuf_lastindex = acb->rqbuf_lastindex; | ||
687 | rqbuf_firstindex = acb->rqbuf_firstindex; | ||
688 | iop_len = readl(&prbuffer->data_len); | ||
689 | my_empty_len = (rqbuf_firstindex - rqbuf_lastindex - 1) | ||
690 | &(ARCMSR_MAX_QBUFFER - 1); | ||
691 | if (my_empty_len >= iop_len) { | ||
692 | while (iop_len > 0) { | ||
693 | acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); | ||
694 | acb->rqbuf_lastindex++; | ||
695 | acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; | ||
696 | iop_data++; | ||
697 | iop_len--; | ||
698 | } | ||
699 | writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, | ||
700 | ®->inbound_doorbell); | ||
701 | } else | ||
702 | acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW; | ||
703 | } | ||
704 | if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK) { | ||
705 | acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED; | ||
706 | if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) { | ||
707 | struct QBUFFER __iomem * pwbuffer = | ||
708 | (struct QBUFFER __iomem *) ®->message_wbuffer; | ||
709 | uint8_t __iomem * iop_data = (uint8_t __iomem *) pwbuffer->data; | ||
710 | int32_t allxfer_len = 0; | ||
711 | |||
712 | acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED); | ||
713 | while ((acb->wqbuf_firstindex != acb->wqbuf_lastindex) | ||
714 | && (allxfer_len < 124)) { | ||
715 | writeb(acb->wqbuffer[acb->wqbuf_firstindex], iop_data); | ||
716 | acb->wqbuf_firstindex++; | ||
717 | acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; | ||
718 | iop_data++; | ||
719 | allxfer_len++; | ||
720 | } | ||
721 | writel(allxfer_len, &pwbuffer->data_len); | ||
722 | writel(ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK, | ||
723 | ®->inbound_doorbell); | ||
724 | } | ||
725 | if (acb->wqbuf_firstindex == acb->wqbuf_lastindex) | ||
726 | acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED; | ||
727 | } | 1043 | } |
1044 | break; | ||
728 | } | 1045 | } |
729 | if (outbound_intstatus & ARCMSR_MU_OUTBOUND_POSTQUEUE_INT) { | 1046 | } |
730 | int id, lun; | 1047 | |
1048 | static void arcmsr_iop_message_wrote(struct AdapterControlBlock *acb) | ||
1049 | { | ||
1050 | switch (acb->adapter_type) { | ||
1051 | case ACB_ADAPTER_TYPE_A: { | ||
1052 | struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; | ||
731 | /* | 1053 | /* |
732 | **************************************************************** | 1054 | ** push inbound doorbell tell iop, driver data write ok |
733 | ** areca cdb command done | 1055 | ** and wait reply on next hwinterrupt for next Qbuffer post |
734 | **************************************************************** | ||
735 | */ | 1056 | */ |
736 | while (1) { | 1057 | writel(ARCMSR_INBOUND_DRIVER_DATA_WRITE_OK, ®->inbound_doorbell); |
737 | if ((flag_ccb = readl(®->outbound_queueport)) == 0xFFFFFFFF) | 1058 | } |
738 | break;/*chip FIFO no ccb for completion already*/ | 1059 | break; |
739 | /* check if command done with no error*/ | 1060 | |
740 | ccb = (struct CommandControlBlock *)(acb->vir2phy_offset + | 1061 | case ACB_ADAPTER_TYPE_B: { |
741 | (flag_ccb << 5)); | 1062 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; |
742 | if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) { | 1063 | /* |
743 | if (ccb->startdone == ARCMSR_CCB_ABORTED) { | 1064 | ** push inbound doorbell tell iop, driver data write ok |
744 | struct scsi_cmnd *abortcmd = ccb->pcmd; | 1065 | ** and wait reply on next hwinterrupt for next Qbuffer post |
745 | if (abortcmd) { | 1066 | */ |
746 | abortcmd->result |= DID_ABORT >> 16; | 1067 | writel(ARCMSR_DRV2IOP_DATA_WRITE_OK, reg->drv2iop_doorbell_reg); |
747 | arcmsr_ccb_complete(ccb, 1); | 1068 | } |
748 | printk(KERN_NOTICE | 1069 | break; |
749 | "arcmsr%d: ccb ='0x%p' isr got aborted command \n" | 1070 | } |
750 | , acb->host->host_no, ccb); | 1071 | } |
751 | } | 1072 | |
752 | continue; | 1073 | struct QBUFFER *arcmsr_get_iop_rqbuffer(struct AdapterControlBlock *acb) |
753 | } | 1074 | { |
754 | printk(KERN_NOTICE | 1075 | static struct QBUFFER *qbuffer; |
755 | "arcmsr%d: isr get an illegal ccb command done acb = '0x%p'" | 1076 | |
756 | "ccb = '0x%p' ccbacb = '0x%p' startdone = 0x%x" | 1077 | switch (acb->adapter_type) { |
757 | " ccboutstandingcount = %d \n" | 1078 | |
758 | , acb->host->host_no | 1079 | case ACB_ADAPTER_TYPE_A: { |
759 | , acb | 1080 | struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; |
760 | , ccb | 1081 | qbuffer = (struct QBUFFER __iomem *) ®->message_rbuffer; |
761 | , ccb->acb | 1082 | } |
762 | , ccb->startdone | 1083 | break; |
763 | , atomic_read(&acb->ccboutstandingcount)); | 1084 | |
764 | continue; | 1085 | case ACB_ADAPTER_TYPE_B: { |
765 | } | 1086 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; |
766 | id = ccb->pcmd->device->id; | 1087 | qbuffer = (struct QBUFFER __iomem *) reg->ioctl_rbuffer_reg; |
767 | lun = ccb->pcmd->device->lun; | 1088 | } |
768 | if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) { | 1089 | break; |
769 | if (acb->devstate[id][lun] == ARECA_RAID_GONE) | 1090 | } |
770 | acb->devstate[id][lun] = ARECA_RAID_GOOD; | 1091 | return qbuffer; |
771 | ccb->pcmd->result = DID_OK << 16; | 1092 | } |
772 | arcmsr_ccb_complete(ccb, 1); | 1093 | |
773 | } else { | 1094 | static struct QBUFFER *arcmsr_get_iop_wqbuffer(struct AdapterControlBlock *acb) |
774 | switch(ccb->arcmsr_cdb.DeviceStatus) { | 1095 | { |
775 | case ARCMSR_DEV_SELECT_TIMEOUT: { | 1096 | static struct QBUFFER *pqbuffer; |
776 | acb->devstate[id][lun] = ARECA_RAID_GONE; | 1097 | |
777 | ccb->pcmd->result = DID_NO_CONNECT << 16; | 1098 | switch (acb->adapter_type) { |
778 | arcmsr_ccb_complete(ccb, 1); | 1099 | |
779 | } | 1100 | case ACB_ADAPTER_TYPE_A: { |
780 | break; | 1101 | struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; |
781 | case ARCMSR_DEV_ABORTED: | 1102 | pqbuffer = (struct QBUFFER *) ®->message_wbuffer; |
782 | case ARCMSR_DEV_INIT_FAIL: { | 1103 | } |
783 | acb->devstate[id][lun] = ARECA_RAID_GONE; | 1104 | break; |
784 | ccb->pcmd->result = DID_BAD_TARGET << 16; | 1105 | |
785 | arcmsr_ccb_complete(ccb, 1); | 1106 | case ACB_ADAPTER_TYPE_B: { |
786 | } | 1107 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; |
787 | break; | 1108 | pqbuffer = (struct QBUFFER __iomem *)reg->ioctl_wbuffer_reg; |
788 | case ARCMSR_DEV_CHECK_CONDITION: { | 1109 | } |
789 | acb->devstate[id][lun] = ARECA_RAID_GOOD; | 1110 | break; |
790 | arcmsr_report_sense_info(ccb); | 1111 | } |
791 | arcmsr_ccb_complete(ccb, 1); | 1112 | return pqbuffer; |
792 | } | 1113 | } |
793 | break; | 1114 | |
794 | default: | 1115 | static void arcmsr_iop2drv_data_wrote_handle(struct AdapterControlBlock *acb) |
795 | printk(KERN_NOTICE | 1116 | { |
796 | "arcmsr%d: scsi id = %d lun = %d" | 1117 | struct QBUFFER *prbuffer; |
797 | " isr get command error done, " | 1118 | struct QBUFFER *pQbuffer; |
798 | "but got unknown DeviceStatus = 0x%x \n" | 1119 | uint8_t *iop_data; |
799 | , acb->host->host_no | 1120 | int32_t my_empty_len, iop_len, rqbuf_firstindex, rqbuf_lastindex; |
800 | , id | 1121 | |
801 | , lun | 1122 | rqbuf_lastindex = acb->rqbuf_lastindex; |
802 | , ccb->arcmsr_cdb.DeviceStatus); | 1123 | rqbuf_firstindex = acb->rqbuf_firstindex; |
803 | acb->devstate[id][lun] = ARECA_RAID_GONE; | 1124 | prbuffer = arcmsr_get_iop_rqbuffer(acb); |
804 | ccb->pcmd->result = DID_NO_CONNECT << 16; | 1125 | iop_data = (uint8_t *)prbuffer->data; |
805 | arcmsr_ccb_complete(ccb, 1); | 1126 | iop_len = prbuffer->data_len; |
806 | break; | 1127 | my_empty_len = (rqbuf_firstindex - rqbuf_lastindex -1)&(ARCMSR_MAX_QBUFFER -1); |
807 | } | 1128 | |
808 | } | 1129 | if (my_empty_len >= iop_len) |
809 | }/*drain reply FIFO*/ | 1130 | { |
1131 | while (iop_len > 0) { | ||
1132 | pQbuffer = (struct QBUFFER *)&acb->rqbuffer[rqbuf_lastindex]; | ||
1133 | memcpy(pQbuffer, iop_data,1); | ||
1134 | rqbuf_lastindex++; | ||
1135 | rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; | ||
1136 | iop_data++; | ||
1137 | iop_len--; | ||
1138 | } | ||
1139 | acb->rqbuf_lastindex = rqbuf_lastindex; | ||
1140 | arcmsr_iop_message_read(acb); | ||
1141 | } | ||
1142 | |||
1143 | else { | ||
1144 | acb->acb_flags |= ACB_F_IOPDATA_OVERFLOW; | ||
1145 | } | ||
1146 | } | ||
1147 | |||
1148 | static void arcmsr_iop2drv_data_read_handle(struct AdapterControlBlock *acb) | ||
1149 | { | ||
1150 | acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_READED; | ||
1151 | if (acb->wqbuf_firstindex != acb->wqbuf_lastindex) { | ||
1152 | uint8_t *pQbuffer; | ||
1153 | struct QBUFFER *pwbuffer; | ||
1154 | uint8_t *iop_data; | ||
1155 | int32_t allxfer_len = 0; | ||
1156 | |||
1157 | acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED); | ||
1158 | pwbuffer = arcmsr_get_iop_wqbuffer(acb); | ||
1159 | iop_data = (uint8_t __iomem *)pwbuffer->data; | ||
1160 | |||
1161 | while ((acb->wqbuf_firstindex != acb->wqbuf_lastindex) && \ | ||
1162 | (allxfer_len < 124)) { | ||
1163 | pQbuffer = &acb->wqbuffer[acb->wqbuf_firstindex]; | ||
1164 | memcpy(iop_data, pQbuffer, 1); | ||
1165 | acb->wqbuf_firstindex++; | ||
1166 | acb->wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; | ||
1167 | iop_data++; | ||
1168 | allxfer_len++; | ||
1169 | } | ||
1170 | pwbuffer->data_len = allxfer_len; | ||
1171 | |||
1172 | arcmsr_iop_message_wrote(acb); | ||
1173 | } | ||
1174 | |||
1175 | if (acb->wqbuf_firstindex == acb->wqbuf_lastindex) { | ||
1176 | acb->acb_flags |= ACB_F_MESSAGE_WQBUFFER_CLEARED; | ||
1177 | } | ||
1178 | } | ||
1179 | |||
1180 | static void arcmsr_hba_doorbell_isr(struct AdapterControlBlock *acb) | ||
1181 | { | ||
1182 | uint32_t outbound_doorbell; | ||
1183 | struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; | ||
1184 | |||
1185 | outbound_doorbell = readl(®->outbound_doorbell); | ||
1186 | writel(outbound_doorbell, ®->outbound_doorbell); | ||
1187 | if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_WRITE_OK) { | ||
1188 | arcmsr_iop2drv_data_wrote_handle(acb); | ||
1189 | } | ||
1190 | |||
1191 | if (outbound_doorbell & ARCMSR_OUTBOUND_IOP331_DATA_READ_OK) { | ||
1192 | arcmsr_iop2drv_data_read_handle(acb); | ||
1193 | } | ||
1194 | } | ||
1195 | |||
1196 | static void arcmsr_hba_postqueue_isr(struct AdapterControlBlock *acb) | ||
1197 | { | ||
1198 | uint32_t flag_ccb; | ||
1199 | struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; | ||
1200 | |||
1201 | while ((flag_ccb = readl(®->outbound_queueport)) != 0xFFFFFFFF) { | ||
1202 | arcmsr_drain_donequeue(acb, flag_ccb); | ||
1203 | } | ||
1204 | } | ||
1205 | |||
1206 | static void arcmsr_hbb_postqueue_isr(struct AdapterControlBlock *acb) | ||
1207 | { | ||
1208 | uint32_t index; | ||
1209 | uint32_t flag_ccb; | ||
1210 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; | ||
1211 | |||
1212 | index = reg->doneq_index; | ||
1213 | |||
1214 | while ((flag_ccb = readl(®->done_qbuffer[index])) != 0) { | ||
1215 | writel(0, ®->done_qbuffer[index]); | ||
1216 | arcmsr_drain_donequeue(acb, flag_ccb); | ||
1217 | index++; | ||
1218 | index %= ARCMSR_MAX_HBB_POSTQUEUE; | ||
1219 | reg->doneq_index = index; | ||
1220 | } | ||
1221 | } | ||
1222 | |||
1223 | static int arcmsr_handle_hba_isr(struct AdapterControlBlock *acb) | ||
1224 | { | ||
1225 | uint32_t outbound_intstatus; | ||
1226 | struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; | ||
1227 | |||
1228 | outbound_intstatus = readl(®->outbound_intstatus) & \ | ||
1229 | acb->outbound_int_enable; | ||
1230 | if (!(outbound_intstatus & ARCMSR_MU_OUTBOUND_HANDLE_INT)) { | ||
1231 | return 1; | ||
1232 | } | ||
1233 | writel(outbound_intstatus, ®->outbound_intstatus); | ||
1234 | if (outbound_intstatus & ARCMSR_MU_OUTBOUND_DOORBELL_INT) { | ||
1235 | arcmsr_hba_doorbell_isr(acb); | ||
1236 | } | ||
1237 | if (outbound_intstatus & ARCMSR_MU_OUTBOUND_POSTQUEUE_INT) { | ||
1238 | arcmsr_hba_postqueue_isr(acb); | ||
1239 | } | ||
1240 | return 0; | ||
1241 | } | ||
1242 | |||
1243 | static int arcmsr_handle_hbb_isr(struct AdapterControlBlock *acb) | ||
1244 | { | ||
1245 | uint32_t outbound_doorbell; | ||
1246 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; | ||
1247 | |||
1248 | outbound_doorbell = readl(reg->iop2drv_doorbell_reg) & \ | ||
1249 | acb->outbound_int_enable; | ||
1250 | if (!outbound_doorbell) | ||
1251 | return 1; | ||
1252 | |||
1253 | writel(~outbound_doorbell, reg->iop2drv_doorbell_reg); | ||
1254 | |||
1255 | if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_WRITE_OK) { | ||
1256 | arcmsr_iop2drv_data_wrote_handle(acb); | ||
1257 | } | ||
1258 | if (outbound_doorbell & ARCMSR_IOP2DRV_DATA_READ_OK) { | ||
1259 | arcmsr_iop2drv_data_read_handle(acb); | ||
1260 | } | ||
1261 | if (outbound_doorbell & ARCMSR_IOP2DRV_CDB_DONE) { | ||
1262 | arcmsr_hbb_postqueue_isr(acb); | ||
1263 | } | ||
1264 | |||
1265 | return 0; | ||
1266 | } | ||
1267 | |||
1268 | static irqreturn_t arcmsr_interrupt(struct AdapterControlBlock *acb) | ||
1269 | { | ||
1270 | switch (acb->adapter_type) { | ||
1271 | case ACB_ADAPTER_TYPE_A: { | ||
1272 | if (arcmsr_handle_hba_isr(acb)) { | ||
1273 | return IRQ_NONE; | ||
1274 | } | ||
1275 | } | ||
1276 | break; | ||
1277 | |||
1278 | case ACB_ADAPTER_TYPE_B: { | ||
1279 | if (arcmsr_handle_hbb_isr(acb)) { | ||
1280 | return IRQ_NONE; | ||
1281 | } | ||
1282 | } | ||
1283 | break; | ||
810 | } | 1284 | } |
811 | if (!(outbound_intstatus & ARCMSR_MU_OUTBOUND_HANDLE_INT)) | ||
812 | return IRQ_NONE; | ||
813 | return IRQ_HANDLED; | 1285 | return IRQ_HANDLED; |
814 | } | 1286 | } |
815 | 1287 | ||
@@ -818,16 +1290,47 @@ static void arcmsr_iop_parking(struct AdapterControlBlock *acb) | |||
818 | if (acb) { | 1290 | if (acb) { |
819 | /* stop adapter background rebuild */ | 1291 | /* stop adapter background rebuild */ |
820 | if (acb->acb_flags & ACB_F_MSG_START_BGRB) { | 1292 | if (acb->acb_flags & ACB_F_MSG_START_BGRB) { |
1293 | uint32_t intmask_org; | ||
821 | acb->acb_flags &= ~ACB_F_MSG_START_BGRB; | 1294 | acb->acb_flags &= ~ACB_F_MSG_START_BGRB; |
1295 | intmask_org = arcmsr_disable_outbound_ints(acb); | ||
822 | arcmsr_stop_adapter_bgrb(acb); | 1296 | arcmsr_stop_adapter_bgrb(acb); |
823 | arcmsr_flush_adapter_cache(acb); | 1297 | arcmsr_flush_adapter_cache(acb); |
1298 | arcmsr_enable_outbound_ints(acb, intmask_org); | ||
824 | } | 1299 | } |
825 | } | 1300 | } |
826 | } | 1301 | } |
827 | 1302 | ||
828 | static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_cmnd *cmd) | 1303 | void arcmsr_post_ioctldata2iop(struct AdapterControlBlock *acb) |
1304 | { | ||
1305 | int32_t wqbuf_firstindex, wqbuf_lastindex; | ||
1306 | uint8_t *pQbuffer; | ||
1307 | struct QBUFFER *pwbuffer; | ||
1308 | uint8_t *iop_data; | ||
1309 | int32_t allxfer_len = 0; | ||
1310 | |||
1311 | pwbuffer = arcmsr_get_iop_wqbuffer(acb); | ||
1312 | iop_data = (uint8_t __iomem *)pwbuffer->data; | ||
1313 | if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_READED) { | ||
1314 | acb->acb_flags &= (~ACB_F_MESSAGE_WQBUFFER_READED); | ||
1315 | wqbuf_firstindex = acb->wqbuf_firstindex; | ||
1316 | wqbuf_lastindex = acb->wqbuf_lastindex; | ||
1317 | while ((wqbuf_firstindex != wqbuf_lastindex) && (allxfer_len < 124)) { | ||
1318 | pQbuffer = &acb->wqbuffer[wqbuf_firstindex]; | ||
1319 | memcpy(iop_data, pQbuffer, 1); | ||
1320 | wqbuf_firstindex++; | ||
1321 | wqbuf_firstindex %= ARCMSR_MAX_QBUFFER; | ||
1322 | iop_data++; | ||
1323 | allxfer_len++; | ||
1324 | } | ||
1325 | acb->wqbuf_firstindex = wqbuf_firstindex; | ||
1326 | pwbuffer->data_len = allxfer_len; | ||
1327 | arcmsr_iop_message_wrote(acb); | ||
1328 | } | ||
1329 | } | ||
1330 | |||
1331 | static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, \ | ||
1332 | struct scsi_cmnd *cmd) | ||
829 | { | 1333 | { |
830 | struct MessageUnit __iomem *reg = acb->pmu; | ||
831 | struct CMD_MESSAGE_FIELD *pcmdmessagefld; | 1334 | struct CMD_MESSAGE_FIELD *pcmdmessagefld; |
832 | int retvalue = 0, transfer_len = 0; | 1335 | int retvalue = 0, transfer_len = 0; |
833 | char *buffer; | 1336 | char *buffer; |
@@ -836,7 +1339,7 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_ | |||
836 | (uint32_t ) cmd->cmnd[6] << 16 | | 1339 | (uint32_t ) cmd->cmnd[6] << 16 | |
837 | (uint32_t ) cmd->cmnd[7] << 8 | | 1340 | (uint32_t ) cmd->cmnd[7] << 8 | |
838 | (uint32_t ) cmd->cmnd[8]; | 1341 | (uint32_t ) cmd->cmnd[8]; |
839 | /* 4 bytes: Areca io control code */ | 1342 | /* 4 bytes: Areca io control code */ |
840 | 1343 | ||
841 | sg = scsi_sglist(cmd); | 1344 | sg = scsi_sglist(cmd); |
842 | buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; | 1345 | buffer = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; |
@@ -852,194 +1355,199 @@ static int arcmsr_iop_message_xfer(struct AdapterControlBlock *acb, struct scsi_ | |||
852 | } | 1355 | } |
853 | pcmdmessagefld = (struct CMD_MESSAGE_FIELD *) buffer; | 1356 | pcmdmessagefld = (struct CMD_MESSAGE_FIELD *) buffer; |
854 | switch(controlcode) { | 1357 | switch(controlcode) { |
1358 | |||
855 | case ARCMSR_MESSAGE_READ_RQBUFFER: { | 1359 | case ARCMSR_MESSAGE_READ_RQBUFFER: { |
856 | unsigned long *ver_addr; | 1360 | unsigned long *ver_addr; |
857 | dma_addr_t buf_handle; | 1361 | dma_addr_t buf_handle; |
858 | uint8_t *pQbuffer, *ptmpQbuffer; | 1362 | uint8_t *pQbuffer, *ptmpQbuffer; |
859 | int32_t allxfer_len = 0; | 1363 | int32_t allxfer_len = 0; |
1364 | |||
1365 | ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle); | ||
1366 | if (!ver_addr) { | ||
1367 | retvalue = ARCMSR_MESSAGE_FAIL; | ||
1368 | goto message_out; | ||
1369 | } | ||
1370 | ptmpQbuffer = (uint8_t *) ver_addr; | ||
1371 | while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex) | ||
1372 | && (allxfer_len < 1031)) { | ||
1373 | pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; | ||
1374 | memcpy(ptmpQbuffer, pQbuffer, 1); | ||
1375 | acb->rqbuf_firstindex++; | ||
1376 | acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER; | ||
1377 | ptmpQbuffer++; | ||
1378 | allxfer_len++; | ||
1379 | } | ||
1380 | if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { | ||
860 | 1381 | ||
861 | ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle); | 1382 | struct QBUFFER *prbuffer; |
862 | if (!ver_addr) { | 1383 | uint8_t *iop_data; |
863 | retvalue = ARCMSR_MESSAGE_FAIL; | 1384 | int32_t iop_len; |
864 | goto message_out; | 1385 | |
865 | } | 1386 | acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; |
866 | ptmpQbuffer = (uint8_t *) ver_addr; | 1387 | prbuffer = arcmsr_get_iop_rqbuffer(acb); |
867 | while ((acb->rqbuf_firstindex != acb->rqbuf_lastindex) | 1388 | iop_data = (uint8_t *)prbuffer->data; |
868 | && (allxfer_len < 1031)) { | 1389 | iop_len = readl(&prbuffer->data_len); |
869 | pQbuffer = &acb->rqbuffer[acb->rqbuf_firstindex]; | 1390 | while (iop_len > 0) { |
870 | memcpy(ptmpQbuffer, pQbuffer, 1); | 1391 | acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); |
871 | acb->rqbuf_firstindex++; | 1392 | acb->rqbuf_lastindex++; |
872 | acb->rqbuf_firstindex %= ARCMSR_MAX_QBUFFER; | 1393 | acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; |
873 | ptmpQbuffer++; | 1394 | iop_data++; |
874 | allxfer_len++; | 1395 | iop_len--; |
875 | } | ||
876 | if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { | ||
877 | struct QBUFFER __iomem * prbuffer = (struct QBUFFER __iomem *) | ||
878 | ®->message_rbuffer; | ||
879 | uint8_t __iomem * iop_data = (uint8_t __iomem *)prbuffer->data; | ||
880 | int32_t iop_len; | ||
881 | |||
882 | acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; | ||
883 | iop_len = readl(&prbuffer->data_len); | ||
884 | while (iop_len > 0) { | ||
885 | acb->rqbuffer[acb->rqbuf_lastindex] = readb(iop_data); | ||
886 | acb->rqbuf_lastindex++; | ||
887 | acb->rqbuf_lastindex %= ARCMSR_MAX_QBUFFER; | ||
888 | iop_data++; | ||
889 | iop_len--; | ||
890 | } | ||
891 | writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, | ||
892 | ®->inbound_doorbell); | ||
893 | } | 1396 | } |
894 | memcpy(pcmdmessagefld->messagedatabuffer, | 1397 | arcmsr_iop_message_read(acb); |
895 | (uint8_t *)ver_addr, allxfer_len); | 1398 | } |
896 | pcmdmessagefld->cmdmessage.Length = allxfer_len; | 1399 | memcpy(pcmdmessagefld->messagedatabuffer, (uint8_t *)ver_addr, allxfer_len); |
897 | pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; | 1400 | pcmdmessagefld->cmdmessage.Length = allxfer_len; |
898 | pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle); | 1401 | pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; |
1402 | pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle); | ||
899 | } | 1403 | } |
900 | break; | 1404 | break; |
901 | case ARCMSR_MESSAGE_WRITE_WQBUFFER: { | ||
902 | unsigned long *ver_addr; | ||
903 | dma_addr_t buf_handle; | ||
904 | int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; | ||
905 | uint8_t *pQbuffer, *ptmpuserbuffer; | ||
906 | 1405 | ||
907 | ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle); | 1406 | case ARCMSR_MESSAGE_WRITE_WQBUFFER: { |
908 | if (!ver_addr) { | 1407 | unsigned long *ver_addr; |
909 | retvalue = ARCMSR_MESSAGE_FAIL; | 1408 | dma_addr_t buf_handle; |
910 | goto message_out; | 1409 | int32_t my_empty_len, user_len, wqbuf_firstindex, wqbuf_lastindex; |
911 | } | 1410 | uint8_t *pQbuffer, *ptmpuserbuffer; |
912 | ptmpuserbuffer = (uint8_t *)ver_addr; | 1411 | |
913 | user_len = pcmdmessagefld->cmdmessage.Length; | 1412 | ver_addr = pci_alloc_consistent(acb->pdev, 1032, &buf_handle); |
914 | memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len); | 1413 | if (!ver_addr) { |
915 | wqbuf_lastindex = acb->wqbuf_lastindex; | 1414 | retvalue = ARCMSR_MESSAGE_FAIL; |
916 | wqbuf_firstindex = acb->wqbuf_firstindex; | 1415 | goto message_out; |
917 | if (wqbuf_lastindex != wqbuf_firstindex) { | 1416 | } |
1417 | ptmpuserbuffer = (uint8_t *)ver_addr; | ||
1418 | user_len = pcmdmessagefld->cmdmessage.Length; | ||
1419 | memcpy(ptmpuserbuffer, pcmdmessagefld->messagedatabuffer, user_len); | ||
1420 | wqbuf_lastindex = acb->wqbuf_lastindex; | ||
1421 | wqbuf_firstindex = acb->wqbuf_firstindex; | ||
1422 | if (wqbuf_lastindex != wqbuf_firstindex) { | ||
1423 | struct SENSE_DATA *sensebuffer = | ||
1424 | (struct SENSE_DATA *)cmd->sense_buffer; | ||
1425 | arcmsr_post_ioctldata2iop(acb); | ||
1426 | /* has error report sensedata */ | ||
1427 | sensebuffer->ErrorCode = 0x70; | ||
1428 | sensebuffer->SenseKey = ILLEGAL_REQUEST; | ||
1429 | sensebuffer->AdditionalSenseLength = 0x0A; | ||
1430 | sensebuffer->AdditionalSenseCode = 0x20; | ||
1431 | sensebuffer->Valid = 1; | ||
1432 | retvalue = ARCMSR_MESSAGE_FAIL; | ||
1433 | } else { | ||
1434 | my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) | ||
1435 | &(ARCMSR_MAX_QBUFFER - 1); | ||
1436 | if (my_empty_len >= user_len) { | ||
1437 | while (user_len > 0) { | ||
1438 | pQbuffer = | ||
1439 | &acb->wqbuffer[acb->wqbuf_lastindex]; | ||
1440 | memcpy(pQbuffer, ptmpuserbuffer, 1); | ||
1441 | acb->wqbuf_lastindex++; | ||
1442 | acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; | ||
1443 | ptmpuserbuffer++; | ||
1444 | user_len--; | ||
1445 | } | ||
1446 | if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { | ||
1447 | acb->acb_flags &= | ||
1448 | ~ACB_F_MESSAGE_WQBUFFER_CLEARED; | ||
1449 | arcmsr_post_ioctldata2iop(acb); | ||
1450 | } | ||
1451 | } else { | ||
1452 | /* has error report sensedata */ | ||
918 | struct SENSE_DATA *sensebuffer = | 1453 | struct SENSE_DATA *sensebuffer = |
919 | (struct SENSE_DATA *)cmd->sense_buffer; | 1454 | (struct SENSE_DATA *)cmd->sense_buffer; |
920 | arcmsr_post_Qbuffer(acb); | ||
921 | /* has error report sensedata */ | ||
922 | sensebuffer->ErrorCode = 0x70; | 1455 | sensebuffer->ErrorCode = 0x70; |
923 | sensebuffer->SenseKey = ILLEGAL_REQUEST; | 1456 | sensebuffer->SenseKey = ILLEGAL_REQUEST; |
924 | sensebuffer->AdditionalSenseLength = 0x0A; | 1457 | sensebuffer->AdditionalSenseLength = 0x0A; |
925 | sensebuffer->AdditionalSenseCode = 0x20; | 1458 | sensebuffer->AdditionalSenseCode = 0x20; |
926 | sensebuffer->Valid = 1; | 1459 | sensebuffer->Valid = 1; |
927 | retvalue = ARCMSR_MESSAGE_FAIL; | 1460 | retvalue = ARCMSR_MESSAGE_FAIL; |
928 | } else { | 1461 | } |
929 | my_empty_len = (wqbuf_firstindex-wqbuf_lastindex - 1) | ||
930 | &(ARCMSR_MAX_QBUFFER - 1); | ||
931 | if (my_empty_len >= user_len) { | ||
932 | while (user_len > 0) { | ||
933 | pQbuffer = | ||
934 | &acb->wqbuffer[acb->wqbuf_lastindex]; | ||
935 | memcpy(pQbuffer, ptmpuserbuffer, 1); | ||
936 | acb->wqbuf_lastindex++; | ||
937 | acb->wqbuf_lastindex %= ARCMSR_MAX_QBUFFER; | ||
938 | ptmpuserbuffer++; | ||
939 | user_len--; | ||
940 | } | ||
941 | if (acb->acb_flags & ACB_F_MESSAGE_WQBUFFER_CLEARED) { | ||
942 | acb->acb_flags &= | ||
943 | ~ACB_F_MESSAGE_WQBUFFER_CLEARED; | ||
944 | arcmsr_post_Qbuffer(acb); | ||
945 | } | ||
946 | } else { | ||
947 | /* has error report sensedata */ | ||
948 | struct SENSE_DATA *sensebuffer = | ||
949 | (struct SENSE_DATA *)cmd->sense_buffer; | ||
950 | sensebuffer->ErrorCode = 0x70; | ||
951 | sensebuffer->SenseKey = ILLEGAL_REQUEST; | ||
952 | sensebuffer->AdditionalSenseLength = 0x0A; | ||
953 | sensebuffer->AdditionalSenseCode = 0x20; | ||
954 | sensebuffer->Valid = 1; | ||
955 | retvalue = ARCMSR_MESSAGE_FAIL; | ||
956 | } | ||
957 | } | 1462 | } |
958 | pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle); | 1463 | pci_free_consistent(acb->pdev, 1032, ver_addr, buf_handle); |
959 | } | 1464 | } |
960 | break; | 1465 | break; |
1466 | |||
961 | case ARCMSR_MESSAGE_CLEAR_RQBUFFER: { | 1467 | case ARCMSR_MESSAGE_CLEAR_RQBUFFER: { |
962 | uint8_t *pQbuffer = acb->rqbuffer; | 1468 | uint8_t *pQbuffer = acb->rqbuffer; |
963 | 1469 | ||
964 | if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { | 1470 | if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { |
965 | acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; | 1471 | acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; |
966 | writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, | 1472 | arcmsr_iop_message_read(acb); |
967 | ®->inbound_doorbell); | 1473 | } |
968 | } | 1474 | acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED; |
969 | acb->acb_flags |= ACB_F_MESSAGE_RQBUFFER_CLEARED; | 1475 | acb->rqbuf_firstindex = 0; |
970 | acb->rqbuf_firstindex = 0; | 1476 | acb->rqbuf_lastindex = 0; |
971 | acb->rqbuf_lastindex = 0; | 1477 | memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); |
972 | memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); | 1478 | pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; |
973 | pcmdmessagefld->cmdmessage.ReturnCode = | ||
974 | ARCMSR_MESSAGE_RETURNCODE_OK; | ||
975 | } | 1479 | } |
976 | break; | 1480 | break; |
1481 | |||
977 | case ARCMSR_MESSAGE_CLEAR_WQBUFFER: { | 1482 | case ARCMSR_MESSAGE_CLEAR_WQBUFFER: { |
978 | uint8_t *pQbuffer = acb->wqbuffer; | 1483 | uint8_t *pQbuffer = acb->wqbuffer; |
979 | 1484 | ||
980 | if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { | 1485 | if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { |
981 | acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; | 1486 | acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; |
982 | writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK | 1487 | arcmsr_iop_message_read(acb); |
983 | , ®->inbound_doorbell); | 1488 | } |
984 | } | 1489 | acb->acb_flags |= |
985 | acb->acb_flags |= | 1490 | (ACB_F_MESSAGE_WQBUFFER_CLEARED | |
986 | (ACB_F_MESSAGE_WQBUFFER_CLEARED | | 1491 | ACB_F_MESSAGE_WQBUFFER_READED); |
987 | ACB_F_MESSAGE_WQBUFFER_READED); | 1492 | acb->wqbuf_firstindex = 0; |
988 | acb->wqbuf_firstindex = 0; | 1493 | acb->wqbuf_lastindex = 0; |
989 | acb->wqbuf_lastindex = 0; | 1494 | memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); |
990 | memset(pQbuffer, 0, ARCMSR_MAX_QBUFFER); | 1495 | pcmdmessagefld->cmdmessage.ReturnCode = |
991 | pcmdmessagefld->cmdmessage.ReturnCode = | 1496 | ARCMSR_MESSAGE_RETURNCODE_OK; |
992 | ARCMSR_MESSAGE_RETURNCODE_OK; | ||
993 | } | 1497 | } |
994 | break; | 1498 | break; |
1499 | |||
995 | case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: { | 1500 | case ARCMSR_MESSAGE_CLEAR_ALLQBUFFER: { |
996 | uint8_t *pQbuffer; | 1501 | uint8_t *pQbuffer; |
997 | 1502 | ||
998 | if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { | 1503 | if (acb->acb_flags & ACB_F_IOPDATA_OVERFLOW) { |
999 | acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; | 1504 | acb->acb_flags &= ~ACB_F_IOPDATA_OVERFLOW; |
1000 | writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK | 1505 | arcmsr_iop_message_read(acb); |
1001 | , ®->inbound_doorbell); | 1506 | } |
1002 | } | 1507 | acb->acb_flags |= |
1003 | acb->acb_flags |= | 1508 | (ACB_F_MESSAGE_WQBUFFER_CLEARED |
1004 | (ACB_F_MESSAGE_WQBUFFER_CLEARED | 1509 | | ACB_F_MESSAGE_RQBUFFER_CLEARED |
1005 | | ACB_F_MESSAGE_RQBUFFER_CLEARED | 1510 | | ACB_F_MESSAGE_WQBUFFER_READED); |
1006 | | ACB_F_MESSAGE_WQBUFFER_READED); | 1511 | acb->rqbuf_firstindex = 0; |
1007 | acb->rqbuf_firstindex = 0; | 1512 | acb->rqbuf_lastindex = 0; |
1008 | acb->rqbuf_lastindex = 0; | 1513 | acb->wqbuf_firstindex = 0; |
1009 | acb->wqbuf_firstindex = 0; | 1514 | acb->wqbuf_lastindex = 0; |
1010 | acb->wqbuf_lastindex = 0; | 1515 | pQbuffer = acb->rqbuffer; |
1011 | pQbuffer = acb->rqbuffer; | 1516 | memset(pQbuffer, 0, sizeof(struct QBUFFER)); |
1012 | memset(pQbuffer, 0, sizeof (struct QBUFFER)); | 1517 | pQbuffer = acb->wqbuffer; |
1013 | pQbuffer = acb->wqbuffer; | 1518 | memset(pQbuffer, 0, sizeof(struct QBUFFER)); |
1014 | memset(pQbuffer, 0, sizeof (struct QBUFFER)); | 1519 | pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; |
1015 | pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; | ||
1016 | } | 1520 | } |
1017 | break; | 1521 | break; |
1522 | |||
1018 | case ARCMSR_MESSAGE_RETURN_CODE_3F: { | 1523 | case ARCMSR_MESSAGE_RETURN_CODE_3F: { |
1019 | pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_3F; | 1524 | pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_3F; |
1020 | } | 1525 | } |
1021 | break; | 1526 | break; |
1527 | |||
1022 | case ARCMSR_MESSAGE_SAY_HELLO: { | 1528 | case ARCMSR_MESSAGE_SAY_HELLO: { |
1023 | int8_t * hello_string = "Hello! I am ARCMSR"; | 1529 | int8_t *hello_string = "Hello! I am ARCMSR"; |
1024 | 1530 | ||
1025 | memcpy(pcmdmessagefld->messagedatabuffer, hello_string | 1531 | memcpy(pcmdmessagefld->messagedatabuffer, hello_string |
1026 | , (int16_t)strlen(hello_string)); | 1532 | , (int16_t)strlen(hello_string)); |
1027 | pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; | 1533 | pcmdmessagefld->cmdmessage.ReturnCode = ARCMSR_MESSAGE_RETURNCODE_OK; |
1028 | } | 1534 | } |
1029 | break; | 1535 | break; |
1536 | |||
1030 | case ARCMSR_MESSAGE_SAY_GOODBYE: | 1537 | case ARCMSR_MESSAGE_SAY_GOODBYE: |
1031 | arcmsr_iop_parking(acb); | 1538 | arcmsr_iop_parking(acb); |
1032 | break; | 1539 | break; |
1540 | |||
1033 | case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE: | 1541 | case ARCMSR_MESSAGE_FLUSH_ADAPTER_CACHE: |
1034 | arcmsr_flush_adapter_cache(acb); | 1542 | arcmsr_flush_adapter_cache(acb); |
1035 | break; | 1543 | break; |
1544 | |||
1036 | default: | 1545 | default: |
1037 | retvalue = ARCMSR_MESSAGE_FAIL; | 1546 | retvalue = ARCMSR_MESSAGE_FAIL; |
1038 | } | 1547 | } |
1039 | message_out: | 1548 | message_out: |
1040 | sg = scsi_sglist(cmd); | 1549 | sg = scsi_sglist(cmd); |
1041 | kunmap_atomic(buffer - sg->offset, KM_IRQ0); | 1550 | kunmap_atomic(buffer - sg->offset, KM_IRQ0); |
1042 | |||
1043 | return retvalue; | 1551 | return retvalue; |
1044 | } | 1552 | } |
1045 | 1553 | ||
@@ -1109,8 +1617,7 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd, | |||
1109 | void (* done)(struct scsi_cmnd *)) | 1617 | void (* done)(struct scsi_cmnd *)) |
1110 | { | 1618 | { |
1111 | struct Scsi_Host *host = cmd->device->host; | 1619 | struct Scsi_Host *host = cmd->device->host; |
1112 | struct AdapterControlBlock *acb = | 1620 | struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; |
1113 | (struct AdapterControlBlock *) host->hostdata; | ||
1114 | struct CommandControlBlock *ccb; | 1621 | struct CommandControlBlock *ccb; |
1115 | int target = cmd->device->id; | 1622 | int target = cmd->device->id; |
1116 | int lun = cmd->device->lun; | 1623 | int lun = cmd->device->lun; |
@@ -1153,26 +1660,27 @@ static int arcmsr_queue_command(struct scsi_cmnd *cmd, | |||
1153 | ccb = arcmsr_get_freeccb(acb); | 1660 | ccb = arcmsr_get_freeccb(acb); |
1154 | if (!ccb) | 1661 | if (!ccb) |
1155 | return SCSI_MLQUEUE_HOST_BUSY; | 1662 | return SCSI_MLQUEUE_HOST_BUSY; |
1663 | |||
1156 | arcmsr_build_ccb(acb, ccb, cmd); | 1664 | arcmsr_build_ccb(acb, ccb, cmd); |
1157 | arcmsr_post_ccb(acb, ccb); | 1665 | arcmsr_post_ccb(acb, ccb); |
1158 | return 0; | 1666 | return 0; |
1159 | } | 1667 | } |
1160 | 1668 | ||
1161 | static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb) | 1669 | static void arcmsr_get_hba_config(struct AdapterControlBlock *acb) |
1162 | { | 1670 | { |
1163 | struct MessageUnit __iomem *reg = acb->pmu; | 1671 | struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; |
1164 | char *acb_firm_model = acb->firm_model; | 1672 | char *acb_firm_model = acb->firm_model; |
1165 | char *acb_firm_version = acb->firm_version; | 1673 | char *acb_firm_version = acb->firm_version; |
1166 | char __iomem *iop_firm_model = (char __iomem *) ®->message_rwbuffer[15]; | 1674 | char *iop_firm_model = (char *) (®->message_rwbuffer[15]); |
1167 | char __iomem *iop_firm_version = (char __iomem *) ®->message_rwbuffer[17]; | 1675 | char *iop_firm_version = (char *) (®->message_rwbuffer[17]); |
1168 | int count; | 1676 | int count; |
1169 | 1677 | ||
1170 | writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); | 1678 | writel(ARCMSR_INBOUND_MESG0_GET_CONFIG, ®->inbound_msgaddr0); |
1171 | if (arcmsr_wait_msgint_ready(acb)) | 1679 | if (arcmsr_hba_wait_msgint_ready(acb)) { |
1172 | printk(KERN_NOTICE | 1680 | printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ |
1173 | "arcmsr%d: wait " | 1681 | miscellaneous data' timeout \n", acb->host->host_no); |
1174 | "'get adapter firmware miscellaneous data' timeout \n" | 1682 | } |
1175 | , acb->host->host_no); | 1683 | |
1176 | count = 8; | 1684 | count = 8; |
1177 | while (count) { | 1685 | while (count) { |
1178 | *acb_firm_model = readb(iop_firm_model); | 1686 | *acb_firm_model = readb(iop_firm_model); |
@@ -1180,6 +1688,7 @@ static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb) | |||
1180 | iop_firm_model++; | 1688 | iop_firm_model++; |
1181 | count--; | 1689 | count--; |
1182 | } | 1690 | } |
1691 | |||
1183 | count = 16; | 1692 | count = 16; |
1184 | while (count) { | 1693 | while (count) { |
1185 | *acb_firm_version = readb(iop_firm_version); | 1694 | *acb_firm_version = readb(iop_firm_version); |
@@ -1187,28 +1696,93 @@ static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb) | |||
1187 | iop_firm_version++; | 1696 | iop_firm_version++; |
1188 | count--; | 1697 | count--; |
1189 | } | 1698 | } |
1190 | printk(KERN_INFO | 1699 | |
1191 | "ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n" | 1700 | printk(KERN_INFO "ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n" |
1192 | , acb->host->host_no | 1701 | , acb->host->host_no |
1193 | , acb->firm_version); | 1702 | , acb->firm_version); |
1703 | |||
1194 | acb->firm_request_len = readl(®->message_rwbuffer[1]); | 1704 | acb->firm_request_len = readl(®->message_rwbuffer[1]); |
1195 | acb->firm_numbers_queue = readl(®->message_rwbuffer[2]); | 1705 | acb->firm_numbers_queue = readl(®->message_rwbuffer[2]); |
1196 | acb->firm_sdram_size = readl(®->message_rwbuffer[3]); | 1706 | acb->firm_sdram_size = readl(®->message_rwbuffer[3]); |
1197 | acb->firm_hd_channels = readl(®->message_rwbuffer[4]); | 1707 | acb->firm_hd_channels = readl(®->message_rwbuffer[4]); |
1198 | } | 1708 | } |
1199 | 1709 | ||
1200 | static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb, | 1710 | static void arcmsr_get_hbb_config(struct AdapterControlBlock *acb) |
1711 | { | ||
1712 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; | ||
1713 | uint32_t *lrwbuffer = reg->msgcode_rwbuffer_reg; | ||
1714 | char *acb_firm_model = acb->firm_model; | ||
1715 | char *acb_firm_version = acb->firm_version; | ||
1716 | char *iop_firm_model = (char *) (&lrwbuffer[15]); | ||
1717 | /*firm_model,15,60-67*/ | ||
1718 | char *iop_firm_version = (char *) (&lrwbuffer[17]); | ||
1719 | /*firm_version,17,68-83*/ | ||
1720 | int count; | ||
1721 | |||
1722 | writel(ARCMSR_MESSAGE_GET_CONFIG, reg->drv2iop_doorbell_reg); | ||
1723 | if (arcmsr_hbb_wait_msgint_ready(acb)) { | ||
1724 | printk(KERN_NOTICE "arcmsr%d: wait 'get adapter firmware \ | ||
1725 | miscellaneous data' timeout \n", acb->host->host_no); | ||
1726 | } | ||
1727 | |||
1728 | count = 8; | ||
1729 | while (count) | ||
1730 | { | ||
1731 | *acb_firm_model = readb(iop_firm_model); | ||
1732 | acb_firm_model++; | ||
1733 | iop_firm_model++; | ||
1734 | count--; | ||
1735 | } | ||
1736 | |||
1737 | count = 16; | ||
1738 | while (count) | ||
1739 | { | ||
1740 | *acb_firm_version = readb(iop_firm_version); | ||
1741 | acb_firm_version++; | ||
1742 | iop_firm_version++; | ||
1743 | count--; | ||
1744 | } | ||
1745 | |||
1746 | printk(KERN_INFO "ARECA RAID ADAPTER%d: FIRMWARE VERSION %s \n", | ||
1747 | acb->host->host_no, | ||
1748 | acb->firm_version); | ||
1749 | |||
1750 | lrwbuffer++; | ||
1751 | acb->firm_request_len = readl(lrwbuffer++); | ||
1752 | /*firm_request_len,1,04-07*/ | ||
1753 | acb->firm_numbers_queue = readl(lrwbuffer++); | ||
1754 | /*firm_numbers_queue,2,08-11*/ | ||
1755 | acb->firm_sdram_size = readl(lrwbuffer++); | ||
1756 | /*firm_sdram_size,3,12-15*/ | ||
1757 | acb->firm_hd_channels = readl(lrwbuffer); | ||
1758 | /*firm_ide_channels,4,16-19*/ | ||
1759 | } | ||
1760 | |||
1761 | static void arcmsr_get_firmware_spec(struct AdapterControlBlock *acb) | ||
1762 | { | ||
1763 | switch (acb->adapter_type) { | ||
1764 | case ACB_ADAPTER_TYPE_A: { | ||
1765 | arcmsr_get_hba_config(acb); | ||
1766 | } | ||
1767 | break; | ||
1768 | |||
1769 | case ACB_ADAPTER_TYPE_B: { | ||
1770 | arcmsr_get_hbb_config(acb); | ||
1771 | } | ||
1772 | break; | ||
1773 | } | ||
1774 | } | ||
1775 | |||
1776 | static void arcmsr_polling_hba_ccbdone(struct AdapterControlBlock *acb, | ||
1201 | struct CommandControlBlock *poll_ccb) | 1777 | struct CommandControlBlock *poll_ccb) |
1202 | { | 1778 | { |
1203 | struct MessageUnit __iomem *reg = acb->pmu; | 1779 | struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; |
1204 | struct CommandControlBlock *ccb; | 1780 | struct CommandControlBlock *ccb; |
1205 | uint32_t flag_ccb, outbound_intstatus, poll_ccb_done = 0, poll_count = 0; | 1781 | uint32_t flag_ccb, outbound_intstatus, poll_ccb_done = 0, poll_count = 0; |
1206 | int id, lun; | ||
1207 | 1782 | ||
1208 | polling_ccb_retry: | 1783 | polling_hba_ccb_retry: |
1209 | poll_count++; | 1784 | poll_count++; |
1210 | outbound_intstatus = readl(®->outbound_intstatus) | 1785 | outbound_intstatus = readl(®->outbound_intstatus) & acb->outbound_int_enable; |
1211 | & acb->outbound_int_enable; | ||
1212 | writel(outbound_intstatus, ®->outbound_intstatus);/*clear interrupt*/ | 1786 | writel(outbound_intstatus, ®->outbound_intstatus);/*clear interrupt*/ |
1213 | while (1) { | 1787 | while (1) { |
1214 | if ((flag_ccb = readl(®->outbound_queueport)) == 0xFFFFFFFF) { | 1788 | if ((flag_ccb = readl(®->outbound_queueport)) == 0xFFFFFFFF) { |
@@ -1218,17 +1792,14 @@ static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb, | |||
1218 | msleep(25); | 1792 | msleep(25); |
1219 | if (poll_count > 100) | 1793 | if (poll_count > 100) |
1220 | break; | 1794 | break; |
1221 | goto polling_ccb_retry; | 1795 | goto polling_hba_ccb_retry; |
1222 | } | 1796 | } |
1223 | } | 1797 | } |
1224 | ccb = (struct CommandControlBlock *) | 1798 | ccb = (struct CommandControlBlock *)(acb->vir2phy_offset + (flag_ccb << 5)); |
1225 | (acb->vir2phy_offset + (flag_ccb << 5)); | 1799 | poll_ccb_done = (ccb == poll_ccb) ? 1:0; |
1226 | if ((ccb->acb != acb) || | 1800 | if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) { |
1227 | (ccb->startdone != ARCMSR_CCB_START)) { | 1801 | if ((ccb->startdone == ARCMSR_CCB_ABORTED) || (ccb == poll_ccb)) { |
1228 | if ((ccb->startdone == ARCMSR_CCB_ABORTED) || | 1802 | printk(KERN_NOTICE "arcmsr%d: scsi id = %d lun = %d ccb = '0x%p'" |
1229 | (ccb == poll_ccb)) { | ||
1230 | printk(KERN_NOTICE | ||
1231 | "arcmsr%d: scsi id = %d lun = %d ccb = '0x%p'" | ||
1232 | " poll command abort successfully \n" | 1803 | " poll command abort successfully \n" |
1233 | , acb->host->host_no | 1804 | , acb->host->host_no |
1234 | , ccb->pcmd->device->id | 1805 | , ccb->pcmd->device->id |
@@ -1239,176 +1810,280 @@ static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb, | |||
1239 | poll_ccb_done = 1; | 1810 | poll_ccb_done = 1; |
1240 | continue; | 1811 | continue; |
1241 | } | 1812 | } |
1242 | printk(KERN_NOTICE | 1813 | printk(KERN_NOTICE "arcmsr%d: polling get an illegal ccb" |
1243 | "arcmsr%d: polling get an illegal ccb" | 1814 | " command done ccb = '0x%p'" |
1244 | " command done ccb ='0x%p'" | ||
1245 | "ccboutstandingcount = %d \n" | 1815 | "ccboutstandingcount = %d \n" |
1246 | , acb->host->host_no | 1816 | , acb->host->host_no |
1247 | , ccb | 1817 | , ccb |
1248 | , atomic_read(&acb->ccboutstandingcount)); | 1818 | , atomic_read(&acb->ccboutstandingcount)); |
1249 | continue; | 1819 | continue; |
1250 | } | 1820 | } |
1251 | id = ccb->pcmd->device->id; | 1821 | arcmsr_report_ccb_state(acb, ccb, flag_ccb); |
1252 | lun = ccb->pcmd->device->lun; | 1822 | } |
1253 | if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) { | 1823 | } |
1254 | if (acb->devstate[id][lun] == ARECA_RAID_GONE) | 1824 | |
1255 | acb->devstate[id][lun] = ARECA_RAID_GOOD; | 1825 | static void arcmsr_polling_hbb_ccbdone(struct AdapterControlBlock *acb, \ |
1256 | ccb->pcmd->result = DID_OK << 16; | 1826 | struct CommandControlBlock *poll_ccb) |
1257 | arcmsr_ccb_complete(ccb, 1); | 1827 | { |
1258 | } else { | 1828 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; |
1259 | switch(ccb->arcmsr_cdb.DeviceStatus) { | 1829 | struct CommandControlBlock *ccb; |
1260 | case ARCMSR_DEV_SELECT_TIMEOUT: { | 1830 | uint32_t flag_ccb, poll_ccb_done = 0, poll_count = 0; |
1261 | acb->devstate[id][lun] = ARECA_RAID_GONE; | 1831 | int index; |
1262 | ccb->pcmd->result = DID_NO_CONNECT << 16; | 1832 | |
1263 | arcmsr_ccb_complete(ccb, 1); | 1833 | polling_hbb_ccb_retry: |
1264 | } | 1834 | poll_count++; |
1265 | break; | 1835 | /* clear doorbell interrupt */ |
1266 | case ARCMSR_DEV_ABORTED: | 1836 | writel(ARCMSR_DOORBELL_INT_CLEAR_PATTERN, reg->iop2drv_doorbell_reg); |
1267 | case ARCMSR_DEV_INIT_FAIL: { | 1837 | while (1) { |
1268 | acb->devstate[id][lun] = ARECA_RAID_GONE; | 1838 | index = reg->doneq_index; |
1269 | ccb->pcmd->result = DID_BAD_TARGET << 16; | 1839 | if ((flag_ccb = readl(®->done_qbuffer[index])) == 0) { |
1270 | arcmsr_ccb_complete(ccb, 1); | 1840 | if (poll_ccb_done) |
1841 | break; | ||
1842 | else { | ||
1843 | msleep(25); | ||
1844 | if (poll_count > 100) | ||
1845 | break; | ||
1846 | goto polling_hbb_ccb_retry; | ||
1271 | } | 1847 | } |
1272 | break; | 1848 | } |
1273 | case ARCMSR_DEV_CHECK_CONDITION: { | 1849 | writel(0, ®->done_qbuffer[index]); |
1274 | acb->devstate[id][lun] = ARECA_RAID_GOOD; | 1850 | index++; |
1275 | arcmsr_report_sense_info(ccb); | 1851 | /*if last index number set it to 0 */ |
1852 | index %= ARCMSR_MAX_HBB_POSTQUEUE; | ||
1853 | reg->doneq_index = index; | ||
1854 | /* check ifcommand done with no error*/ | ||
1855 | ccb = (struct CommandControlBlock *)\ | ||
1856 | (acb->vir2phy_offset + (flag_ccb << 5));/*frame must be 32 bytes aligned*/ | ||
1857 | poll_ccb_done = (ccb == poll_ccb) ? 1:0; | ||
1858 | if ((ccb->acb != acb) || (ccb->startdone != ARCMSR_CCB_START)) { | ||
1859 | if (ccb->startdone == ARCMSR_CCB_ABORTED) { | ||
1860 | printk(KERN_NOTICE "arcmsr%d: \ | ||
1861 | scsi id = %d lun = %d ccb = '0x%p' poll command abort successfully \n" | ||
1862 | ,acb->host->host_no | ||
1863 | ,ccb->pcmd->device->id | ||
1864 | ,ccb->pcmd->device->lun | ||
1865 | ,ccb); | ||
1866 | ccb->pcmd->result = DID_ABORT << 16; | ||
1276 | arcmsr_ccb_complete(ccb, 1); | 1867 | arcmsr_ccb_complete(ccb, 1); |
1868 | continue; | ||
1277 | } | 1869 | } |
1278 | break; | 1870 | printk(KERN_NOTICE "arcmsr%d: polling get an illegal ccb" |
1279 | default: | 1871 | " command done ccb = '0x%p'" |
1280 | printk(KERN_NOTICE | 1872 | "ccboutstandingcount = %d \n" |
1281 | "arcmsr%d: scsi id = %d lun = %d" | ||
1282 | " polling and getting command error done" | ||
1283 | "but got unknown DeviceStatus = 0x%x \n" | ||
1284 | , acb->host->host_no | 1873 | , acb->host->host_no |
1285 | , id | 1874 | , ccb |
1286 | , lun | 1875 | , atomic_read(&acb->ccboutstandingcount)); |
1287 | , ccb->arcmsr_cdb.DeviceStatus); | 1876 | continue; |
1288 | acb->devstate[id][lun] = ARECA_RAID_GONE; | ||
1289 | ccb->pcmd->result = DID_BAD_TARGET << 16; | ||
1290 | arcmsr_ccb_complete(ccb, 1); | ||
1291 | break; | ||
1292 | } | 1877 | } |
1878 | arcmsr_report_ccb_state(acb, ccb, flag_ccb); | ||
1879 | } /*drain reply FIFO*/ | ||
1880 | } | ||
1881 | |||
1882 | static void arcmsr_polling_ccbdone(struct AdapterControlBlock *acb, \ | ||
1883 | struct CommandControlBlock *poll_ccb) | ||
1884 | { | ||
1885 | switch (acb->adapter_type) { | ||
1886 | |||
1887 | case ACB_ADAPTER_TYPE_A: { | ||
1888 | arcmsr_polling_hba_ccbdone(acb,poll_ccb); | ||
1889 | } | ||
1890 | break; | ||
1891 | |||
1892 | case ACB_ADAPTER_TYPE_B: { | ||
1893 | arcmsr_polling_hbb_ccbdone(acb,poll_ccb); | ||
1293 | } | 1894 | } |
1294 | } | 1895 | } |
1295 | } | 1896 | } |
1296 | static void arcmsr_done4_abort_postqueue(struct AdapterControlBlock *acb) | 1897 | |
1898 | static int arcmsr_iop_confirm(struct AdapterControlBlock *acb) | ||
1297 | { | 1899 | { |
1298 | int i = 0, found = 0; | 1900 | uint32_t cdb_phyaddr, ccb_phyaddr_hi32; |
1299 | int id, lun; | 1901 | dma_addr_t dma_coherent_handle; |
1300 | uint32_t flag_ccb, outbound_intstatus; | 1902 | /* |
1301 | struct MessageUnit __iomem *reg = acb->pmu; | 1903 | ******************************************************************** |
1302 | struct CommandControlBlock *ccb; | 1904 | ** here we need to tell iop 331 our freeccb.HighPart |
1303 | /*clear and abort all outbound posted Q*/ | 1905 | ** if freeccb.HighPart is not zero |
1304 | 1906 | ******************************************************************** | |
1305 | while (((flag_ccb = readl(®->outbound_queueport)) != 0xFFFFFFFF) && | 1907 | */ |
1306 | (i++ < 256)){ | 1908 | dma_coherent_handle = acb->dma_coherent_handle; |
1307 | ccb = (struct CommandControlBlock *)(acb->vir2phy_offset + | 1909 | cdb_phyaddr = (uint32_t)(dma_coherent_handle); |
1308 | (flag_ccb << 5)); | 1910 | ccb_phyaddr_hi32 = (uint32_t)((cdb_phyaddr >> 16) >> 16); |
1309 | if (ccb){ | 1911 | /* |
1310 | if ((ccb->acb != acb)||(ccb->startdone != \ | 1912 | *********************************************************************** |
1311 | ARCMSR_CCB_START)){ | 1913 | ** if adapter type B, set window of "post command Q" |
1312 | printk(KERN_NOTICE "arcmsr%d: polling get \ | 1914 | *********************************************************************** |
1313 | an illegal ccb" "command done ccb = '0x%p'""ccboutstandingcount = %d \n", | 1915 | */ |
1314 | acb->host->host_no, ccb, | 1916 | switch (acb->adapter_type) { |
1315 | atomic_read(&acb->ccboutstandingcount)); | 1917 | |
1316 | continue; | 1918 | case ACB_ADAPTER_TYPE_A: { |
1919 | if (ccb_phyaddr_hi32 != 0) { | ||
1920 | struct MessageUnit_A __iomem *reg = \ | ||
1921 | (struct MessageUnit_A *)acb->pmu; | ||
1922 | uint32_t intmask_org; | ||
1923 | intmask_org = arcmsr_disable_outbound_ints(acb); | ||
1924 | writel(ARCMSR_SIGNATURE_SET_CONFIG, \ | ||
1925 | ®->message_rwbuffer[0]); | ||
1926 | writel(ccb_phyaddr_hi32, ®->message_rwbuffer[1]); | ||
1927 | writel(ARCMSR_INBOUND_MESG0_SET_CONFIG, \ | ||
1928 | ®->inbound_msgaddr0); | ||
1929 | if (arcmsr_hba_wait_msgint_ready(acb)) { | ||
1930 | printk(KERN_NOTICE "arcmsr%d: ""set ccb high \ | ||
1931 | part physical address timeout\n", | ||
1932 | acb->host->host_no); | ||
1933 | return 1; | ||
1317 | } | 1934 | } |
1935 | arcmsr_enable_outbound_ints(acb, intmask_org); | ||
1936 | } | ||
1937 | } | ||
1938 | break; | ||
1318 | 1939 | ||
1319 | id = ccb->pcmd->device->id; | 1940 | case ACB_ADAPTER_TYPE_B: { |
1320 | lun = ccb->pcmd->device->lun; | 1941 | unsigned long post_queue_phyaddr; |
1321 | if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)){ | 1942 | uint32_t *rwbuffer; |
1322 | if (acb->devstate[id][lun] == ARECA_RAID_GONE) | ||
1323 | acb->devstate[id][lun] = ARECA_RAID_GOOD; | ||
1324 | ccb->pcmd->result = DID_OK << 16; | ||
1325 | arcmsr_ccb_complete(ccb, 1); | ||
1326 | } | ||
1327 | else { | ||
1328 | switch(ccb->arcmsr_cdb.DeviceStatus) { | ||
1329 | case ARCMSR_DEV_SELECT_TIMEOUT: { | ||
1330 | acb->devstate[id][lun] = ARECA_RAID_GONE; | ||
1331 | ccb->pcmd->result = DID_NO_CONNECT << 16; | ||
1332 | arcmsr_ccb_complete(ccb, 1); | ||
1333 | } | ||
1334 | break; | ||
1335 | 1943 | ||
1336 | case ARCMSR_DEV_ABORTED: | 1944 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; |
1945 | uint32_t intmask_org; | ||
1946 | intmask_org = arcmsr_disable_outbound_ints(acb); | ||
1947 | reg->postq_index = 0; | ||
1948 | reg->doneq_index = 0; | ||
1949 | writel(ARCMSR_MESSAGE_SET_POST_WINDOW, reg->drv2iop_doorbell_reg); | ||
1950 | if (arcmsr_hbb_wait_msgint_ready(acb)) { | ||
1951 | printk(KERN_NOTICE "arcmsr%d:can not set diver mode\n", \ | ||
1952 | acb->host->host_no); | ||
1953 | return 1; | ||
1954 | } | ||
1955 | post_queue_phyaddr = cdb_phyaddr + ARCMSR_MAX_FREECCB_NUM * \ | ||
1956 | sizeof(struct CommandControlBlock) + offsetof(struct MessageUnit_B, post_qbuffer) ; | ||
1957 | rwbuffer = reg->msgcode_rwbuffer_reg; | ||
1958 | /* driver "set config" signature */ | ||
1959 | writel(ARCMSR_SIGNATURE_SET_CONFIG, rwbuffer++); | ||
1960 | /* normal should be zero */ | ||
1961 | writel(ccb_phyaddr_hi32, rwbuffer++); | ||
1962 | /* postQ size (256 + 8)*4 */ | ||
1963 | writel(post_queue_phyaddr, rwbuffer++); | ||
1964 | /* doneQ size (256 + 8)*4 */ | ||
1965 | writel(post_queue_phyaddr + 1056, rwbuffer++); | ||
1966 | /* ccb maxQ size must be --> [(256 + 8)*4]*/ | ||
1967 | writel(1056, rwbuffer); | ||
1968 | |||
1969 | writel(ARCMSR_MESSAGE_SET_CONFIG, reg->drv2iop_doorbell_reg); | ||
1970 | if (arcmsr_hbb_wait_msgint_ready(acb)) { | ||
1971 | printk(KERN_NOTICE "arcmsr%d: 'set command Q window' \ | ||
1972 | timeout \n",acb->host->host_no); | ||
1973 | return 1; | ||
1974 | } | ||
1337 | 1975 | ||
1338 | case ARCMSR_DEV_INIT_FAIL: { | 1976 | writel(ARCMSR_MESSAGE_START_DRIVER_MODE, reg->drv2iop_doorbell_reg); |
1339 | acb->devstate[id][lun] = | 1977 | if (arcmsr_hbb_wait_msgint_ready(acb)) { |
1340 | ARECA_RAID_GONE; | 1978 | printk(KERN_NOTICE "arcmsr%d: 'can not set diver mode \n"\ |
1341 | ccb->pcmd->result = | 1979 | ,acb->host->host_no); |
1342 | DID_BAD_TARGET << 16; | 1980 | return 1; |
1343 | arcmsr_ccb_complete(ccb, 1); | 1981 | } |
1344 | } | 1982 | arcmsr_enable_outbound_ints(acb, intmask_org); |
1345 | break; | 1983 | } |
1984 | break; | ||
1985 | } | ||
1986 | return 0; | ||
1987 | } | ||
1346 | 1988 | ||
1347 | case ARCMSR_DEV_CHECK_CONDITION: { | 1989 | static void arcmsr_wait_firmware_ready(struct AdapterControlBlock *acb) |
1348 | acb->devstate[id][lun] = | 1990 | { |
1349 | ARECA_RAID_GOOD; | 1991 | uint32_t firmware_state = 0; |
1350 | arcmsr_report_sense_info(ccb); | ||
1351 | arcmsr_ccb_complete(ccb, 1); | ||
1352 | } | ||
1353 | break; | ||
1354 | 1992 | ||
1355 | default: | 1993 | switch (acb->adapter_type) { |
1356 | printk(KERN_NOTICE | 1994 | |
1357 | "arcmsr%d: scsi id = %d \ | 1995 | case ACB_ADAPTER_TYPE_A: { |
1358 | lun = %d""polling and \ | 1996 | struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; |
1359 | getting command error \ | 1997 | do { |
1360 | done""but got unknown \ | 1998 | firmware_state = readl(®->outbound_msgaddr1); |
1361 | DeviceStatus = 0x%x \n", | 1999 | } while ((firmware_state & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK) == 0); |
1362 | acb->host->host_no, id, | 2000 | } |
1363 | lun, ccb->arcmsr_cdb.DeviceStatus); | 2001 | break; |
1364 | acb->devstate[id][lun] = | 2002 | |
1365 | ARECA_RAID_GONE; | 2003 | case ACB_ADAPTER_TYPE_B: { |
1366 | ccb->pcmd->result = | 2004 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; |
1367 | DID_BAD_TARGET << 16; | 2005 | do { |
1368 | arcmsr_ccb_complete(ccb, 1); | 2006 | firmware_state = readl(reg->iop2drv_doorbell_reg); |
1369 | break; | 2007 | } while ((firmware_state & ARCMSR_MESSAGE_FIRMWARE_OK) == 0); |
1370 | } | 2008 | } |
1371 | } | 2009 | break; |
1372 | found = 1; | ||
1373 | } | ||
1374 | } | 2010 | } |
1375 | if (found){ | 2011 | } |
1376 | outbound_intstatus = readl(®->outbound_intstatus) & \ | 2012 | |
1377 | acb->outbound_int_enable; | 2013 | static void arcmsr_start_hba_bgrb(struct AdapterControlBlock *acb) |
1378 | writel(outbound_intstatus, ®->outbound_intstatus); | 2014 | { |
1379 | /*clear interrupt*/ | 2015 | struct MessageUnit_A __iomem *reg = (struct MessageUnit_A *)acb->pmu; |
2016 | acb->acb_flags |= ACB_F_MSG_START_BGRB; | ||
2017 | writel(ARCMSR_INBOUND_MESG0_START_BGRB, ®->inbound_msgaddr0); | ||
2018 | if (arcmsr_hba_wait_msgint_ready(acb)) { | ||
2019 | printk(KERN_NOTICE "arcmsr%d: wait 'start adapter background \ | ||
2020 | rebulid' timeout \n", acb->host->host_no); | ||
1380 | } | 2021 | } |
1381 | return; | ||
1382 | } | 2022 | } |
1383 | 2023 | ||
2024 | static void arcmsr_start_hbb_bgrb(struct AdapterControlBlock *acb) | ||
2025 | { | ||
2026 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; | ||
2027 | acb->acb_flags |= ACB_F_MSG_START_BGRB; | ||
2028 | writel(ARCMSR_MESSAGE_START_BGRB, reg->drv2iop_doorbell_reg); | ||
2029 | if (arcmsr_hbb_wait_msgint_ready(acb)) { | ||
2030 | printk(KERN_NOTICE "arcmsr%d: wait 'start adapter background \ | ||
2031 | rebulid' timeout \n",acb->host->host_no); | ||
2032 | } | ||
2033 | } | ||
1384 | 2034 | ||
1385 | static void arcmsr_iop_init(struct AdapterControlBlock *acb) | 2035 | static void arcmsr_start_adapter_bgrb(struct AdapterControlBlock *acb) |
1386 | { | 2036 | { |
1387 | struct MessageUnit __iomem *reg = acb->pmu; | 2037 | switch (acb->adapter_type) { |
1388 | uint32_t intmask_org, mask, outbound_doorbell, firmware_state = 0; | 2038 | case ACB_ADAPTER_TYPE_A: |
2039 | arcmsr_start_hba_bgrb(acb); | ||
2040 | break; | ||
2041 | case ACB_ADAPTER_TYPE_B: | ||
2042 | arcmsr_start_hbb_bgrb(acb); | ||
2043 | break; | ||
2044 | } | ||
2045 | } | ||
1389 | 2046 | ||
1390 | do { | 2047 | static void arcmsr_clear_doorbell_queue_buffer(struct AdapterControlBlock *acb) |
1391 | firmware_state = readl(®->outbound_msgaddr1); | 2048 | { |
1392 | } while (!(firmware_state & ARCMSR_OUTBOUND_MESG1_FIRMWARE_OK)); | 2049 | switch (acb->adapter_type) { |
1393 | intmask_org = readl(®->outbound_intmask) | 2050 | case ACB_ADAPTER_TYPE_A: { |
1394 | | ARCMSR_MU_OUTBOUND_MESSAGE0_INTMASKENABLE; | 2051 | struct MessageUnit_A *reg = (struct MessageUnit_A *)acb->pmu; |
1395 | arcmsr_get_firmware_spec(acb); | 2052 | uint32_t outbound_doorbell; |
2053 | /* empty doorbell Qbuffer if door bell ringed */ | ||
2054 | outbound_doorbell = readl(®->outbound_doorbell); | ||
2055 | /*clear doorbell interrupt */ | ||
2056 | writel(outbound_doorbell, ®->outbound_doorbell); | ||
2057 | writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, ®->inbound_doorbell); | ||
2058 | } | ||
2059 | break; | ||
1396 | 2060 | ||
1397 | acb->acb_flags |= ACB_F_MSG_START_BGRB; | 2061 | case ACB_ADAPTER_TYPE_B: { |
1398 | writel(ARCMSR_INBOUND_MESG0_START_BGRB, ®->inbound_msgaddr0); | 2062 | struct MessageUnit_B *reg = (struct MessageUnit_B *)acb->pmu; |
1399 | if (arcmsr_wait_msgint_ready(acb)) { | 2063 | /*clear interrupt and message state*/ |
1400 | printk(KERN_NOTICE "arcmsr%d: " | 2064 | writel(ARCMSR_MESSAGE_INT_CLEAR_PATTERN, reg->iop2drv_doorbell_reg); |
1401 | "wait 'start adapter background rebulid' timeout\n", | 2065 | writel(ARCMSR_DRV2IOP_DATA_READ_OK, reg->drv2iop_doorbell_reg); |
1402 | acb->host->host_no); | 2066 | /* let IOP know data has been read */ |
2067 | } | ||
2068 | break; | ||
1403 | } | 2069 | } |
2070 | } | ||
1404 | 2071 | ||
1405 | outbound_doorbell = readl(®->outbound_doorbell); | 2072 | static void arcmsr_iop_init(struct AdapterControlBlock *acb) |
1406 | writel(outbound_doorbell, ®->outbound_doorbell); | 2073 | { |
1407 | writel(ARCMSR_INBOUND_DRIVER_DATA_READ_OK, ®->inbound_doorbell); | 2074 | uint32_t intmask_org; |
1408 | mask = ~(ARCMSR_MU_OUTBOUND_POSTQUEUE_INTMASKENABLE | 2075 | |
1409 | | ARCMSR_MU_OUTBOUND_DOORBELL_INTMASKENABLE); | 2076 | arcmsr_wait_firmware_ready(acb); |
1410 | writel(intmask_org & mask, ®->outbound_intmask); | 2077 | arcmsr_iop_confirm(acb); |
1411 | acb->outbound_int_enable = ~(intmask_org & mask) & 0x000000ff; | 2078 | /* disable all outbound interrupt */ |
2079 | intmask_org = arcmsr_disable_outbound_ints(acb); | ||
2080 | arcmsr_get_firmware_spec(acb); | ||
2081 | /*start background rebuild*/ | ||
2082 | arcmsr_start_adapter_bgrb(acb); | ||
2083 | /* empty doorbell Qbuffer if door bell ringed */ | ||
2084 | arcmsr_clear_doorbell_queue_buffer(acb); | ||
2085 | /* enable outbound Post Queue,outbound doorbell Interrupt */ | ||
2086 | arcmsr_enable_outbound_ints(acb, intmask_org); | ||
1412 | acb->acb_flags |= ACB_F_IOP_INITED; | 2087 | acb->acb_flags |= ACB_F_IOP_INITED; |
1413 | } | 2088 | } |
1414 | 2089 | ||
@@ -1421,22 +2096,24 @@ static void arcmsr_iop_reset(struct AdapterControlBlock *acb) | |||
1421 | if (atomic_read(&acb->ccboutstandingcount) != 0) { | 2096 | if (atomic_read(&acb->ccboutstandingcount) != 0) { |
1422 | /* talk to iop 331 outstanding command aborted */ | 2097 | /* talk to iop 331 outstanding command aborted */ |
1423 | arcmsr_abort_allcmd(acb); | 2098 | arcmsr_abort_allcmd(acb); |
2099 | |||
1424 | /* wait for 3 sec for all command aborted*/ | 2100 | /* wait for 3 sec for all command aborted*/ |
1425 | msleep_interruptible(3000); | 2101 | ssleep(3); |
2102 | |||
1426 | /* disable all outbound interrupt */ | 2103 | /* disable all outbound interrupt */ |
1427 | intmask_org = arcmsr_disable_outbound_ints(acb); | 2104 | intmask_org = arcmsr_disable_outbound_ints(acb); |
1428 | /* clear all outbound posted Q */ | 2105 | /* clear all outbound posted Q */ |
1429 | arcmsr_done4_abort_postqueue(acb); | 2106 | arcmsr_done4abort_postqueue(acb); |
1430 | for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { | 2107 | for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { |
1431 | ccb = acb->pccb_pool[i]; | 2108 | ccb = acb->pccb_pool[i]; |
1432 | if (ccb->startdone == ARCMSR_CCB_START) { | 2109 | if (ccb->startdone == ARCMSR_CCB_START) { |
1433 | ccb->startdone = ARCMSR_CCB_ABORTED; | 2110 | ccb->startdone = ARCMSR_CCB_ABORTED; |
2111 | arcmsr_ccb_complete(ccb, 1); | ||
1434 | } | 2112 | } |
1435 | } | 2113 | } |
1436 | /* enable all outbound interrupt */ | 2114 | /* enable all outbound interrupt */ |
1437 | arcmsr_enable_outbound_ints(acb, intmask_org); | 2115 | arcmsr_enable_outbound_ints(acb, intmask_org); |
1438 | } | 2116 | } |
1439 | |||
1440 | } | 2117 | } |
1441 | 2118 | ||
1442 | static int arcmsr_bus_reset(struct scsi_cmnd *cmd) | 2119 | static int arcmsr_bus_reset(struct scsi_cmnd *cmd) |
@@ -1450,7 +2127,7 @@ static int arcmsr_bus_reset(struct scsi_cmnd *cmd) | |||
1450 | for (i = 0; i < 400; i++) { | 2127 | for (i = 0; i < 400; i++) { |
1451 | if (!atomic_read(&acb->ccboutstandingcount)) | 2128 | if (!atomic_read(&acb->ccboutstandingcount)) |
1452 | break; | 2129 | break; |
1453 | arcmsr_interrupt(acb); | 2130 | arcmsr_interrupt(acb);/* FIXME: need spinlock */ |
1454 | msleep(25); | 2131 | msleep(25); |
1455 | } | 2132 | } |
1456 | arcmsr_iop_reset(acb); | 2133 | arcmsr_iop_reset(acb); |
@@ -1468,7 +2145,7 @@ static void arcmsr_abort_one_cmd(struct AdapterControlBlock *acb, | |||
1468 | /* | 2145 | /* |
1469 | ** Wait for 3 sec for all command done. | 2146 | ** Wait for 3 sec for all command done. |
1470 | */ | 2147 | */ |
1471 | msleep_interruptible(3000); | 2148 | ssleep(3); |
1472 | 2149 | ||
1473 | intmask = arcmsr_disable_outbound_ints(acb); | 2150 | intmask = arcmsr_disable_outbound_ints(acb); |
1474 | arcmsr_polling_ccbdone(acb, ccb); | 2151 | arcmsr_polling_ccbdone(acb, ccb); |
@@ -1515,6 +2192,8 @@ static const char *arcmsr_info(struct Scsi_Host *host) | |||
1515 | 2192 | ||
1516 | switch (acb->pdev->device) { | 2193 | switch (acb->pdev->device) { |
1517 | case PCI_DEVICE_ID_ARECA_1110: | 2194 | case PCI_DEVICE_ID_ARECA_1110: |
2195 | case PCI_DEVICE_ID_ARECA_1200: | ||
2196 | case PCI_DEVICE_ID_ARECA_1202: | ||
1518 | case PCI_DEVICE_ID_ARECA_1210: | 2197 | case PCI_DEVICE_ID_ARECA_1210: |
1519 | raid6 = 0; | 2198 | raid6 = 0; |
1520 | /*FALLTHRU*/ | 2199 | /*FALLTHRU*/ |
@@ -1522,6 +2201,7 @@ static const char *arcmsr_info(struct Scsi_Host *host) | |||
1522 | case PCI_DEVICE_ID_ARECA_1130: | 2201 | case PCI_DEVICE_ID_ARECA_1130: |
1523 | case PCI_DEVICE_ID_ARECA_1160: | 2202 | case PCI_DEVICE_ID_ARECA_1160: |
1524 | case PCI_DEVICE_ID_ARECA_1170: | 2203 | case PCI_DEVICE_ID_ARECA_1170: |
2204 | case PCI_DEVICE_ID_ARECA_1201: | ||
1525 | case PCI_DEVICE_ID_ARECA_1220: | 2205 | case PCI_DEVICE_ID_ARECA_1220: |
1526 | case PCI_DEVICE_ID_ARECA_1230: | 2206 | case PCI_DEVICE_ID_ARECA_1230: |
1527 | case PCI_DEVICE_ID_ARECA_1260: | 2207 | case PCI_DEVICE_ID_ARECA_1260: |
@@ -1544,287 +2224,82 @@ static const char *arcmsr_info(struct Scsi_Host *host) | |||
1544 | ARCMSR_DRIVER_VERSION); | 2224 | ARCMSR_DRIVER_VERSION); |
1545 | return buf; | 2225 | return buf; |
1546 | } | 2226 | } |
1547 | 2227 | #ifdef CONFIG_SCSI_ARCMSR_AER | |
1548 | static pci_ers_result_t arcmsr_pci_slot_reset(struct pci_dev *pdev) | 2228 | static pci_ers_result_t arcmsr_pci_slot_reset(struct pci_dev *pdev) |
1549 | { | 2229 | { |
1550 | struct Scsi_Host *host; | 2230 | struct Scsi_Host *host = pci_get_drvdata(pdev); |
1551 | struct AdapterControlBlock *acb; | 2231 | struct AdapterControlBlock *acb = |
1552 | uint8_t bus, dev_fun; | 2232 | (struct AdapterControlBlock *) host->hostdata; |
1553 | int error; | 2233 | uint32_t intmask_org; |
1554 | 2234 | int i, j; | |
1555 | error = pci_enable_device(pdev); | ||
1556 | if (error) | ||
1557 | return PCI_ERS_RESULT_DISCONNECT; | ||
1558 | pci_set_master(pdev); | ||
1559 | |||
1560 | host = scsi_host_alloc(&arcmsr_scsi_host_template, sizeof \ | ||
1561 | (struct AdapterControlBlock)); | ||
1562 | if (!host) | ||
1563 | return PCI_ERS_RESULT_DISCONNECT; | ||
1564 | acb = (struct AdapterControlBlock *)host->hostdata; | ||
1565 | memset(acb, 0, sizeof (struct AdapterControlBlock)); | ||
1566 | |||
1567 | error = pci_set_dma_mask(pdev, DMA_64BIT_MASK); | ||
1568 | if (error) { | ||
1569 | error = pci_set_dma_mask(pdev, DMA_32BIT_MASK); | ||
1570 | if (error) { | ||
1571 | printk(KERN_WARNING | ||
1572 | "scsi%d: No suitable DMA mask available\n", | ||
1573 | host->host_no); | ||
1574 | return PCI_ERS_RESULT_DISCONNECT; | ||
1575 | } | ||
1576 | } | ||
1577 | bus = pdev->bus->number; | ||
1578 | dev_fun = pdev->devfn; | ||
1579 | acb = (struct AdapterControlBlock *) host->hostdata; | ||
1580 | memset(acb, 0, sizeof(struct AdapterControlBlock)); | ||
1581 | acb->pdev = pdev; | ||
1582 | acb->host = host; | ||
1583 | host->max_sectors = ARCMSR_MAX_XFER_SECTORS; | ||
1584 | host->max_lun = ARCMSR_MAX_TARGETLUN; | ||
1585 | host->max_id = ARCMSR_MAX_TARGETID;/*16:8*/ | ||
1586 | host->max_cmd_len = 16; /*this is issue of 64bit LBA, over 2T byte*/ | ||
1587 | host->sg_tablesize = ARCMSR_MAX_SG_ENTRIES; | ||
1588 | host->can_queue = ARCMSR_MAX_FREECCB_NUM; /* max simultaneous cmds */ | ||
1589 | host->cmd_per_lun = ARCMSR_MAX_CMD_PERLUN; | ||
1590 | host->this_id = ARCMSR_SCSI_INITIATOR_ID; | ||
1591 | host->unique_id = (bus << 8) | dev_fun; | ||
1592 | host->irq = pdev->irq; | ||
1593 | error = pci_request_regions(pdev, "arcmsr"); | ||
1594 | if (error) | ||
1595 | return PCI_ERS_RESULT_DISCONNECT; | ||
1596 | 2235 | ||
1597 | acb->pmu = ioremap(pci_resource_start(pdev, 0), | 2236 | if (pci_enable_device(pdev)) { |
1598 | pci_resource_len(pdev, 0)); | ||
1599 | if (!acb->pmu) { | ||
1600 | printk(KERN_NOTICE "arcmsr%d: memory" | ||
1601 | " mapping region fail \n", acb->host->host_no); | ||
1602 | return PCI_ERS_RESULT_DISCONNECT; | 2237 | return PCI_ERS_RESULT_DISCONNECT; |
1603 | } | 2238 | } |
2239 | pci_set_master(pdev); | ||
2240 | intmask_org = arcmsr_disable_outbound_ints(acb); | ||
1604 | acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED | | 2241 | acb->acb_flags |= (ACB_F_MESSAGE_WQBUFFER_CLEARED | |
1605 | ACB_F_MESSAGE_RQBUFFER_CLEARED | | 2242 | ACB_F_MESSAGE_RQBUFFER_CLEARED | |
1606 | ACB_F_MESSAGE_WQBUFFER_READED); | 2243 | ACB_F_MESSAGE_WQBUFFER_READED); |
1607 | acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER; | 2244 | acb->acb_flags &= ~ACB_F_SCSISTOPADAPTER; |
1608 | INIT_LIST_HEAD(&acb->ccb_free_list); | 2245 | for (i = 0; i < ARCMSR_MAX_TARGETID; i++) |
1609 | 2246 | for (j = 0; j < ARCMSR_MAX_TARGETLUN; j++) | |
1610 | error = arcmsr_alloc_ccb_pool(acb); | 2247 | acb->devstate[i][j] = ARECA_RAID_GONE; |
1611 | if (error) | ||
1612 | return PCI_ERS_RESULT_DISCONNECT; | ||
1613 | |||
1614 | error = request_irq(pdev->irq, arcmsr_do_interrupt, | ||
1615 | IRQF_DISABLED | IRQF_SHARED, "arcmsr", acb); | ||
1616 | if (error) | ||
1617 | return PCI_ERS_RESULT_DISCONNECT; | ||
1618 | |||
1619 | arcmsr_iop_init(acb); | ||
1620 | if (strncmp(acb->firm_version, "V1.42", 5) >= 0) | ||
1621 | host->max_sectors = ARCMSR_MAX_XFER_SECTORS_B; | ||
1622 | |||
1623 | pci_set_drvdata(pdev, host); | ||
1624 | |||
1625 | error = scsi_add_host(host, &pdev->dev); | ||
1626 | if (error) | ||
1627 | return PCI_ERS_RESULT_DISCONNECT; | ||
1628 | 2248 | ||
1629 | error = arcmsr_alloc_sysfs_attr(acb); | 2249 | arcmsr_wait_firmware_ready(acb); |
1630 | if (error) | 2250 | arcmsr_iop_confirm(acb); |
1631 | return PCI_ERS_RESULT_DISCONNECT; | 2251 | /* disable all outbound interrupt */ |
2252 | arcmsr_get_firmware_spec(acb); | ||
2253 | /*start background rebuild*/ | ||
2254 | arcmsr_start_adapter_bgrb(acb); | ||
2255 | /* empty doorbell Qbuffer if door bell ringed */ | ||
2256 | arcmsr_clear_doorbell_queue_buffer(acb); | ||
2257 | /* enable outbound Post Queue,outbound doorbell Interrupt */ | ||
2258 | arcmsr_enable_outbound_ints(acb, intmask_org); | ||
2259 | acb->acb_flags |= ACB_F_IOP_INITED; | ||
1632 | 2260 | ||
1633 | scsi_scan_host(host); | 2261 | pci_enable_pcie_error_reporting(pdev); |
1634 | return PCI_ERS_RESULT_RECOVERED; | 2262 | return PCI_ERS_RESULT_RECOVERED; |
1635 | } | 2263 | } |
1636 | 2264 | ||
1637 | static void arcmsr_pci_ers_need_reset_forepart(struct pci_dev *pdev) | 2265 | static void arcmsr_pci_ers_need_reset_forepart(struct pci_dev *pdev) |
1638 | { | 2266 | { |
1639 | struct Scsi_Host *host = pci_get_drvdata(pdev); | 2267 | struct Scsi_Host *host = pci_get_drvdata(pdev); |
1640 | struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; | 2268 | struct AdapterControlBlock *acb = (struct AdapterControlBlock *)host->hostdata; |
1641 | struct MessageUnit __iomem *reg = acb->pmu; | ||
1642 | struct CommandControlBlock *ccb; | 2269 | struct CommandControlBlock *ccb; |
1643 | /*clear and abort all outbound posted Q*/ | 2270 | uint32_t intmask_org; |
1644 | int i = 0, found = 0; | 2271 | int i = 0; |
1645 | int id, lun; | ||
1646 | uint32_t flag_ccb, outbound_intstatus; | ||
1647 | |||
1648 | while (((flag_ccb = readl(®->outbound_queueport)) != 0xFFFFFFFF) && | ||
1649 | (i++ < 256)){ | ||
1650 | ccb = (struct CommandControlBlock *)(acb->vir2phy_offset | ||
1651 | + (flag_ccb << 5)); | ||
1652 | if (ccb){ | ||
1653 | if ((ccb->acb != acb)||(ccb->startdone != | ||
1654 | ARCMSR_CCB_START)){ | ||
1655 | printk(KERN_NOTICE "arcmsr%d: polling \ | ||
1656 | get an illegal ccb"" command done ccb = '0x%p'" | ||
1657 | "ccboutstandingcount = %d \n", | ||
1658 | acb->host->host_no, ccb, | ||
1659 | atomic_read(&acb->ccboutstandingcount)); | ||
1660 | continue; | ||
1661 | } | ||
1662 | |||
1663 | id = ccb->pcmd->device->id; | ||
1664 | lun = ccb->pcmd->device->lun; | ||
1665 | if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) { | ||
1666 | if (acb->devstate[id][lun] == | ||
1667 | ARECA_RAID_GONE) | ||
1668 | acb->devstate[id][lun] = | ||
1669 | ARECA_RAID_GOOD; | ||
1670 | ccb->pcmd->result = DID_OK << 16; | ||
1671 | arcmsr_ccb_complete(ccb, 1); | ||
1672 | } | ||
1673 | else { | ||
1674 | switch(ccb->arcmsr_cdb.DeviceStatus) { | ||
1675 | case ARCMSR_DEV_SELECT_TIMEOUT: { | ||
1676 | acb->devstate[id][lun] = | ||
1677 | ARECA_RAID_GONE; | ||
1678 | ccb->pcmd->result = | ||
1679 | DID_NO_CONNECT << 16; | ||
1680 | arcmsr_ccb_complete(ccb, 1); | ||
1681 | } | ||
1682 | break; | ||
1683 | |||
1684 | case ARCMSR_DEV_ABORTED: | ||
1685 | |||
1686 | case ARCMSR_DEV_INIT_FAIL: { | ||
1687 | acb->devstate[id][lun] = | ||
1688 | ARECA_RAID_GONE; | ||
1689 | ccb->pcmd->result = | ||
1690 | DID_BAD_TARGET << 16; | ||
1691 | arcmsr_ccb_complete(ccb, 1); | ||
1692 | } | ||
1693 | break; | ||
1694 | |||
1695 | case ARCMSR_DEV_CHECK_CONDITION: { | ||
1696 | acb->devstate[id][lun] = | ||
1697 | ARECA_RAID_GOOD; | ||
1698 | arcmsr_report_sense_info(ccb); | ||
1699 | arcmsr_ccb_complete(ccb, 1); | ||
1700 | } | ||
1701 | break; | ||
1702 | 2272 | ||
1703 | default: | 2273 | if (atomic_read(&acb->ccboutstandingcount) != 0) { |
1704 | printk(KERN_NOTICE | 2274 | /* talk to iop 331 outstanding command aborted */ |
1705 | "arcmsr%d: scsi \ | 2275 | arcmsr_abort_allcmd(acb); |
1706 | id = %d lun = %d" | 2276 | /* wait for 3 sec for all command aborted*/ |
1707 | " polling and \ | 2277 | ssleep(3); |
1708 | getting command \ | 2278 | /* disable all outbound interrupt */ |
1709 | error done" | 2279 | intmask_org = arcmsr_disable_outbound_ints(acb); |
1710 | "but got unknown \ | 2280 | /* clear all outbound posted Q */ |
1711 | DeviceStatus = 0x%x \n" | 2281 | arcmsr_done4abort_postqueue(acb); |
1712 | , acb->host->host_no, | 2282 | for (i = 0; i < ARCMSR_MAX_FREECCB_NUM; i++) { |
1713 | id, lun, | 2283 | ccb = acb->pccb_pool[i]; |
1714 | ccb->arcmsr_cdb.DeviceStatus); | 2284 | if (ccb->startdone == ARCMSR_CCB_START) { |
1715 | acb->devstate[id][lun] = | 2285 | ccb->startdone = ARCMSR_CCB_ABORTED; |
1716 | ARECA_RAID_GONE; | 2286 | arcmsr_ccb_complete(ccb, 1); |
1717 | ccb->pcmd->result = | ||
1718 | DID_BAD_TARGET << 16; | ||
1719 | arcmsr_ccb_complete(ccb, 1); | ||
1720 | break; | ||
1721 | } | ||
1722 | } | ||
1723 | found = 1; | ||
1724 | } | 2287 | } |
1725 | } | 2288 | } |
1726 | if (found){ | 2289 | /* enable all outbound interrupt */ |
1727 | outbound_intstatus = readl(®->outbound_intstatus) & | 2290 | arcmsr_enable_outbound_ints(acb, intmask_org); |
1728 | acb->outbound_int_enable; | 2291 | } |
1729 | writel(outbound_intstatus, ®->outbound_intstatus); | 2292 | pci_disable_device(pdev); |
1730 | /*clear interrupt*/ | ||
1731 | } | ||
1732 | return; | ||
1733 | } | 2293 | } |
1734 | 2294 | ||
1735 | |||
1736 | static void arcmsr_pci_ers_disconnect_forepart(struct pci_dev *pdev) | 2295 | static void arcmsr_pci_ers_disconnect_forepart(struct pci_dev *pdev) |
1737 | { | 2296 | { |
1738 | struct Scsi_Host *host = pci_get_drvdata(pdev); | 2297 | struct Scsi_Host *host = pci_get_drvdata(pdev); |
1739 | struct AdapterControlBlock *acb = (struct AdapterControlBlock *) host->hostdata; | 2298 | struct AdapterControlBlock *acb = \ |
1740 | struct MessageUnit __iomem *reg = acb->pmu; | 2299 | (struct AdapterControlBlock *)host->hostdata; |
1741 | struct CommandControlBlock *ccb; | ||
1742 | /*clear and abort all outbound posted Q*/ | ||
1743 | int i = 0, found = 0; | ||
1744 | int id, lun; | ||
1745 | uint32_t flag_ccb, outbound_intstatus; | ||
1746 | |||
1747 | while (((flag_ccb = readl(®->outbound_queueport)) != 0xFFFFFFFF) && | ||
1748 | (i++ < 256)){ | ||
1749 | ccb = (struct CommandControlBlock *)(acb->vir2phy_offset + | ||
1750 | (flag_ccb << 5)); | ||
1751 | if (ccb){ | ||
1752 | if ((ccb->acb != acb)||(ccb->startdone != | ||
1753 | ARCMSR_CCB_START)){ | ||
1754 | printk(KERN_NOTICE | ||
1755 | "arcmsr%d: polling get an illegal ccb" | ||
1756 | " command done ccb = '0x%p'" | ||
1757 | "ccboutstandingcount = %d \n", | ||
1758 | acb->host->host_no, ccb, | ||
1759 | atomic_read(&acb->ccboutstandingcount)); | ||
1760 | continue; | ||
1761 | } | ||
1762 | |||
1763 | id = ccb->pcmd->device->id; | ||
1764 | lun = ccb->pcmd->device->lun; | ||
1765 | if (!(flag_ccb & ARCMSR_CCBREPLY_FLAG_ERROR)) { | ||
1766 | if (acb->devstate[id][lun] == ARECA_RAID_GONE) | ||
1767 | acb->devstate[id][lun] = ARECA_RAID_GOOD; | ||
1768 | ccb->pcmd->result = DID_OK << 16; | ||
1769 | arcmsr_ccb_complete(ccb, 1); | ||
1770 | } | ||
1771 | else { | ||
1772 | switch(ccb->arcmsr_cdb.DeviceStatus) { | ||
1773 | case ARCMSR_DEV_SELECT_TIMEOUT: { | ||
1774 | acb->devstate[id][lun] = | ||
1775 | ARECA_RAID_GONE; | ||
1776 | ccb->pcmd->result = | ||
1777 | DID_NO_CONNECT << 16; | ||
1778 | arcmsr_ccb_complete(ccb, 1); | ||
1779 | } | ||
1780 | break; | ||
1781 | |||
1782 | case ARCMSR_DEV_ABORTED: | ||
1783 | |||
1784 | case ARCMSR_DEV_INIT_FAIL: { | ||
1785 | acb->devstate[id][lun] = | ||
1786 | ARECA_RAID_GONE; | ||
1787 | ccb->pcmd->result = | ||
1788 | DID_BAD_TARGET << 16; | ||
1789 | arcmsr_ccb_complete(ccb, 1); | ||
1790 | } | ||
1791 | break; | ||
1792 | 2300 | ||
1793 | case ARCMSR_DEV_CHECK_CONDITION: { | 2301 | arcmsr_stop_adapter_bgrb(acb); |
1794 | acb->devstate[id][lun] = | 2302 | arcmsr_flush_adapter_cache(acb); |
1795 | ARECA_RAID_GOOD; | ||
1796 | arcmsr_report_sense_info(ccb); | ||
1797 | arcmsr_ccb_complete(ccb, 1); | ||
1798 | } | ||
1799 | break; | ||
1800 | |||
1801 | default: | ||
1802 | printk(KERN_NOTICE "arcmsr%d: \ | ||
1803 | scsi id = %d lun = %d" | ||
1804 | " polling and \ | ||
1805 | getting command error done" | ||
1806 | "but got unknown \ | ||
1807 | DeviceStatus = 0x%x \n" | ||
1808 | , acb->host->host_no, | ||
1809 | id, lun, ccb->arcmsr_cdb.DeviceStatus); | ||
1810 | acb->devstate[id][lun] = | ||
1811 | ARECA_RAID_GONE; | ||
1812 | ccb->pcmd->result = | ||
1813 | DID_BAD_TARGET << 16; | ||
1814 | arcmsr_ccb_complete(ccb, 1); | ||
1815 | break; | ||
1816 | } | ||
1817 | } | ||
1818 | found = 1; | ||
1819 | } | ||
1820 | } | ||
1821 | if (found){ | ||
1822 | outbound_intstatus = readl(®->outbound_intstatus) & | ||
1823 | acb->outbound_int_enable; | ||
1824 | writel(outbound_intstatus, ®->outbound_intstatus); | ||
1825 | /*clear interrupt*/ | ||
1826 | } | ||
1827 | return; | ||
1828 | } | 2303 | } |
1829 | 2304 | ||
1830 | static pci_ers_result_t arcmsr_pci_error_detected(struct pci_dev *pdev, | 2305 | static pci_ers_result_t arcmsr_pci_error_detected(struct pci_dev *pdev, |
@@ -1840,5 +2315,6 @@ static pci_ers_result_t arcmsr_pci_error_detected(struct pci_dev *pdev, | |||
1840 | break; | 2315 | break; |
1841 | default: | 2316 | default: |
1842 | return PCI_ERS_RESULT_NEED_RESET; | 2317 | return PCI_ERS_RESULT_NEED_RESET; |
1843 | } | 2318 | } |
1844 | } | 2319 | } |
2320 | #endif | ||
diff --git a/drivers/scsi/atari_NCR5380.c b/drivers/scsi/atari_NCR5380.c index 03dbe60c264a..52d0b87e9aa4 100644 --- a/drivers/scsi/atari_NCR5380.c +++ b/drivers/scsi/atari_NCR5380.c | |||
@@ -2041,7 +2041,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2041 | sink = 1; | 2041 | sink = 1; |
2042 | do_abort(instance); | 2042 | do_abort(instance); |
2043 | cmd->result = DID_ERROR << 16; | 2043 | cmd->result = DID_ERROR << 16; |
2044 | cmd->done(cmd); | 2044 | cmd->scsi_done(cmd); |
2045 | return; | 2045 | return; |
2046 | #endif | 2046 | #endif |
2047 | case PHASE_DATAIN: | 2047 | case PHASE_DATAIN: |
@@ -2100,7 +2100,7 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2100 | sink = 1; | 2100 | sink = 1; |
2101 | do_abort(instance); | 2101 | do_abort(instance); |
2102 | cmd->result = DID_ERROR << 16; | 2102 | cmd->result = DID_ERROR << 16; |
2103 | cmd->done(cmd); | 2103 | cmd->scsi_done(cmd); |
2104 | /* XXX - need to source or sink data here, as appropriate */ | 2104 | /* XXX - need to source or sink data here, as appropriate */ |
2105 | } else { | 2105 | } else { |
2106 | #ifdef REAL_DMA | 2106 | #ifdef REAL_DMA |
@@ -2235,24 +2235,17 @@ static void NCR5380_information_transfer(struct Scsi_Host *instance) | |||
2235 | cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); | 2235 | cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); |
2236 | 2236 | ||
2237 | #ifdef AUTOSENSE | 2237 | #ifdef AUTOSENSE |
2238 | if ((cmd->cmnd[0] == REQUEST_SENSE) && | ||
2239 | hostdata->ses.cmd_len) { | ||
2240 | scsi_eh_restore_cmnd(cmd, &hostdata->ses); | ||
2241 | hostdata->ses.cmd_len = 0 ; | ||
2242 | } | ||
2243 | |||
2238 | if ((cmd->cmnd[0] != REQUEST_SENSE) && | 2244 | if ((cmd->cmnd[0] != REQUEST_SENSE) && |
2239 | (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) { | 2245 | (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) { |
2246 | scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0); | ||
2247 | |||
2240 | ASEN_PRINTK("scsi%d: performing request sense\n", HOSTNO); | 2248 | ASEN_PRINTK("scsi%d: performing request sense\n", HOSTNO); |
2241 | cmd->cmnd[0] = REQUEST_SENSE; | ||
2242 | cmd->cmnd[1] &= 0xe0; | ||
2243 | cmd->cmnd[2] = 0; | ||
2244 | cmd->cmnd[3] = 0; | ||
2245 | cmd->cmnd[4] = sizeof(cmd->sense_buffer); | ||
2246 | cmd->cmnd[5] = 0; | ||
2247 | cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); | ||
2248 | |||
2249 | cmd->use_sg = 0; | ||
2250 | /* this is initialized from initialize_SCp | ||
2251 | cmd->SCp.buffer = NULL; | ||
2252 | cmd->SCp.buffers_residual = 0; | ||
2253 | */ | ||
2254 | cmd->request_buffer = (char *) cmd->sense_buffer; | ||
2255 | cmd->request_bufflen = sizeof(cmd->sense_buffer); | ||
2256 | 2249 | ||
2257 | local_irq_save(flags); | 2250 | local_irq_save(flags); |
2258 | LIST(cmd,hostdata->issue_queue); | 2251 | LIST(cmd,hostdata->issue_queue); |
diff --git a/drivers/scsi/bvme6000_scsi.c b/drivers/scsi/bvme6000_scsi.c index cac354086737..d858f3d41274 100644 --- a/drivers/scsi/bvme6000_scsi.c +++ b/drivers/scsi/bvme6000_scsi.c | |||
@@ -36,19 +36,18 @@ static struct platform_device *bvme6000_scsi_device; | |||
36 | static __devinit int | 36 | static __devinit int |
37 | bvme6000_probe(struct device *dev) | 37 | bvme6000_probe(struct device *dev) |
38 | { | 38 | { |
39 | struct Scsi_Host * host = NULL; | 39 | struct Scsi_Host *host; |
40 | struct NCR_700_Host_Parameters *hostdata; | 40 | struct NCR_700_Host_Parameters *hostdata; |
41 | 41 | ||
42 | if (!MACH_IS_BVME6000) | 42 | if (!MACH_IS_BVME6000) |
43 | goto out; | 43 | goto out; |
44 | 44 | ||
45 | hostdata = kmalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); | 45 | hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); |
46 | if (hostdata == NULL) { | 46 | if (!hostdata) { |
47 | printk(KERN_ERR "bvme6000-scsi: " | 47 | printk(KERN_ERR "bvme6000-scsi: " |
48 | "Failed to allocate host data\n"); | 48 | "Failed to allocate host data\n"); |
49 | goto out; | 49 | goto out; |
50 | } | 50 | } |
51 | memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters)); | ||
52 | 51 | ||
53 | /* Fill in the required pieces of hostdata */ | 52 | /* Fill in the required pieces of hostdata */ |
54 | hostdata->base = (void __iomem *)BVME_NCR53C710_BASE; | 53 | hostdata->base = (void __iomem *)BVME_NCR53C710_BASE; |
diff --git a/drivers/scsi/constants.c b/drivers/scsi/constants.c index 2a458d66b6ff..024553f9c247 100644 --- a/drivers/scsi/constants.c +++ b/drivers/scsi/constants.c | |||
@@ -1235,7 +1235,21 @@ scsi_print_sense_hdr(const char *name, struct scsi_sense_hdr *sshdr) | |||
1235 | } | 1235 | } |
1236 | EXPORT_SYMBOL(scsi_print_sense_hdr); | 1236 | EXPORT_SYMBOL(scsi_print_sense_hdr); |
1237 | 1237 | ||
1238 | /* | ||
1239 | * Print normalized SCSI sense header with device information and a prefix. | ||
1240 | */ | ||
1238 | void | 1241 | void |
1242 | scsi_cmd_print_sense_hdr(struct scsi_cmnd *scmd, const char *desc, | ||
1243 | struct scsi_sense_hdr *sshdr) | ||
1244 | { | ||
1245 | scmd_printk(KERN_INFO, scmd, "%s: ", desc); | ||
1246 | scsi_show_sense_hdr(sshdr); | ||
1247 | scmd_printk(KERN_INFO, scmd, "%s: ", desc); | ||
1248 | scsi_show_extd_sense(sshdr->asc, sshdr->ascq); | ||
1249 | } | ||
1250 | EXPORT_SYMBOL(scsi_cmd_print_sense_hdr); | ||
1251 | |||
1252 | static void | ||
1239 | scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len, | 1253 | scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len, |
1240 | struct scsi_sense_hdr *sshdr) | 1254 | struct scsi_sense_hdr *sshdr) |
1241 | { | 1255 | { |
@@ -1258,7 +1272,7 @@ scsi_decode_sense_buffer(const unsigned char *sense_buffer, int sense_len, | |||
1258 | } | 1272 | } |
1259 | } | 1273 | } |
1260 | 1274 | ||
1261 | void | 1275 | static void |
1262 | scsi_decode_sense_extras(const unsigned char *sense_buffer, int sense_len, | 1276 | scsi_decode_sense_extras(const unsigned char *sense_buffer, int sense_len, |
1263 | struct scsi_sense_hdr *sshdr) | 1277 | struct scsi_sense_hdr *sshdr) |
1264 | { | 1278 | { |
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c index 7b8a3457b696..1591824cf4b3 100644 --- a/drivers/scsi/dc395x.c +++ b/drivers/scsi/dc395x.c | |||
@@ -778,7 +778,7 @@ static void srb_waiting_insert(struct DeviceCtlBlk *dcb, | |||
778 | struct ScsiReqBlk *srb) | 778 | struct ScsiReqBlk *srb) |
779 | { | 779 | { |
780 | dprintkdbg(DBG_0, "srb_waiting_insert: (pid#%li) <%02i-%i> srb=%p\n", | 780 | dprintkdbg(DBG_0, "srb_waiting_insert: (pid#%li) <%02i-%i> srb=%p\n", |
781 | srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); | 781 | srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb); |
782 | list_add(&srb->list, &dcb->srb_waiting_list); | 782 | list_add(&srb->list, &dcb->srb_waiting_list); |
783 | } | 783 | } |
784 | 784 | ||
@@ -787,7 +787,7 @@ static void srb_waiting_append(struct DeviceCtlBlk *dcb, | |||
787 | struct ScsiReqBlk *srb) | 787 | struct ScsiReqBlk *srb) |
788 | { | 788 | { |
789 | dprintkdbg(DBG_0, "srb_waiting_append: (pid#%li) <%02i-%i> srb=%p\n", | 789 | dprintkdbg(DBG_0, "srb_waiting_append: (pid#%li) <%02i-%i> srb=%p\n", |
790 | srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); | 790 | srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb); |
791 | list_add_tail(&srb->list, &dcb->srb_waiting_list); | 791 | list_add_tail(&srb->list, &dcb->srb_waiting_list); |
792 | } | 792 | } |
793 | 793 | ||
@@ -795,7 +795,7 @@ static void srb_waiting_append(struct DeviceCtlBlk *dcb, | |||
795 | static void srb_going_append(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) | 795 | static void srb_going_append(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) |
796 | { | 796 | { |
797 | dprintkdbg(DBG_0, "srb_going_append: (pid#%li) <%02i-%i> srb=%p\n", | 797 | dprintkdbg(DBG_0, "srb_going_append: (pid#%li) <%02i-%i> srb=%p\n", |
798 | srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); | 798 | srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb); |
799 | list_add_tail(&srb->list, &dcb->srb_going_list); | 799 | list_add_tail(&srb->list, &dcb->srb_going_list); |
800 | } | 800 | } |
801 | 801 | ||
@@ -805,7 +805,7 @@ static void srb_going_remove(struct DeviceCtlBlk *dcb, struct ScsiReqBlk *srb) | |||
805 | struct ScsiReqBlk *i; | 805 | struct ScsiReqBlk *i; |
806 | struct ScsiReqBlk *tmp; | 806 | struct ScsiReqBlk *tmp; |
807 | dprintkdbg(DBG_0, "srb_going_remove: (pid#%li) <%02i-%i> srb=%p\n", | 807 | dprintkdbg(DBG_0, "srb_going_remove: (pid#%li) <%02i-%i> srb=%p\n", |
808 | srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); | 808 | srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb); |
809 | 809 | ||
810 | list_for_each_entry_safe(i, tmp, &dcb->srb_going_list, list) | 810 | list_for_each_entry_safe(i, tmp, &dcb->srb_going_list, list) |
811 | if (i == srb) { | 811 | if (i == srb) { |
@@ -821,7 +821,7 @@ static void srb_waiting_remove(struct DeviceCtlBlk *dcb, | |||
821 | struct ScsiReqBlk *i; | 821 | struct ScsiReqBlk *i; |
822 | struct ScsiReqBlk *tmp; | 822 | struct ScsiReqBlk *tmp; |
823 | dprintkdbg(DBG_0, "srb_waiting_remove: (pid#%li) <%02i-%i> srb=%p\n", | 823 | dprintkdbg(DBG_0, "srb_waiting_remove: (pid#%li) <%02i-%i> srb=%p\n", |
824 | srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); | 824 | srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb); |
825 | 825 | ||
826 | list_for_each_entry_safe(i, tmp, &dcb->srb_waiting_list, list) | 826 | list_for_each_entry_safe(i, tmp, &dcb->srb_waiting_list, list) |
827 | if (i == srb) { | 827 | if (i == srb) { |
@@ -836,7 +836,7 @@ static void srb_going_to_waiting_move(struct DeviceCtlBlk *dcb, | |||
836 | { | 836 | { |
837 | dprintkdbg(DBG_0, | 837 | dprintkdbg(DBG_0, |
838 | "srb_going_to_waiting_move: (pid#%li) <%02i-%i> srb=%p\n", | 838 | "srb_going_to_waiting_move: (pid#%li) <%02i-%i> srb=%p\n", |
839 | srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); | 839 | srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb); |
840 | list_move(&srb->list, &dcb->srb_waiting_list); | 840 | list_move(&srb->list, &dcb->srb_waiting_list); |
841 | } | 841 | } |
842 | 842 | ||
@@ -846,7 +846,7 @@ static void srb_waiting_to_going_move(struct DeviceCtlBlk *dcb, | |||
846 | { | 846 | { |
847 | dprintkdbg(DBG_0, | 847 | dprintkdbg(DBG_0, |
848 | "srb_waiting_to_going_move: (pid#%li) <%02i-%i> srb=%p\n", | 848 | "srb_waiting_to_going_move: (pid#%li) <%02i-%i> srb=%p\n", |
849 | srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); | 849 | srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb); |
850 | list_move(&srb->list, &dcb->srb_going_list); | 850 | list_move(&srb->list, &dcb->srb_going_list); |
851 | } | 851 | } |
852 | 852 | ||
@@ -982,7 +982,7 @@ static void build_srb(struct scsi_cmnd *cmd, struct DeviceCtlBlk *dcb, | |||
982 | int nseg; | 982 | int nseg; |
983 | enum dma_data_direction dir = cmd->sc_data_direction; | 983 | enum dma_data_direction dir = cmd->sc_data_direction; |
984 | dprintkdbg(DBG_0, "build_srb: (pid#%li) <%02i-%i>\n", | 984 | dprintkdbg(DBG_0, "build_srb: (pid#%li) <%02i-%i>\n", |
985 | cmd->pid, dcb->target_id, dcb->target_lun); | 985 | cmd->serial_number, dcb->target_id, dcb->target_lun); |
986 | 986 | ||
987 | srb->dcb = dcb; | 987 | srb->dcb = dcb; |
988 | srb->cmd = cmd; | 988 | srb->cmd = cmd; |
@@ -1086,7 +1086,7 @@ static int dc395x_queue_command(struct scsi_cmnd *cmd, void (*done)(struct scsi_ | |||
1086 | struct AdapterCtlBlk *acb = | 1086 | struct AdapterCtlBlk *acb = |
1087 | (struct AdapterCtlBlk *)cmd->device->host->hostdata; | 1087 | (struct AdapterCtlBlk *)cmd->device->host->hostdata; |
1088 | dprintkdbg(DBG_0, "queue_command: (pid#%li) <%02i-%i> cmnd=0x%02x\n", | 1088 | dprintkdbg(DBG_0, "queue_command: (pid#%li) <%02i-%i> cmnd=0x%02x\n", |
1089 | cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); | 1089 | cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); |
1090 | 1090 | ||
1091 | /* Assume BAD_TARGET; will be cleared later */ | 1091 | /* Assume BAD_TARGET; will be cleared later */ |
1092 | cmd->result = DID_BAD_TARGET << 16; | 1092 | cmd->result = DID_BAD_TARGET << 16; |
@@ -1139,7 +1139,7 @@ static int dc395x_queue_command(struct scsi_cmnd *cmd, void (*done)(struct scsi_ | |||
1139 | /* process immediately */ | 1139 | /* process immediately */ |
1140 | send_srb(acb, srb); | 1140 | send_srb(acb, srb); |
1141 | } | 1141 | } |
1142 | dprintkdbg(DBG_1, "queue_command: (pid#%li) done\n", cmd->pid); | 1142 | dprintkdbg(DBG_1, "queue_command: (pid#%li) done\n", cmd->serial_number); |
1143 | return 0; | 1143 | return 0; |
1144 | 1144 | ||
1145 | complete: | 1145 | complete: |
@@ -1203,7 +1203,7 @@ static void dump_register_info(struct AdapterCtlBlk *acb, | |||
1203 | else | 1203 | else |
1204 | dprintkl(KERN_INFO, "dump: srb=%p cmd=%p (pid#%li) " | 1204 | dprintkl(KERN_INFO, "dump: srb=%p cmd=%p (pid#%li) " |
1205 | "cmnd=0x%02x <%02i-%i>\n", | 1205 | "cmnd=0x%02x <%02i-%i>\n", |
1206 | srb, srb->cmd, srb->cmd->pid, | 1206 | srb, srb->cmd, srb->cmd->serial_number, |
1207 | srb->cmd->cmnd[0], srb->cmd->device->id, | 1207 | srb->cmd->cmnd[0], srb->cmd->device->id, |
1208 | srb->cmd->device->lun); | 1208 | srb->cmd->device->lun); |
1209 | printk(" sglist=%p cnt=%i idx=%i len=%zu\n", | 1209 | printk(" sglist=%p cnt=%i idx=%i len=%zu\n", |
@@ -1300,7 +1300,7 @@ static int __dc395x_eh_bus_reset(struct scsi_cmnd *cmd) | |||
1300 | (struct AdapterCtlBlk *)cmd->device->host->hostdata; | 1300 | (struct AdapterCtlBlk *)cmd->device->host->hostdata; |
1301 | dprintkl(KERN_INFO, | 1301 | dprintkl(KERN_INFO, |
1302 | "eh_bus_reset: (pid#%li) target=<%02i-%i> cmd=%p\n", | 1302 | "eh_bus_reset: (pid#%li) target=<%02i-%i> cmd=%p\n", |
1303 | cmd->pid, cmd->device->id, cmd->device->lun, cmd); | 1303 | cmd->serial_number, cmd->device->id, cmd->device->lun, cmd); |
1304 | 1304 | ||
1305 | if (timer_pending(&acb->waiting_timer)) | 1305 | if (timer_pending(&acb->waiting_timer)) |
1306 | del_timer(&acb->waiting_timer); | 1306 | del_timer(&acb->waiting_timer); |
@@ -1367,7 +1367,7 @@ static int dc395x_eh_abort(struct scsi_cmnd *cmd) | |||
1367 | struct DeviceCtlBlk *dcb; | 1367 | struct DeviceCtlBlk *dcb; |
1368 | struct ScsiReqBlk *srb; | 1368 | struct ScsiReqBlk *srb; |
1369 | dprintkl(KERN_INFO, "eh_abort: (pid#%li) target=<%02i-%i> cmd=%p\n", | 1369 | dprintkl(KERN_INFO, "eh_abort: (pid#%li) target=<%02i-%i> cmd=%p\n", |
1370 | cmd->pid, cmd->device->id, cmd->device->lun, cmd); | 1370 | cmd->serial_number, cmd->device->id, cmd->device->lun, cmd); |
1371 | 1371 | ||
1372 | dcb = find_dcb(acb, cmd->device->id, cmd->device->lun); | 1372 | dcb = find_dcb(acb, cmd->device->id, cmd->device->lun); |
1373 | if (!dcb) { | 1373 | if (!dcb) { |
@@ -1494,7 +1494,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb, | |||
1494 | u8 s_stat, scsicommand, i, identify_message; | 1494 | u8 s_stat, scsicommand, i, identify_message; |
1495 | u8 *ptr; | 1495 | u8 *ptr; |
1496 | dprintkdbg(DBG_0, "start_scsi: (pid#%li) <%02i-%i> srb=%p\n", | 1496 | dprintkdbg(DBG_0, "start_scsi: (pid#%li) <%02i-%i> srb=%p\n", |
1497 | srb->cmd->pid, dcb->target_id, dcb->target_lun, srb); | 1497 | srb->cmd->serial_number, dcb->target_id, dcb->target_lun, srb); |
1498 | 1498 | ||
1499 | srb->tag_number = TAG_NONE; /* acb->tag_max_num: had error read in eeprom */ | 1499 | srb->tag_number = TAG_NONE; /* acb->tag_max_num: had error read in eeprom */ |
1500 | 1500 | ||
@@ -1504,7 +1504,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb, | |||
1504 | #if 1 | 1504 | #if 1 |
1505 | if (s_stat & 0x20 /* s_stat2 & 0x02000 */ ) { | 1505 | if (s_stat & 0x20 /* s_stat2 & 0x02000 */ ) { |
1506 | dprintkdbg(DBG_KG, "start_scsi: (pid#%li) BUSY %02x %04x\n", | 1506 | dprintkdbg(DBG_KG, "start_scsi: (pid#%li) BUSY %02x %04x\n", |
1507 | srb->cmd->pid, s_stat, s_stat2); | 1507 | srb->cmd->serial_number, s_stat, s_stat2); |
1508 | /* | 1508 | /* |
1509 | * Try anyway? | 1509 | * Try anyway? |
1510 | * | 1510 | * |
@@ -1522,14 +1522,14 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb, | |||
1522 | if (acb->active_dcb) { | 1522 | if (acb->active_dcb) { |
1523 | dprintkl(KERN_DEBUG, "start_scsi: (pid#%li) Attempt to start a" | 1523 | dprintkl(KERN_DEBUG, "start_scsi: (pid#%li) Attempt to start a" |
1524 | "command while another command (pid#%li) is active.", | 1524 | "command while another command (pid#%li) is active.", |
1525 | srb->cmd->pid, | 1525 | srb->cmd->serial_number, |
1526 | acb->active_dcb->active_srb ? | 1526 | acb->active_dcb->active_srb ? |
1527 | acb->active_dcb->active_srb->cmd->pid : 0); | 1527 | acb->active_dcb->active_srb->cmd->serial_number : 0); |
1528 | return 1; | 1528 | return 1; |
1529 | } | 1529 | } |
1530 | if (DC395x_read16(acb, TRM_S1040_SCSI_STATUS) & SCSIINTERRUPT) { | 1530 | if (DC395x_read16(acb, TRM_S1040_SCSI_STATUS) & SCSIINTERRUPT) { |
1531 | dprintkdbg(DBG_KG, "start_scsi: (pid#%li) Failed (busy)\n", | 1531 | dprintkdbg(DBG_KG, "start_scsi: (pid#%li) Failed (busy)\n", |
1532 | srb->cmd->pid); | 1532 | srb->cmd->serial_number); |
1533 | return 1; | 1533 | return 1; |
1534 | } | 1534 | } |
1535 | /* Allow starting of SCSI commands half a second before we allow the mid-level | 1535 | /* Allow starting of SCSI commands half a second before we allow the mid-level |
@@ -1603,7 +1603,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb, | |||
1603 | if (tag_number >= dcb->max_command) { | 1603 | if (tag_number >= dcb->max_command) { |
1604 | dprintkl(KERN_WARNING, "start_scsi: (pid#%li) " | 1604 | dprintkl(KERN_WARNING, "start_scsi: (pid#%li) " |
1605 | "Out of tags target=<%02i-%i>)\n", | 1605 | "Out of tags target=<%02i-%i>)\n", |
1606 | srb->cmd->pid, srb->cmd->device->id, | 1606 | srb->cmd->serial_number, srb->cmd->device->id, |
1607 | srb->cmd->device->lun); | 1607 | srb->cmd->device->lun); |
1608 | srb->state = SRB_READY; | 1608 | srb->state = SRB_READY; |
1609 | DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, | 1609 | DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, |
@@ -1622,7 +1622,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb, | |||
1622 | /*polling:*/ | 1622 | /*polling:*/ |
1623 | /* Send CDB ..command block ......... */ | 1623 | /* Send CDB ..command block ......... */ |
1624 | dprintkdbg(DBG_KG, "start_scsi: (pid#%li) <%02i-%i> cmnd=0x%02x tag=%i\n", | 1624 | dprintkdbg(DBG_KG, "start_scsi: (pid#%li) <%02i-%i> cmnd=0x%02x tag=%i\n", |
1625 | srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun, | 1625 | srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun, |
1626 | srb->cmd->cmnd[0], srb->tag_number); | 1626 | srb->cmd->cmnd[0], srb->tag_number); |
1627 | if (srb->flag & AUTO_REQSENSE) { | 1627 | if (srb->flag & AUTO_REQSENSE) { |
1628 | DC395x_write8(acb, TRM_S1040_SCSI_FIFO, REQUEST_SENSE); | 1628 | DC395x_write8(acb, TRM_S1040_SCSI_FIFO, REQUEST_SENSE); |
@@ -1647,7 +1647,7 @@ static u8 start_scsi(struct AdapterCtlBlk* acb, struct DeviceCtlBlk* dcb, | |||
1647 | * : Let's process it first! | 1647 | * : Let's process it first! |
1648 | */ | 1648 | */ |
1649 | dprintkdbg(DBG_0, "start_scsi: (pid#%li) <%02i-%i> Failed - busy\n", | 1649 | dprintkdbg(DBG_0, "start_scsi: (pid#%li) <%02i-%i> Failed - busy\n", |
1650 | srb->cmd->pid, dcb->target_id, dcb->target_lun); | 1650 | srb->cmd->serial_number, dcb->target_id, dcb->target_lun); |
1651 | srb->state = SRB_READY; | 1651 | srb->state = SRB_READY; |
1652 | free_tag(dcb, srb); | 1652 | free_tag(dcb, srb); |
1653 | srb->msg_count = 0; | 1653 | srb->msg_count = 0; |
@@ -1842,7 +1842,7 @@ static irqreturn_t dc395x_interrupt(int irq, void *dev_id) | |||
1842 | static void msgout_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, | 1842 | static void msgout_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, |
1843 | u16 *pscsi_status) | 1843 | u16 *pscsi_status) |
1844 | { | 1844 | { |
1845 | dprintkdbg(DBG_0, "msgout_phase0: (pid#%li)\n", srb->cmd->pid); | 1845 | dprintkdbg(DBG_0, "msgout_phase0: (pid#%li)\n", srb->cmd->serial_number); |
1846 | if (srb->state & (SRB_UNEXPECT_RESEL + SRB_ABORT_SENT)) | 1846 | if (srb->state & (SRB_UNEXPECT_RESEL + SRB_ABORT_SENT)) |
1847 | *pscsi_status = PH_BUS_FREE; /*.. initial phase */ | 1847 | *pscsi_status = PH_BUS_FREE; /*.. initial phase */ |
1848 | 1848 | ||
@@ -1856,18 +1856,18 @@ static void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, | |||
1856 | { | 1856 | { |
1857 | u16 i; | 1857 | u16 i; |
1858 | u8 *ptr; | 1858 | u8 *ptr; |
1859 | dprintkdbg(DBG_0, "msgout_phase1: (pid#%li)\n", srb->cmd->pid); | 1859 | dprintkdbg(DBG_0, "msgout_phase1: (pid#%li)\n", srb->cmd->serial_number); |
1860 | 1860 | ||
1861 | clear_fifo(acb, "msgout_phase1"); | 1861 | clear_fifo(acb, "msgout_phase1"); |
1862 | if (!(srb->state & SRB_MSGOUT)) { | 1862 | if (!(srb->state & SRB_MSGOUT)) { |
1863 | srb->state |= SRB_MSGOUT; | 1863 | srb->state |= SRB_MSGOUT; |
1864 | dprintkl(KERN_DEBUG, | 1864 | dprintkl(KERN_DEBUG, |
1865 | "msgout_phase1: (pid#%li) Phase unexpected\n", | 1865 | "msgout_phase1: (pid#%li) Phase unexpected\n", |
1866 | srb->cmd->pid); /* So what ? */ | 1866 | srb->cmd->serial_number); /* So what ? */ |
1867 | } | 1867 | } |
1868 | if (!srb->msg_count) { | 1868 | if (!srb->msg_count) { |
1869 | dprintkdbg(DBG_0, "msgout_phase1: (pid#%li) NOP msg\n", | 1869 | dprintkdbg(DBG_0, "msgout_phase1: (pid#%li) NOP msg\n", |
1870 | srb->cmd->pid); | 1870 | srb->cmd->serial_number); |
1871 | DC395x_write8(acb, TRM_S1040_SCSI_FIFO, MSG_NOP); | 1871 | DC395x_write8(acb, TRM_S1040_SCSI_FIFO, MSG_NOP); |
1872 | DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ | 1872 | DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ |
1873 | DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT); | 1873 | DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_FIFO_OUT); |
@@ -1887,7 +1887,7 @@ static void msgout_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, | |||
1887 | static void command_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, | 1887 | static void command_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, |
1888 | u16 *pscsi_status) | 1888 | u16 *pscsi_status) |
1889 | { | 1889 | { |
1890 | dprintkdbg(DBG_0, "command_phase0: (pid#%li)\n", srb->cmd->pid); | 1890 | dprintkdbg(DBG_0, "command_phase0: (pid#%li)\n", srb->cmd->serial_number); |
1891 | DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); | 1891 | DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); |
1892 | } | 1892 | } |
1893 | 1893 | ||
@@ -1898,7 +1898,7 @@ static void command_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, | |||
1898 | struct DeviceCtlBlk *dcb; | 1898 | struct DeviceCtlBlk *dcb; |
1899 | u8 *ptr; | 1899 | u8 *ptr; |
1900 | u16 i; | 1900 | u16 i; |
1901 | dprintkdbg(DBG_0, "command_phase1: (pid#%li)\n", srb->cmd->pid); | 1901 | dprintkdbg(DBG_0, "command_phase1: (pid#%li)\n", srb->cmd->serial_number); |
1902 | 1902 | ||
1903 | clear_fifo(acb, "command_phase1"); | 1903 | clear_fifo(acb, "command_phase1"); |
1904 | DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_CLRATN); | 1904 | DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_CLRATN); |
@@ -2042,7 +2042,7 @@ static void data_out_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, | |||
2042 | u16 scsi_status = *pscsi_status; | 2042 | u16 scsi_status = *pscsi_status; |
2043 | u32 d_left_counter = 0; | 2043 | u32 d_left_counter = 0; |
2044 | dprintkdbg(DBG_0, "data_out_phase0: (pid#%li) <%02i-%i>\n", | 2044 | dprintkdbg(DBG_0, "data_out_phase0: (pid#%li) <%02i-%i>\n", |
2045 | srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); | 2045 | srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun); |
2046 | 2046 | ||
2047 | /* | 2047 | /* |
2048 | * KG: We need to drain the buffers before we draw any conclusions! | 2048 | * KG: We need to drain the buffers before we draw any conclusions! |
@@ -2172,7 +2172,7 @@ static void data_out_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, | |||
2172 | u16 *pscsi_status) | 2172 | u16 *pscsi_status) |
2173 | { | 2173 | { |
2174 | dprintkdbg(DBG_0, "data_out_phase1: (pid#%li) <%02i-%i>\n", | 2174 | dprintkdbg(DBG_0, "data_out_phase1: (pid#%li) <%02i-%i>\n", |
2175 | srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); | 2175 | srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun); |
2176 | clear_fifo(acb, "data_out_phase1"); | 2176 | clear_fifo(acb, "data_out_phase1"); |
2177 | /* do prepare before transfer when data out phase */ | 2177 | /* do prepare before transfer when data out phase */ |
2178 | data_io_transfer(acb, srb, XFERDATAOUT); | 2178 | data_io_transfer(acb, srb, XFERDATAOUT); |
@@ -2184,7 +2184,7 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, | |||
2184 | u16 scsi_status = *pscsi_status; | 2184 | u16 scsi_status = *pscsi_status; |
2185 | 2185 | ||
2186 | dprintkdbg(DBG_0, "data_in_phase0: (pid#%li) <%02i-%i>\n", | 2186 | dprintkdbg(DBG_0, "data_in_phase0: (pid#%li) <%02i-%i>\n", |
2187 | srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); | 2187 | srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun); |
2188 | 2188 | ||
2189 | /* | 2189 | /* |
2190 | * KG: DataIn is much more tricky than DataOut. When the device is finished | 2190 | * KG: DataIn is much more tricky than DataOut. When the device is finished |
@@ -2205,7 +2205,7 @@ static void data_in_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, | |||
2205 | 2205 | ||
2206 | if (scsi_status & PARITYERROR) { | 2206 | if (scsi_status & PARITYERROR) { |
2207 | dprintkl(KERN_INFO, "data_in_phase0: (pid#%li) " | 2207 | dprintkl(KERN_INFO, "data_in_phase0: (pid#%li) " |
2208 | "Parity Error\n", srb->cmd->pid); | 2208 | "Parity Error\n", srb->cmd->serial_number); |
2209 | srb->status |= PARITY_ERROR; | 2209 | srb->status |= PARITY_ERROR; |
2210 | } | 2210 | } |
2211 | /* | 2211 | /* |
@@ -2395,7 +2395,7 @@ static void data_in_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, | |||
2395 | u16 *pscsi_status) | 2395 | u16 *pscsi_status) |
2396 | { | 2396 | { |
2397 | dprintkdbg(DBG_0, "data_in_phase1: (pid#%li) <%02i-%i>\n", | 2397 | dprintkdbg(DBG_0, "data_in_phase1: (pid#%li) <%02i-%i>\n", |
2398 | srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); | 2398 | srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun); |
2399 | data_io_transfer(acb, srb, XFERDATAIN); | 2399 | data_io_transfer(acb, srb, XFERDATAIN); |
2400 | } | 2400 | } |
2401 | 2401 | ||
@@ -2407,7 +2407,7 @@ static void data_io_transfer(struct AdapterCtlBlk *acb, | |||
2407 | u8 bval; | 2407 | u8 bval; |
2408 | dprintkdbg(DBG_0, | 2408 | dprintkdbg(DBG_0, |
2409 | "data_io_transfer: (pid#%li) <%02i-%i> %c len=%i, sg=(%i/%i)\n", | 2409 | "data_io_transfer: (pid#%li) <%02i-%i> %c len=%i, sg=(%i/%i)\n", |
2410 | srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun, | 2410 | srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun, |
2411 | ((io_dir & DMACMD_DIR) ? 'r' : 'w'), | 2411 | ((io_dir & DMACMD_DIR) ? 'r' : 'w'), |
2412 | srb->total_xfer_length, srb->sg_index, srb->sg_count); | 2412 | srb->total_xfer_length, srb->sg_index, srb->sg_count); |
2413 | if (srb == acb->tmp_srb) | 2413 | if (srb == acb->tmp_srb) |
@@ -2580,7 +2580,7 @@ static void status_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, | |||
2580 | u16 *pscsi_status) | 2580 | u16 *pscsi_status) |
2581 | { | 2581 | { |
2582 | dprintkdbg(DBG_0, "status_phase0: (pid#%li) <%02i-%i>\n", | 2582 | dprintkdbg(DBG_0, "status_phase0: (pid#%li) <%02i-%i>\n", |
2583 | srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); | 2583 | srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun); |
2584 | srb->target_status = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); | 2584 | srb->target_status = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); |
2585 | srb->end_message = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); /* get message */ | 2585 | srb->end_message = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); /* get message */ |
2586 | srb->state = SRB_COMPLETED; | 2586 | srb->state = SRB_COMPLETED; |
@@ -2594,7 +2594,7 @@ static void status_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, | |||
2594 | u16 *pscsi_status) | 2594 | u16 *pscsi_status) |
2595 | { | 2595 | { |
2596 | dprintkdbg(DBG_0, "status_phase1: (pid#%li) <%02i-%i>\n", | 2596 | dprintkdbg(DBG_0, "status_phase1: (pid#%li) <%02i-%i>\n", |
2597 | srb->cmd->pid, srb->cmd->device->id, srb->cmd->device->lun); | 2597 | srb->cmd->serial_number, srb->cmd->device->id, srb->cmd->device->lun); |
2598 | srb->state = SRB_STATUS; | 2598 | srb->state = SRB_STATUS; |
2599 | DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ | 2599 | DC395x_write16(acb, TRM_S1040_SCSI_CONTROL, DO_DATALATCH); /* it's important for atn stop */ |
2600 | DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_COMP); | 2600 | DC395x_write8(acb, TRM_S1040_SCSI_COMMAND, SCMD_COMP); |
@@ -2636,7 +2636,7 @@ static struct ScsiReqBlk *msgin_qtag(struct AdapterCtlBlk *acb, | |||
2636 | struct ScsiReqBlk *srb = NULL; | 2636 | struct ScsiReqBlk *srb = NULL; |
2637 | struct ScsiReqBlk *i; | 2637 | struct ScsiReqBlk *i; |
2638 | dprintkdbg(DBG_0, "msgin_qtag: (pid#%li) tag=%i srb=%p\n", | 2638 | dprintkdbg(DBG_0, "msgin_qtag: (pid#%li) tag=%i srb=%p\n", |
2639 | srb->cmd->pid, tag, srb); | 2639 | srb->cmd->serial_number, tag, srb); |
2640 | 2640 | ||
2641 | if (!(dcb->tag_mask & (1 << tag))) | 2641 | if (!(dcb->tag_mask & (1 << tag))) |
2642 | dprintkl(KERN_DEBUG, | 2642 | dprintkl(KERN_DEBUG, |
@@ -2655,7 +2655,7 @@ static struct ScsiReqBlk *msgin_qtag(struct AdapterCtlBlk *acb, | |||
2655 | goto mingx0; | 2655 | goto mingx0; |
2656 | 2656 | ||
2657 | dprintkdbg(DBG_0, "msgin_qtag: (pid#%li) <%02i-%i>\n", | 2657 | dprintkdbg(DBG_0, "msgin_qtag: (pid#%li) <%02i-%i>\n", |
2658 | srb->cmd->pid, srb->dcb->target_id, srb->dcb->target_lun); | 2658 | srb->cmd->serial_number, srb->dcb->target_id, srb->dcb->target_lun); |
2659 | if (dcb->flag & ABORT_DEV_) { | 2659 | if (dcb->flag & ABORT_DEV_) { |
2660 | /*srb->state = SRB_ABORT_SENT; */ | 2660 | /*srb->state = SRB_ABORT_SENT; */ |
2661 | enable_msgout_abort(acb, srb); | 2661 | enable_msgout_abort(acb, srb); |
@@ -2865,7 +2865,7 @@ static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, | |||
2865 | u16 *pscsi_status) | 2865 | u16 *pscsi_status) |
2866 | { | 2866 | { |
2867 | struct DeviceCtlBlk *dcb = acb->active_dcb; | 2867 | struct DeviceCtlBlk *dcb = acb->active_dcb; |
2868 | dprintkdbg(DBG_0, "msgin_phase0: (pid#%li)\n", srb->cmd->pid); | 2868 | dprintkdbg(DBG_0, "msgin_phase0: (pid#%li)\n", srb->cmd->serial_number); |
2869 | 2869 | ||
2870 | srb->msgin_buf[acb->msg_len++] = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); | 2870 | srb->msgin_buf[acb->msg_len++] = DC395x_read8(acb, TRM_S1040_SCSI_FIFO); |
2871 | if (msgin_completed(srb->msgin_buf, acb->msg_len)) { | 2871 | if (msgin_completed(srb->msgin_buf, acb->msg_len)) { |
@@ -2933,7 +2933,7 @@ static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, | |||
2933 | */ | 2933 | */ |
2934 | dprintkdbg(DBG_0, "msgin_phase0: (pid#%li) " | 2934 | dprintkdbg(DBG_0, "msgin_phase0: (pid#%li) " |
2935 | "SAVE POINTER rem=%i Ignore\n", | 2935 | "SAVE POINTER rem=%i Ignore\n", |
2936 | srb->cmd->pid, srb->total_xfer_length); | 2936 | srb->cmd->serial_number, srb->total_xfer_length); |
2937 | break; | 2937 | break; |
2938 | 2938 | ||
2939 | case RESTORE_POINTERS: | 2939 | case RESTORE_POINTERS: |
@@ -2943,7 +2943,7 @@ static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, | |||
2943 | case ABORT: | 2943 | case ABORT: |
2944 | dprintkdbg(DBG_0, "msgin_phase0: (pid#%li) " | 2944 | dprintkdbg(DBG_0, "msgin_phase0: (pid#%li) " |
2945 | "<%02i-%i> ABORT msg\n", | 2945 | "<%02i-%i> ABORT msg\n", |
2946 | srb->cmd->pid, dcb->target_id, | 2946 | srb->cmd->serial_number, dcb->target_id, |
2947 | dcb->target_lun); | 2947 | dcb->target_lun); |
2948 | dcb->flag |= ABORT_DEV_; | 2948 | dcb->flag |= ABORT_DEV_; |
2949 | enable_msgout_abort(acb, srb); | 2949 | enable_msgout_abort(acb, srb); |
@@ -2975,7 +2975,7 @@ static void msgin_phase0(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, | |||
2975 | static void msgin_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, | 2975 | static void msgin_phase1(struct AdapterCtlBlk *acb, struct ScsiReqBlk *srb, |
2976 | u16 *pscsi_status) | 2976 | u16 *pscsi_status) |
2977 | { | 2977 | { |
2978 | dprintkdbg(DBG_0, "msgin_phase1: (pid#%li)\n", srb->cmd->pid); | 2978 | dprintkdbg(DBG_0, "msgin_phase1: (pid#%li)\n", srb->cmd->serial_number); |
2979 | clear_fifo(acb, "msgin_phase1"); | 2979 | clear_fifo(acb, "msgin_phase1"); |
2980 | DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, 1); | 2980 | DC395x_write32(acb, TRM_S1040_SCSI_COUNTER, 1); |
2981 | if (!(srb->state & SRB_MSGIN)) { | 2981 | if (!(srb->state & SRB_MSGIN)) { |
@@ -3041,7 +3041,7 @@ static void disconnect(struct AdapterCtlBlk *acb) | |||
3041 | } | 3041 | } |
3042 | srb = dcb->active_srb; | 3042 | srb = dcb->active_srb; |
3043 | acb->active_dcb = NULL; | 3043 | acb->active_dcb = NULL; |
3044 | dprintkdbg(DBG_0, "disconnect: (pid#%li)\n", srb->cmd->pid); | 3044 | dprintkdbg(DBG_0, "disconnect: (pid#%li)\n", srb->cmd->serial_number); |
3045 | 3045 | ||
3046 | srb->scsi_phase = PH_BUS_FREE; /* initial phase */ | 3046 | srb->scsi_phase = PH_BUS_FREE; /* initial phase */ |
3047 | clear_fifo(acb, "disconnect"); | 3047 | clear_fifo(acb, "disconnect"); |
@@ -3072,13 +3072,13 @@ static void disconnect(struct AdapterCtlBlk *acb) | |||
3072 | srb->state = SRB_READY; | 3072 | srb->state = SRB_READY; |
3073 | dprintkl(KERN_DEBUG, | 3073 | dprintkl(KERN_DEBUG, |
3074 | "disconnect: (pid#%li) Unexpected\n", | 3074 | "disconnect: (pid#%li) Unexpected\n", |
3075 | srb->cmd->pid); | 3075 | srb->cmd->serial_number); |
3076 | srb->target_status = SCSI_STAT_SEL_TIMEOUT; | 3076 | srb->target_status = SCSI_STAT_SEL_TIMEOUT; |
3077 | goto disc1; | 3077 | goto disc1; |
3078 | } else { | 3078 | } else { |
3079 | /* Normal selection timeout */ | 3079 | /* Normal selection timeout */ |
3080 | dprintkdbg(DBG_KG, "disconnect: (pid#%li) " | 3080 | dprintkdbg(DBG_KG, "disconnect: (pid#%li) " |
3081 | "<%02i-%i> SelTO\n", srb->cmd->pid, | 3081 | "<%02i-%i> SelTO\n", srb->cmd->serial_number, |
3082 | dcb->target_id, dcb->target_lun); | 3082 | dcb->target_id, dcb->target_lun); |
3083 | if (srb->retry_count++ > DC395x_MAX_RETRIES | 3083 | if (srb->retry_count++ > DC395x_MAX_RETRIES |
3084 | || acb->scan_devices) { | 3084 | || acb->scan_devices) { |
@@ -3090,7 +3090,7 @@ static void disconnect(struct AdapterCtlBlk *acb) | |||
3090 | srb_going_to_waiting_move(dcb, srb); | 3090 | srb_going_to_waiting_move(dcb, srb); |
3091 | dprintkdbg(DBG_KG, | 3091 | dprintkdbg(DBG_KG, |
3092 | "disconnect: (pid#%li) Retry\n", | 3092 | "disconnect: (pid#%li) Retry\n", |
3093 | srb->cmd->pid); | 3093 | srb->cmd->serial_number); |
3094 | waiting_set_timer(acb, HZ / 20); | 3094 | waiting_set_timer(acb, HZ / 20); |
3095 | } | 3095 | } |
3096 | } else if (srb->state & SRB_DISCONNECT) { | 3096 | } else if (srb->state & SRB_DISCONNECT) { |
@@ -3144,7 +3144,7 @@ static void reselect(struct AdapterCtlBlk *acb) | |||
3144 | if (!acb->scan_devices) { | 3144 | if (!acb->scan_devices) { |
3145 | dprintkdbg(DBG_KG, "reselect: (pid#%li) <%02i-%i> " | 3145 | dprintkdbg(DBG_KG, "reselect: (pid#%li) <%02i-%i> " |
3146 | "Arb lost but Resel win rsel=%i stat=0x%04x\n", | 3146 | "Arb lost but Resel win rsel=%i stat=0x%04x\n", |
3147 | srb->cmd->pid, dcb->target_id, | 3147 | srb->cmd->serial_number, dcb->target_id, |
3148 | dcb->target_lun, rsel_tar_lun_id, | 3148 | dcb->target_lun, rsel_tar_lun_id, |
3149 | DC395x_read16(acb, TRM_S1040_SCSI_STATUS)); | 3149 | DC395x_read16(acb, TRM_S1040_SCSI_STATUS)); |
3150 | arblostflag = 1; | 3150 | arblostflag = 1; |
@@ -3318,7 +3318,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, | |||
3318 | enum dma_data_direction dir = cmd->sc_data_direction; | 3318 | enum dma_data_direction dir = cmd->sc_data_direction; |
3319 | int ckc_only = 1; | 3319 | int ckc_only = 1; |
3320 | 3320 | ||
3321 | dprintkdbg(DBG_1, "srb_done: (pid#%li) <%02i-%i>\n", srb->cmd->pid, | 3321 | dprintkdbg(DBG_1, "srb_done: (pid#%li) <%02i-%i>\n", srb->cmd->serial_number, |
3322 | srb->cmd->device->id, srb->cmd->device->lun); | 3322 | srb->cmd->device->id, srb->cmd->device->lun); |
3323 | dprintkdbg(DBG_SG, "srb_done: srb=%p sg=%i(%i/%i) buf=%p\n", | 3323 | dprintkdbg(DBG_SG, "srb_done: srb=%p sg=%i(%i/%i) buf=%p\n", |
3324 | srb, scsi_sg_count(cmd), srb->sg_index, srb->sg_count, | 3324 | srb, scsi_sg_count(cmd), srb->sg_index, srb->sg_count, |
@@ -3499,7 +3499,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, | |||
3499 | if (srb->total_xfer_length) | 3499 | if (srb->total_xfer_length) |
3500 | dprintkdbg(DBG_KG, "srb_done: (pid#%li) <%02i-%i> " | 3500 | dprintkdbg(DBG_KG, "srb_done: (pid#%li) <%02i-%i> " |
3501 | "cmnd=0x%02x Missed %i bytes\n", | 3501 | "cmnd=0x%02x Missed %i bytes\n", |
3502 | cmd->pid, cmd->device->id, cmd->device->lun, | 3502 | cmd->serial_number, cmd->device->id, cmd->device->lun, |
3503 | cmd->cmnd[0], srb->total_xfer_length); | 3503 | cmd->cmnd[0], srb->total_xfer_length); |
3504 | } | 3504 | } |
3505 | 3505 | ||
@@ -3509,7 +3509,7 @@ static void srb_done(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, | |||
3509 | dprintkl(KERN_ERR, "srb_done: ERROR! Completed cmd with tmp_srb\n"); | 3509 | dprintkl(KERN_ERR, "srb_done: ERROR! Completed cmd with tmp_srb\n"); |
3510 | else { | 3510 | else { |
3511 | dprintkdbg(DBG_0, "srb_done: (pid#%li) done result=0x%08x\n", | 3511 | dprintkdbg(DBG_0, "srb_done: (pid#%li) done result=0x%08x\n", |
3512 | cmd->pid, cmd->result); | 3512 | cmd->serial_number, cmd->result); |
3513 | srb_free_insert(acb, srb); | 3513 | srb_free_insert(acb, srb); |
3514 | } | 3514 | } |
3515 | pci_unmap_srb(acb, srb); | 3515 | pci_unmap_srb(acb, srb); |
@@ -3538,7 +3538,7 @@ static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag, | |||
3538 | p = srb->cmd; | 3538 | p = srb->cmd; |
3539 | dir = p->sc_data_direction; | 3539 | dir = p->sc_data_direction; |
3540 | result = MK_RES(0, did_flag, 0, 0); | 3540 | result = MK_RES(0, did_flag, 0, 0); |
3541 | printk("G:%li(%02i-%i) ", p->pid, | 3541 | printk("G:%li(%02i-%i) ", p->serial_number, |
3542 | p->device->id, p->device->lun); | 3542 | p->device->id, p->device->lun); |
3543 | srb_going_remove(dcb, srb); | 3543 | srb_going_remove(dcb, srb); |
3544 | free_tag(dcb, srb); | 3544 | free_tag(dcb, srb); |
@@ -3568,7 +3568,7 @@ static void doing_srb_done(struct AdapterCtlBlk *acb, u8 did_flag, | |||
3568 | p = srb->cmd; | 3568 | p = srb->cmd; |
3569 | 3569 | ||
3570 | result = MK_RES(0, did_flag, 0, 0); | 3570 | result = MK_RES(0, did_flag, 0, 0); |
3571 | printk("W:%li<%02i-%i>", p->pid, p->device->id, | 3571 | printk("W:%li<%02i-%i>", p->serial_number, p->device->id, |
3572 | p->device->lun); | 3572 | p->device->lun); |
3573 | srb_waiting_remove(dcb, srb); | 3573 | srb_waiting_remove(dcb, srb); |
3574 | srb_free_insert(acb, srb); | 3574 | srb_free_insert(acb, srb); |
@@ -3678,7 +3678,7 @@ static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, | |||
3678 | { | 3678 | { |
3679 | struct scsi_cmnd *cmd = srb->cmd; | 3679 | struct scsi_cmnd *cmd = srb->cmd; |
3680 | dprintkdbg(DBG_1, "request_sense: (pid#%li) <%02i-%i>\n", | 3680 | dprintkdbg(DBG_1, "request_sense: (pid#%li) <%02i-%i>\n", |
3681 | cmd->pid, cmd->device->id, cmd->device->lun); | 3681 | cmd->serial_number, cmd->device->id, cmd->device->lun); |
3682 | 3682 | ||
3683 | srb->flag |= AUTO_REQSENSE; | 3683 | srb->flag |= AUTO_REQSENSE; |
3684 | srb->adapter_status = 0; | 3684 | srb->adapter_status = 0; |
@@ -3709,7 +3709,7 @@ static void request_sense(struct AdapterCtlBlk *acb, struct DeviceCtlBlk *dcb, | |||
3709 | if (start_scsi(acb, dcb, srb)) { /* Should only happen, if sb. else grabs the bus */ | 3709 | if (start_scsi(acb, dcb, srb)) { /* Should only happen, if sb. else grabs the bus */ |
3710 | dprintkl(KERN_DEBUG, | 3710 | dprintkl(KERN_DEBUG, |
3711 | "request_sense: (pid#%li) failed <%02i-%i>\n", | 3711 | "request_sense: (pid#%li) failed <%02i-%i>\n", |
3712 | srb->cmd->pid, dcb->target_id, dcb->target_lun); | 3712 | srb->cmd->serial_number, dcb->target_id, dcb->target_lun); |
3713 | srb_going_to_waiting_move(dcb, srb); | 3713 | srb_going_to_waiting_move(dcb, srb); |
3714 | waiting_set_timer(acb, HZ / 100); | 3714 | waiting_set_timer(acb, HZ / 100); |
3715 | } | 3715 | } |
@@ -4717,13 +4717,13 @@ static int dc395x_proc_info(struct Scsi_Host *host, char *buffer, | |||
4717 | dcb->target_id, dcb->target_lun, | 4717 | dcb->target_id, dcb->target_lun, |
4718 | list_size(&dcb->srb_waiting_list)); | 4718 | list_size(&dcb->srb_waiting_list)); |
4719 | list_for_each_entry(srb, &dcb->srb_waiting_list, list) | 4719 | list_for_each_entry(srb, &dcb->srb_waiting_list, list) |
4720 | SPRINTF(" %li", srb->cmd->pid); | 4720 | SPRINTF(" %li", srb->cmd->serial_number); |
4721 | if (!list_empty(&dcb->srb_going_list)) | 4721 | if (!list_empty(&dcb->srb_going_list)) |
4722 | SPRINTF("\nDCB (%02i-%i): Going : %i:", | 4722 | SPRINTF("\nDCB (%02i-%i): Going : %i:", |
4723 | dcb->target_id, dcb->target_lun, | 4723 | dcb->target_id, dcb->target_lun, |
4724 | list_size(&dcb->srb_going_list)); | 4724 | list_size(&dcb->srb_going_list)); |
4725 | list_for_each_entry(srb, &dcb->srb_going_list, list) | 4725 | list_for_each_entry(srb, &dcb->srb_going_list, list) |
4726 | SPRINTF(" %li", srb->cmd->pid); | 4726 | SPRINTF(" %li", srb->cmd->serial_number); |
4727 | if (!list_empty(&dcb->srb_waiting_list) || !list_empty(&dcb->srb_going_list)) | 4727 | if (!list_empty(&dcb->srb_waiting_list) || !list_empty(&dcb->srb_going_list)) |
4728 | SPRINTF("\n"); | 4728 | SPRINTF("\n"); |
4729 | } | 4729 | } |
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c index 502732ac270d..bea9d659af15 100644 --- a/drivers/scsi/dpt_i2o.c +++ b/drivers/scsi/dpt_i2o.c | |||
@@ -949,16 +949,14 @@ static int adpt_install_hba(struct pci_dev* pDev) | |||
949 | } | 949 | } |
950 | 950 | ||
951 | // Allocate and zero the data structure | 951 | // Allocate and zero the data structure |
952 | pHba = kmalloc(sizeof(adpt_hba), GFP_KERNEL); | 952 | pHba = kzalloc(sizeof(adpt_hba), GFP_KERNEL); |
953 | if( pHba == NULL) { | 953 | if (!pHba) { |
954 | if(msg_addr_virt != base_addr_virt){ | 954 | if (msg_addr_virt != base_addr_virt) |
955 | iounmap(msg_addr_virt); | 955 | iounmap(msg_addr_virt); |
956 | } | ||
957 | iounmap(base_addr_virt); | 956 | iounmap(base_addr_virt); |
958 | pci_release_regions(pDev); | 957 | pci_release_regions(pDev); |
959 | return -ENOMEM; | 958 | return -ENOMEM; |
960 | } | 959 | } |
961 | memset(pHba, 0, sizeof(adpt_hba)); | ||
962 | 960 | ||
963 | mutex_lock(&adpt_configuration_lock); | 961 | mutex_lock(&adpt_configuration_lock); |
964 | 962 | ||
@@ -2622,14 +2620,13 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba) | |||
2622 | 2620 | ||
2623 | msg=(u32 __iomem *)(pHba->msg_addr_virt+m); | 2621 | msg=(u32 __iomem *)(pHba->msg_addr_virt+m); |
2624 | 2622 | ||
2625 | status = kmalloc(4,GFP_KERNEL|ADDR32); | 2623 | status = kzalloc(4, GFP_KERNEL|ADDR32); |
2626 | if (status==NULL) { | 2624 | if (!status) { |
2627 | adpt_send_nop(pHba, m); | 2625 | adpt_send_nop(pHba, m); |
2628 | printk(KERN_WARNING"%s: IOP reset failed - no free memory.\n", | 2626 | printk(KERN_WARNING"%s: IOP reset failed - no free memory.\n", |
2629 | pHba->name); | 2627 | pHba->name); |
2630 | return -ENOMEM; | 2628 | return -ENOMEM; |
2631 | } | 2629 | } |
2632 | memset(status, 0, 4); | ||
2633 | 2630 | ||
2634 | writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]); | 2631 | writel(EIGHT_WORD_MSG_SIZE| SGL_OFFSET_6, &msg[0]); |
2635 | writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]); | 2632 | writel(I2O_CMD_OUTBOUND_INIT<<24 | HOST_TID<<12 | ADAPTER_TID, &msg[1]); |
@@ -2668,12 +2665,11 @@ static s32 adpt_i2o_init_outbound_q(adpt_hba* pHba) | |||
2668 | 2665 | ||
2669 | kfree(pHba->reply_pool); | 2666 | kfree(pHba->reply_pool); |
2670 | 2667 | ||
2671 | pHba->reply_pool = kmalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32); | 2668 | pHba->reply_pool = kzalloc(pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4, GFP_KERNEL|ADDR32); |
2672 | if(!pHba->reply_pool){ | 2669 | if (!pHba->reply_pool) { |
2673 | printk(KERN_ERR"%s: Could not allocate reply pool\n",pHba->name); | 2670 | printk(KERN_ERR "%s: Could not allocate reply pool\n", pHba->name); |
2674 | return -1; | 2671 | return -ENOMEM; |
2675 | } | 2672 | } |
2676 | memset(pHba->reply_pool, 0 , pHba->reply_fifo_size * REPLY_FRAME_SIZE * 4); | ||
2677 | 2673 | ||
2678 | ptr = pHba->reply_pool; | 2674 | ptr = pHba->reply_pool; |
2679 | for(i = 0; i < pHba->reply_fifo_size; i++) { | 2675 | for(i = 0; i < pHba->reply_fifo_size; i++) { |
@@ -2884,12 +2880,11 @@ static int adpt_i2o_build_sys_table(void) | |||
2884 | 2880 | ||
2885 | kfree(sys_tbl); | 2881 | kfree(sys_tbl); |
2886 | 2882 | ||
2887 | sys_tbl = kmalloc(sys_tbl_len, GFP_KERNEL|ADDR32); | 2883 | sys_tbl = kzalloc(sys_tbl_len, GFP_KERNEL|ADDR32); |
2888 | if(!sys_tbl) { | 2884 | if (!sys_tbl) { |
2889 | printk(KERN_WARNING "SysTab Set failed. Out of memory.\n"); | 2885 | printk(KERN_WARNING "SysTab Set failed. Out of memory.\n"); |
2890 | return -ENOMEM; | 2886 | return -ENOMEM; |
2891 | } | 2887 | } |
2892 | memset(sys_tbl, 0, sys_tbl_len); | ||
2893 | 2888 | ||
2894 | sys_tbl->num_entries = hba_count; | 2889 | sys_tbl->num_entries = hba_count; |
2895 | sys_tbl->version = I2OVERSION; | 2890 | sys_tbl->version = I2OVERSION; |
@@ -3351,7 +3346,7 @@ static int __init adpt_init(void) | |||
3351 | return count > 0 ? 0 : -ENODEV; | 3346 | return count > 0 ? 0 : -ENODEV; |
3352 | } | 3347 | } |
3353 | 3348 | ||
3354 | static void __exit adpt_exit(void) | 3349 | static void adpt_exit(void) |
3355 | { | 3350 | { |
3356 | while (hba_chain) | 3351 | while (hba_chain) |
3357 | adpt_release(hba_chain); | 3352 | adpt_release(hba_chain); |
diff --git a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c index 9d52e45c7d36..2596165096d3 100644 --- a/drivers/scsi/dtc.c +++ b/drivers/scsi/dtc.c | |||
@@ -137,11 +137,9 @@ static struct override { | |||
137 | #ifdef OVERRIDE | 137 | #ifdef OVERRIDE |
138 | [] __initdata = OVERRIDE; | 138 | [] __initdata = OVERRIDE; |
139 | #else | 139 | #else |
140 | [4] __initdata = { { | 140 | [4] __initdata = { |
141 | 0, IRQ_AUTO}, { | 141 | { 0, IRQ_AUTO }, { 0, IRQ_AUTO }, { 0, IRQ_AUTO }, { 0, IRQ_AUTO } |
142 | 0, IRQ_AUTO}, { | 142 | }; |
143 | 0, IRQ_AUTO}, { | ||
144 | 0, IRQ_AUTO}}; | ||
145 | #endif | 143 | #endif |
146 | 144 | ||
147 | #define NO_OVERRIDES ARRAY_SIZE(overrides) | 145 | #define NO_OVERRIDES ARRAY_SIZE(overrides) |
@@ -176,7 +174,7 @@ static const struct signature { | |||
176 | * Inputs : str - unused, ints - array of integer parameters with ints[0] | 174 | * Inputs : str - unused, ints - array of integer parameters with ints[0] |
177 | * equal to the number of ints. | 175 | * equal to the number of ints. |
178 | * | 176 | * |
179 | */ | 177 | */ |
180 | 178 | ||
181 | static void __init dtc_setup(char *str, int *ints) | 179 | static void __init dtc_setup(char *str, int *ints) |
182 | { | 180 | { |
@@ -233,7 +231,7 @@ static int __init dtc_detect(struct scsi_host_template * tpnt) | |||
233 | } else | 231 | } else |
234 | for (; !addr && (current_base < NO_BASES); ++current_base) { | 232 | for (; !addr && (current_base < NO_BASES); ++current_base) { |
235 | #if (DTCDEBUG & DTCDEBUG_INIT) | 233 | #if (DTCDEBUG & DTCDEBUG_INIT) |
236 | printk("scsi-dtc : probing address %08x\n", bases[current_base].address); | 234 | printk(KERN_DEBUG "scsi-dtc : probing address %08x\n", bases[current_base].address); |
237 | #endif | 235 | #endif |
238 | if (bases[current_base].noauto) | 236 | if (bases[current_base].noauto) |
239 | continue; | 237 | continue; |
@@ -244,7 +242,7 @@ static int __init dtc_detect(struct scsi_host_template * tpnt) | |||
244 | if (check_signature(base + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) { | 242 | if (check_signature(base + signatures[sig].offset, signatures[sig].string, strlen(signatures[sig].string))) { |
245 | addr = bases[current_base].address; | 243 | addr = bases[current_base].address; |
246 | #if (DTCDEBUG & DTCDEBUG_INIT) | 244 | #if (DTCDEBUG & DTCDEBUG_INIT) |
247 | printk("scsi-dtc : detected board.\n"); | 245 | printk(KERN_DEBUG "scsi-dtc : detected board.\n"); |
248 | #endif | 246 | #endif |
249 | goto found; | 247 | goto found; |
250 | } | 248 | } |
@@ -253,7 +251,7 @@ static int __init dtc_detect(struct scsi_host_template * tpnt) | |||
253 | } | 251 | } |
254 | 252 | ||
255 | #if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT) | 253 | #if defined(DTCDEBUG) && (DTCDEBUG & DTCDEBUG_INIT) |
256 | printk("scsi-dtc : base = %08x\n", addr); | 254 | printk(KERN_DEBUG "scsi-dtc : base = %08x\n", addr); |
257 | #endif | 255 | #endif |
258 | 256 | ||
259 | if (!addr) | 257 | if (!addr) |
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c index a83e9f150b97..ec2233114bc9 100644 --- a/drivers/scsi/eata.c +++ b/drivers/scsi/eata.c | |||
@@ -1758,7 +1758,7 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, | |||
1758 | 1758 | ||
1759 | if (SCpnt->host_scribble) | 1759 | if (SCpnt->host_scribble) |
1760 | panic("%s: qcomm, pid %ld, SCpnt %p already active.\n", | 1760 | panic("%s: qcomm, pid %ld, SCpnt %p already active.\n", |
1761 | ha->board_name, SCpnt->pid, SCpnt); | 1761 | ha->board_name, SCpnt->serial_number, SCpnt); |
1762 | 1762 | ||
1763 | /* i is the mailbox number, look for the first free mailbox | 1763 | /* i is the mailbox number, look for the first free mailbox |
1764 | starting from last_cp_used */ | 1764 | starting from last_cp_used */ |
@@ -1792,7 +1792,7 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, | |||
1792 | 1792 | ||
1793 | if (do_trace) | 1793 | if (do_trace) |
1794 | scmd_printk(KERN_INFO, SCpnt, | 1794 | scmd_printk(KERN_INFO, SCpnt, |
1795 | "qcomm, mbox %d, pid %ld.\n", i, SCpnt->pid); | 1795 | "qcomm, mbox %d, pid %ld.\n", i, SCpnt->serial_number); |
1796 | 1796 | ||
1797 | cpp->reqsen = 1; | 1797 | cpp->reqsen = 1; |
1798 | cpp->dispri = 1; | 1798 | cpp->dispri = 1; |
@@ -1825,7 +1825,7 @@ static int eata2x_queuecommand(struct scsi_cmnd *SCpnt, | |||
1825 | unmap_dma(i, ha); | 1825 | unmap_dma(i, ha); |
1826 | SCpnt->host_scribble = NULL; | 1826 | SCpnt->host_scribble = NULL; |
1827 | scmd_printk(KERN_INFO, SCpnt, | 1827 | scmd_printk(KERN_INFO, SCpnt, |
1828 | "qcomm, pid %ld, adapter busy.\n", SCpnt->pid); | 1828 | "qcomm, pid %ld, adapter busy.\n", SCpnt->serial_number); |
1829 | return 1; | 1829 | return 1; |
1830 | } | 1830 | } |
1831 | 1831 | ||
@@ -1841,13 +1841,13 @@ static int eata2x_eh_abort(struct scsi_cmnd *SCarg) | |||
1841 | 1841 | ||
1842 | if (SCarg->host_scribble == NULL) { | 1842 | if (SCarg->host_scribble == NULL) { |
1843 | scmd_printk(KERN_INFO, SCarg, | 1843 | scmd_printk(KERN_INFO, SCarg, |
1844 | "abort, pid %ld inactive.\n", SCarg->pid); | 1844 | "abort, pid %ld inactive.\n", SCarg->serial_number); |
1845 | return SUCCESS; | 1845 | return SUCCESS; |
1846 | } | 1846 | } |
1847 | 1847 | ||
1848 | i = *(unsigned int *)SCarg->host_scribble; | 1848 | i = *(unsigned int *)SCarg->host_scribble; |
1849 | scmd_printk(KERN_WARNING, SCarg, | 1849 | scmd_printk(KERN_WARNING, SCarg, |
1850 | "abort, mbox %d, pid %ld.\n", i, SCarg->pid); | 1850 | "abort, mbox %d, pid %ld.\n", i, SCarg->serial_number); |
1851 | 1851 | ||
1852 | if (i >= shost->can_queue) | 1852 | if (i >= shost->can_queue) |
1853 | panic("%s: abort, invalid SCarg->host_scribble.\n", ha->board_name); | 1853 | panic("%s: abort, invalid SCarg->host_scribble.\n", ha->board_name); |
@@ -1892,7 +1892,7 @@ static int eata2x_eh_abort(struct scsi_cmnd *SCarg) | |||
1892 | SCarg->host_scribble = NULL; | 1892 | SCarg->host_scribble = NULL; |
1893 | ha->cp_stat[i] = FREE; | 1893 | ha->cp_stat[i] = FREE; |
1894 | printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n", | 1894 | printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n", |
1895 | ha->board_name, i, SCarg->pid); | 1895 | ha->board_name, i, SCarg->serial_number); |
1896 | SCarg->scsi_done(SCarg); | 1896 | SCarg->scsi_done(SCarg); |
1897 | return SUCCESS; | 1897 | return SUCCESS; |
1898 | } | 1898 | } |
@@ -1909,12 +1909,12 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) | |||
1909 | struct hostdata *ha = (struct hostdata *)shost->hostdata; | 1909 | struct hostdata *ha = (struct hostdata *)shost->hostdata; |
1910 | 1910 | ||
1911 | scmd_printk(KERN_INFO, SCarg, | 1911 | scmd_printk(KERN_INFO, SCarg, |
1912 | "reset, enter, pid %ld.\n", SCarg->pid); | 1912 | "reset, enter, pid %ld.\n", SCarg->serial_number); |
1913 | 1913 | ||
1914 | spin_lock_irq(shost->host_lock); | 1914 | spin_lock_irq(shost->host_lock); |
1915 | 1915 | ||
1916 | if (SCarg->host_scribble == NULL) | 1916 | if (SCarg->host_scribble == NULL) |
1917 | printk("%s: reset, pid %ld inactive.\n", ha->board_name, SCarg->pid); | 1917 | printk("%s: reset, pid %ld inactive.\n", ha->board_name, SCarg->serial_number); |
1918 | 1918 | ||
1919 | if (ha->in_reset) { | 1919 | if (ha->in_reset) { |
1920 | printk("%s: reset, exit, already in reset.\n", ha->board_name); | 1920 | printk("%s: reset, exit, already in reset.\n", ha->board_name); |
@@ -1954,13 +1954,13 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) | |||
1954 | if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) { | 1954 | if (ha->cp_stat[i] == READY || ha->cp_stat[i] == ABORTING) { |
1955 | ha->cp_stat[i] = ABORTING; | 1955 | ha->cp_stat[i] = ABORTING; |
1956 | printk("%s: reset, mbox %d aborting, pid %ld.\n", | 1956 | printk("%s: reset, mbox %d aborting, pid %ld.\n", |
1957 | ha->board_name, i, SCpnt->pid); | 1957 | ha->board_name, i, SCpnt->serial_number); |
1958 | } | 1958 | } |
1959 | 1959 | ||
1960 | else { | 1960 | else { |
1961 | ha->cp_stat[i] = IN_RESET; | 1961 | ha->cp_stat[i] = IN_RESET; |
1962 | printk("%s: reset, mbox %d in reset, pid %ld.\n", | 1962 | printk("%s: reset, mbox %d in reset, pid %ld.\n", |
1963 | ha->board_name, i, SCpnt->pid); | 1963 | ha->board_name, i, SCpnt->serial_number); |
1964 | } | 1964 | } |
1965 | 1965 | ||
1966 | if (SCpnt->host_scribble == NULL) | 1966 | if (SCpnt->host_scribble == NULL) |
@@ -2015,7 +2015,7 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) | |||
2015 | 2015 | ||
2016 | printk | 2016 | printk |
2017 | ("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n", | 2017 | ("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n", |
2018 | ha->board_name, i, SCpnt->pid); | 2018 | ha->board_name, i, SCpnt->serial_number); |
2019 | } | 2019 | } |
2020 | 2020 | ||
2021 | else if (ha->cp_stat[i] == ABORTING) { | 2021 | else if (ha->cp_stat[i] == ABORTING) { |
@@ -2029,7 +2029,7 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) | |||
2029 | 2029 | ||
2030 | printk | 2030 | printk |
2031 | ("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n", | 2031 | ("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n", |
2032 | ha->board_name, i, SCpnt->pid); | 2032 | ha->board_name, i, SCpnt->serial_number); |
2033 | } | 2033 | } |
2034 | 2034 | ||
2035 | else | 2035 | else |
@@ -2043,7 +2043,7 @@ static int eata2x_eh_host_reset(struct scsi_cmnd *SCarg) | |||
2043 | do_trace = 0; | 2043 | do_trace = 0; |
2044 | 2044 | ||
2045 | if (arg_done) | 2045 | if (arg_done) |
2046 | printk("%s: reset, exit, pid %ld done.\n", ha->board_name, SCarg->pid); | 2046 | printk("%s: reset, exit, pid %ld done.\n", ha->board_name, SCarg->serial_number); |
2047 | else | 2047 | else |
2048 | printk("%s: reset, exit.\n", ha->board_name); | 2048 | printk("%s: reset, exit.\n", ha->board_name); |
2049 | 2049 | ||
@@ -2182,7 +2182,7 @@ static int reorder(struct hostdata *ha, unsigned long cursec, | |||
2182 | cpp = &ha->cp[k]; | 2182 | cpp = &ha->cp[k]; |
2183 | SCpnt = cpp->SCpnt; | 2183 | SCpnt = cpp->SCpnt; |
2184 | ll[n] = SCpnt->request->nr_sectors; | 2184 | ll[n] = SCpnt->request->nr_sectors; |
2185 | pl[n] = SCpnt->pid; | 2185 | pl[n] = SCpnt->serial_number; |
2186 | 2186 | ||
2187 | if (!n) | 2187 | if (!n) |
2188 | continue; | 2188 | continue; |
@@ -2230,7 +2230,7 @@ static int reorder(struct hostdata *ha, unsigned long cursec, | |||
2230 | "%s pid %ld mb %d fc %d nr %d sec %ld ns %ld" | 2230 | "%s pid %ld mb %d fc %d nr %d sec %ld ns %ld" |
2231 | " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n", | 2231 | " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n", |
2232 | (ihdlr ? "ihdlr" : "qcomm"), | 2232 | (ihdlr ? "ihdlr" : "qcomm"), |
2233 | SCpnt->pid, k, flushcount, | 2233 | SCpnt->serial_number, k, flushcount, |
2234 | n_ready, SCpnt->request->sector, | 2234 | n_ready, SCpnt->request->sector, |
2235 | SCpnt->request->nr_sectors, cursec, YESNO(s), | 2235 | SCpnt->request->nr_sectors, cursec, YESNO(s), |
2236 | YESNO(r), YESNO(rev), YESNO(input_only), | 2236 | YESNO(r), YESNO(rev), YESNO(input_only), |
@@ -2277,7 +2277,7 @@ static void flush_dev(struct scsi_device *dev, unsigned long cursec, | |||
2277 | "%s, pid %ld, mbox %d, adapter" | 2277 | "%s, pid %ld, mbox %d, adapter" |
2278 | " busy, will abort.\n", | 2278 | " busy, will abort.\n", |
2279 | (ihdlr ? "ihdlr" : "qcomm"), | 2279 | (ihdlr ? "ihdlr" : "qcomm"), |
2280 | SCpnt->pid, k); | 2280 | SCpnt->serial_number, k); |
2281 | ha->cp_stat[k] = ABORTING; | 2281 | ha->cp_stat[k] = ABORTING; |
2282 | continue; | 2282 | continue; |
2283 | } | 2283 | } |
@@ -2391,11 +2391,11 @@ static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost) | |||
2391 | 2391 | ||
2392 | if (SCpnt->host_scribble == NULL) | 2392 | if (SCpnt->host_scribble == NULL) |
2393 | panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", ha->board_name, | 2393 | panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", ha->board_name, |
2394 | i, SCpnt->pid, SCpnt); | 2394 | i, SCpnt->serial_number, SCpnt); |
2395 | 2395 | ||
2396 | if (*(unsigned int *)SCpnt->host_scribble != i) | 2396 | if (*(unsigned int *)SCpnt->host_scribble != i) |
2397 | panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n", | 2397 | panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n", |
2398 | ha->board_name, i, SCpnt->pid, | 2398 | ha->board_name, i, SCpnt->serial_number, |
2399 | *(unsigned int *)SCpnt->host_scribble); | 2399 | *(unsigned int *)SCpnt->host_scribble); |
2400 | 2400 | ||
2401 | sync_dma(i, ha); | 2401 | sync_dma(i, ha); |
@@ -2445,12 +2445,12 @@ static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost) | |||
2445 | "target_status 0x%x, sense key 0x%x.\n", | 2445 | "target_status 0x%x, sense key 0x%x.\n", |
2446 | ha->board_name, | 2446 | ha->board_name, |
2447 | SCpnt->device->channel, SCpnt->device->id, | 2447 | SCpnt->device->channel, SCpnt->device->id, |
2448 | SCpnt->device->lun, SCpnt->pid, | 2448 | SCpnt->device->lun, SCpnt->serial_number, |
2449 | spp->target_status, SCpnt->sense_buffer[2]); | 2449 | spp->target_status, SCpnt->sense_buffer[2]); |
2450 | 2450 | ||
2451 | ha->target_to[SCpnt->device->id][SCpnt->device->channel] = 0; | 2451 | ha->target_to[SCpnt->device->id][SCpnt->device->channel] = 0; |
2452 | 2452 | ||
2453 | if (ha->last_retried_pid == SCpnt->pid) | 2453 | if (ha->last_retried_pid == SCpnt->serial_number) |
2454 | ha->retries = 0; | 2454 | ha->retries = 0; |
2455 | 2455 | ||
2456 | break; | 2456 | break; |
@@ -2485,7 +2485,7 @@ static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost) | |||
2485 | #endif | 2485 | #endif |
2486 | 2486 | ||
2487 | ha->retries++; | 2487 | ha->retries++; |
2488 | ha->last_retried_pid = SCpnt->pid; | 2488 | ha->last_retried_pid = SCpnt->serial_number; |
2489 | } else | 2489 | } else |
2490 | status = DID_ERROR << 16; | 2490 | status = DID_ERROR << 16; |
2491 | 2491 | ||
@@ -2516,7 +2516,7 @@ static irqreturn_t ihdlr(int irq, struct Scsi_Host *shost) | |||
2516 | scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x," | 2516 | scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x," |
2517 | " pid %ld, reg 0x%x, count %d.\n", | 2517 | " pid %ld, reg 0x%x, count %d.\n", |
2518 | i, spp->adapter_status, spp->target_status, | 2518 | i, spp->adapter_status, spp->target_status, |
2519 | SCpnt->pid, reg, ha->iocount); | 2519 | SCpnt->serial_number, reg, ha->iocount); |
2520 | 2520 | ||
2521 | unmap_dma(i, ha); | 2521 | unmap_dma(i, ha); |
2522 | 2522 | ||
diff --git a/drivers/scsi/eata_pio.c b/drivers/scsi/eata_pio.c index f33ad01064a9..96180bb47e41 100644 --- a/drivers/scsi/eata_pio.c +++ b/drivers/scsi/eata_pio.c | |||
@@ -107,59 +107,44 @@ static struct scsi_host_template driver_template; | |||
107 | static int eata_pio_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset, | 107 | static int eata_pio_proc_info(struct Scsi_Host *shost, char *buffer, char **start, off_t offset, |
108 | int length, int rw) | 108 | int length, int rw) |
109 | { | 109 | { |
110 | static u8 buff[512]; | 110 | int len = 0; |
111 | int size, len = 0; | 111 | off_t begin = 0, pos = 0; |
112 | off_t begin = 0, pos = 0; | ||
113 | 112 | ||
114 | if (rw) | 113 | if (rw) |
115 | return -ENOSYS; | 114 | return -ENOSYS; |
116 | if (offset == 0) | ||
117 | memset(buff, 0, sizeof(buff)); | ||
118 | 115 | ||
119 | size = sprintf(buffer+len, "EATA (Extended Attachment) PIO driver version: " | 116 | len += sprintf(buffer+len, "EATA (Extended Attachment) PIO driver version: " |
120 | "%d.%d%s\n",VER_MAJOR, VER_MINOR, VER_SUB); | 117 | "%d.%d%s\n",VER_MAJOR, VER_MINOR, VER_SUB); |
121 | len += size; pos = begin + len; | 118 | len += sprintf(buffer + len, "queued commands: %10ld\n" |
122 | size = sprintf(buffer + len, "queued commands: %10ld\n" | ||
123 | "processed interrupts:%10ld\n", queue_counter, int_counter); | 119 | "processed interrupts:%10ld\n", queue_counter, int_counter); |
124 | len += size; pos = begin + len; | 120 | len += sprintf(buffer + len, "\nscsi%-2d: HBA %.10s\n", |
125 | |||
126 | size = sprintf(buffer + len, "\nscsi%-2d: HBA %.10s\n", | ||
127 | shost->host_no, SD(shost)->name); | 121 | shost->host_no, SD(shost)->name); |
128 | len += size; | 122 | len += sprintf(buffer + len, "Firmware revision: v%s\n", |
129 | pos = begin + len; | ||
130 | size = sprintf(buffer + len, "Firmware revision: v%s\n", | ||
131 | SD(shost)->revision); | 123 | SD(shost)->revision); |
132 | len += size; | 124 | len += sprintf(buffer + len, "IO: PIO\n"); |
133 | pos = begin + len; | 125 | len += sprintf(buffer + len, "Base IO : %#.4x\n", (u32) shost->base); |
134 | size = sprintf(buffer + len, "IO: PIO\n"); | 126 | len += sprintf(buffer + len, "Host Bus: %s\n", |
135 | len += size; | ||
136 | pos = begin + len; | ||
137 | size = sprintf(buffer + len, "Base IO : %#.4x\n", (u32) shost->base); | ||
138 | len += size; | ||
139 | pos = begin + len; | ||
140 | size = sprintf(buffer + len, "Host Bus: %s\n", | ||
141 | (SD(shost)->bustype == 'P')?"PCI ": | 127 | (SD(shost)->bustype == 'P')?"PCI ": |
142 | (SD(shost)->bustype == 'E')?"EISA":"ISA "); | 128 | (SD(shost)->bustype == 'E')?"EISA":"ISA "); |
143 | 129 | ||
144 | len += size; | 130 | pos = begin + len; |
145 | pos = begin + len; | ||
146 | 131 | ||
147 | if (pos < offset) { | 132 | if (pos < offset) { |
148 | len = 0; | 133 | len = 0; |
149 | begin = pos; | 134 | begin = pos; |
150 | } | 135 | } |
151 | if (pos > offset + length) | 136 | if (pos > offset + length) |
152 | goto stop_output; | 137 | goto stop_output; |
153 | 138 | ||
154 | stop_output: | 139 | stop_output: |
155 | DBG(DBG_PROC, printk("2pos: %ld offset: %ld len: %d\n", pos, offset, len)); | 140 | DBG(DBG_PROC, printk("2pos: %ld offset: %ld len: %d\n", pos, offset, len)); |
156 | *start=buffer+(offset-begin); /* Start of wanted data */ | 141 | *start = buffer + (offset - begin); /* Start of wanted data */ |
157 | len-=(offset-begin); /* Start slop */ | 142 | len -= (offset - begin); /* Start slop */ |
158 | if(len>length) | 143 | if (len > length) |
159 | len = length; /* Ending slop */ | 144 | len = length; /* Ending slop */ |
160 | DBG(DBG_PROC, printk("3pos: %ld offset: %ld len: %d\n", pos, offset, len)); | 145 | DBG(DBG_PROC, printk("3pos: %ld offset: %ld len: %d\n", pos, offset, len)); |
161 | 146 | ||
162 | return (len); | 147 | return len; |
163 | } | 148 | } |
164 | 149 | ||
165 | static int eata_pio_release(struct Scsi_Host *sh) | 150 | static int eata_pio_release(struct Scsi_Host *sh) |
@@ -390,7 +375,7 @@ static int eata_pio_queue(struct scsi_cmnd *cmd, | |||
390 | 375 | ||
391 | DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd, | 376 | DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd, |
392 | "eata_pio_queue pid %ld, y %d\n", | 377 | "eata_pio_queue pid %ld, y %d\n", |
393 | cmd->pid, y)); | 378 | cmd->serial_number, y)); |
394 | 379 | ||
395 | cmd->scsi_done = (void *) done; | 380 | cmd->scsi_done = (void *) done; |
396 | 381 | ||
@@ -435,10 +420,10 @@ static int eata_pio_queue(struct scsi_cmnd *cmd, | |||
435 | cmd->result = DID_BUS_BUSY << 16; | 420 | cmd->result = DID_BUS_BUSY << 16; |
436 | scmd_printk(KERN_NOTICE, cmd, | 421 | scmd_printk(KERN_NOTICE, cmd, |
437 | "eata_pio_queue pid %ld, HBA busy, " | 422 | "eata_pio_queue pid %ld, HBA busy, " |
438 | "returning DID_BUS_BUSY, done.\n", cmd->pid); | 423 | "returning DID_BUS_BUSY, done.\n", cmd->serial_number); |
439 | done(cmd); | 424 | done(cmd); |
440 | cp->status = FREE; | 425 | cp->status = FREE; |
441 | return (0); | 426 | return 0; |
442 | } | 427 | } |
443 | /* FIXME: timeout */ | 428 | /* FIXME: timeout */ |
444 | while (!(inb(base + HA_RSTATUS) & HA_SDRQ)) | 429 | while (!(inb(base + HA_RSTATUS) & HA_SDRQ)) |
@@ -450,9 +435,9 @@ static int eata_pio_queue(struct scsi_cmnd *cmd, | |||
450 | 435 | ||
451 | DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd, | 436 | DBG(DBG_QUEUE, scmd_printk(KERN_DEBUG, cmd, |
452 | "Queued base %#.4lx pid: %ld " | 437 | "Queued base %#.4lx pid: %ld " |
453 | "slot %d irq %d\n", sh->base, cmd->pid, y, sh->irq)); | 438 | "slot %d irq %d\n", sh->base, cmd->serial_number, y, sh->irq)); |
454 | 439 | ||
455 | return (0); | 440 | return 0; |
456 | } | 441 | } |
457 | 442 | ||
458 | static int eata_pio_abort(struct scsi_cmnd *cmd) | 443 | static int eata_pio_abort(struct scsi_cmnd *cmd) |
@@ -461,7 +446,7 @@ static int eata_pio_abort(struct scsi_cmnd *cmd) | |||
461 | 446 | ||
462 | DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd, | 447 | DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd, |
463 | "eata_pio_abort called pid: %ld\n", | 448 | "eata_pio_abort called pid: %ld\n", |
464 | cmd->pid)); | 449 | cmd->serial_number)); |
465 | 450 | ||
466 | while (inb(cmd->device->host->base + HA_RAUXSTAT) & HA_ABUSY) | 451 | while (inb(cmd->device->host->base + HA_RAUXSTAT) & HA_ABUSY) |
467 | if (--loop == 0) { | 452 | if (--loop == 0) { |
@@ -497,7 +482,7 @@ static int eata_pio_host_reset(struct scsi_cmnd *cmd) | |||
497 | 482 | ||
498 | DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd, | 483 | DBG(DBG_ABNORM, scmd_printk(KERN_WARNING, cmd, |
499 | "eata_pio_reset called pid:%ld\n", | 484 | "eata_pio_reset called pid:%ld\n", |
500 | cmd->pid)); | 485 | cmd->serial_number)); |
501 | 486 | ||
502 | spin_lock_irq(host->host_lock); | 487 | spin_lock_irq(host->host_lock); |
503 | 488 | ||
@@ -516,7 +501,7 @@ static int eata_pio_host_reset(struct scsi_cmnd *cmd) | |||
516 | 501 | ||
517 | sp = HD(cmd)->ccb[x].cmd; | 502 | sp = HD(cmd)->ccb[x].cmd; |
518 | HD(cmd)->ccb[x].status = RESET; | 503 | HD(cmd)->ccb[x].status = RESET; |
519 | printk(KERN_WARNING "eata_pio_reset: slot %d in reset, pid %ld.\n", x, sp->pid); | 504 | printk(KERN_WARNING "eata_pio_reset: slot %d in reset, pid %ld.\n", x, sp->serial_number); |
520 | 505 | ||
521 | if (sp == NULL) | 506 | if (sp == NULL) |
522 | panic("eata_pio_reset: slot %d, sp==NULL.\n", x); | 507 | panic("eata_pio_reset: slot %d, sp==NULL.\n", x); |
@@ -589,23 +574,28 @@ static char *get_pio_board_data(unsigned long base, unsigned int irq, unsigned i | |||
589 | cp.cp_cdb[5] = 0; | 574 | cp.cp_cdb[5] = 0; |
590 | 575 | ||
591 | if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) | 576 | if (eata_pio_send_command(base, EATA_CMD_PIO_SEND_CP)) |
592 | return (NULL); | 577 | return NULL; |
593 | while (!(inb(base + HA_RSTATUS) & HA_SDRQ)); | 578 | |
579 | while (!(inb(base + HA_RSTATUS) & HA_SDRQ)) | ||
580 | cpu_relax(); | ||
581 | |||
594 | outsw(base + HA_RDATA, &cp, cplen); | 582 | outsw(base + HA_RDATA, &cp, cplen); |
595 | outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND); | 583 | outb(EATA_CMD_PIO_TRUNC, base + HA_WCOMMAND); |
596 | for (z = 0; z < cppadlen; z++) | 584 | for (z = 0; z < cppadlen; z++) |
597 | outw(0, base + HA_RDATA); | 585 | outw(0, base + HA_RDATA); |
598 | 586 | ||
599 | while (inb(base + HA_RSTATUS) & HA_SBUSY); | 587 | while (inb(base + HA_RSTATUS) & HA_SBUSY) |
588 | cpu_relax(); | ||
589 | |||
600 | if (inb(base + HA_RSTATUS) & HA_SERROR) | 590 | if (inb(base + HA_RSTATUS) & HA_SERROR) |
601 | return (NULL); | 591 | return NULL; |
602 | else if (!(inb(base + HA_RSTATUS) & HA_SDRQ)) | 592 | else if (!(inb(base + HA_RSTATUS) & HA_SDRQ)) |
603 | return (NULL); | 593 | return NULL; |
604 | else { | 594 | else { |
605 | insw(base + HA_RDATA, &buff, 127); | 595 | insw(base + HA_RDATA, &buff, 127); |
606 | while (inb(base + HA_RSTATUS) & HA_SDRQ) | 596 | while (inb(base + HA_RSTATUS) & HA_SDRQ) |
607 | inw(base + HA_RDATA); | 597 | inw(base + HA_RDATA); |
608 | return (buff); | 598 | return buff; |
609 | } | 599 | } |
610 | } | 600 | } |
611 | 601 | ||
diff --git a/drivers/scsi/esp_scsi.c b/drivers/scsi/esp_scsi.c index 95cf7b6cd622..4ed3a5297066 100644 --- a/drivers/scsi/esp_scsi.c +++ b/drivers/scsi/esp_scsi.c | |||
@@ -2138,7 +2138,7 @@ irqreturn_t scsi_esp_intr(int irq, void *dev_id) | |||
2138 | } | 2138 | } |
2139 | EXPORT_SYMBOL(scsi_esp_intr); | 2139 | EXPORT_SYMBOL(scsi_esp_intr); |
2140 | 2140 | ||
2141 | static void __devinit esp_get_revision(struct esp *esp) | 2141 | static void esp_get_revision(struct esp *esp) |
2142 | { | 2142 | { |
2143 | u8 val; | 2143 | u8 val; |
2144 | 2144 | ||
@@ -2187,7 +2187,7 @@ static void __devinit esp_get_revision(struct esp *esp) | |||
2187 | } | 2187 | } |
2188 | } | 2188 | } |
2189 | 2189 | ||
2190 | static void __devinit esp_init_swstate(struct esp *esp) | 2190 | static void esp_init_swstate(struct esp *esp) |
2191 | { | 2191 | { |
2192 | int i; | 2192 | int i; |
2193 | 2193 | ||
@@ -2233,7 +2233,7 @@ static void esp_bootup_reset(struct esp *esp) | |||
2233 | esp_read8(ESP_INTRPT); | 2233 | esp_read8(ESP_INTRPT); |
2234 | } | 2234 | } |
2235 | 2235 | ||
2236 | static void __devinit esp_set_clock_params(struct esp *esp) | 2236 | static void esp_set_clock_params(struct esp *esp) |
2237 | { | 2237 | { |
2238 | int fmhz; | 2238 | int fmhz; |
2239 | u8 ccf; | 2239 | u8 ccf; |
@@ -2306,7 +2306,7 @@ static const char *esp_chip_names[] = { | |||
2306 | 2306 | ||
2307 | static struct scsi_transport_template *esp_transport_template; | 2307 | static struct scsi_transport_template *esp_transport_template; |
2308 | 2308 | ||
2309 | int __devinit scsi_esp_register(struct esp *esp, struct device *dev) | 2309 | int scsi_esp_register(struct esp *esp, struct device *dev) |
2310 | { | 2310 | { |
2311 | static int instance; | 2311 | static int instance; |
2312 | int err; | 2312 | int err; |
@@ -2346,7 +2346,7 @@ int __devinit scsi_esp_register(struct esp *esp, struct device *dev) | |||
2346 | } | 2346 | } |
2347 | EXPORT_SYMBOL(scsi_esp_register); | 2347 | EXPORT_SYMBOL(scsi_esp_register); |
2348 | 2348 | ||
2349 | void __devexit scsi_esp_unregister(struct esp *esp) | 2349 | void scsi_esp_unregister(struct esp *esp) |
2350 | { | 2350 | { |
2351 | scsi_remove_host(esp->host); | 2351 | scsi_remove_host(esp->host); |
2352 | } | 2352 | } |
diff --git a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c index 36169d597e98..5d282e6a6ae1 100644 --- a/drivers/scsi/fdomain.c +++ b/drivers/scsi/fdomain.c | |||
@@ -387,7 +387,9 @@ static void __iomem * bios_mem; | |||
387 | static int bios_major; | 387 | static int bios_major; |
388 | static int bios_minor; | 388 | static int bios_minor; |
389 | static int PCI_bus; | 389 | static int PCI_bus; |
390 | #ifdef CONFIG_PCI | ||
390 | static struct pci_dev *PCI_dev; | 391 | static struct pci_dev *PCI_dev; |
392 | #endif | ||
391 | static int Quantum; /* Quantum board variant */ | 393 | static int Quantum; /* Quantum board variant */ |
392 | static int interrupt_level; | 394 | static int interrupt_level; |
393 | static volatile int in_command; | 395 | static volatile int in_command; |
@@ -1764,6 +1766,7 @@ struct scsi_host_template fdomain_driver_template = { | |||
1764 | }; | 1766 | }; |
1765 | 1767 | ||
1766 | #ifndef PCMCIA | 1768 | #ifndef PCMCIA |
1769 | #ifdef CONFIG_PCI | ||
1767 | 1770 | ||
1768 | static struct pci_device_id fdomain_pci_tbl[] __devinitdata = { | 1771 | static struct pci_device_id fdomain_pci_tbl[] __devinitdata = { |
1769 | { PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, | 1772 | { PCI_VENDOR_ID_FD, PCI_DEVICE_ID_FD_36C70, |
@@ -1771,7 +1774,7 @@ static struct pci_device_id fdomain_pci_tbl[] __devinitdata = { | |||
1771 | { } | 1774 | { } |
1772 | }; | 1775 | }; |
1773 | MODULE_DEVICE_TABLE(pci, fdomain_pci_tbl); | 1776 | MODULE_DEVICE_TABLE(pci, fdomain_pci_tbl); |
1774 | 1777 | #endif | |
1775 | #define driver_template fdomain_driver_template | 1778 | #define driver_template fdomain_driver_template |
1776 | #include "scsi_module.c" | 1779 | #include "scsi_module.c" |
1777 | 1780 | ||
diff --git a/drivers/scsi/g_NCR5380.c b/drivers/scsi/g_NCR5380.c index 880f70d24e65..607336f56d55 100644 --- a/drivers/scsi/g_NCR5380.c +++ b/drivers/scsi/g_NCR5380.c | |||
@@ -556,7 +556,7 @@ generic_NCR5380_biosparam(struct scsi_device *sdev, struct block_device *bdev, | |||
556 | } | 556 | } |
557 | #endif | 557 | #endif |
558 | 558 | ||
559 | #if NCR53C400_PSEUDO_DMA | 559 | #ifdef NCR53C400_PSEUDO_DMA |
560 | 560 | ||
561 | /** | 561 | /** |
562 | * NCR5380_pread - pseudo DMA read | 562 | * NCR5380_pread - pseudo DMA read |
diff --git a/drivers/scsi/gdth.c b/drivers/scsi/gdth.c index 55e4d2dc2bbe..e8010a702e73 100644 --- a/drivers/scsi/gdth.c +++ b/drivers/scsi/gdth.c | |||
@@ -27,280 +27,8 @@ | |||
27 | * along with this kernel; if not, write to the Free Software * | 27 | * along with this kernel; if not, write to the Free Software * |
28 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * | 28 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * |
29 | * * | 29 | * * |
30 | * Linux kernel 2.4.x, 2.6.x supported * | 30 | * Linux kernel 2.6.x supported * |
31 | * * | 31 | * * |
32 | * $Log: gdth.c,v $ | ||
33 | * Revision 1.74 2006/04/10 13:44:47 achim | ||
34 | * Community changes for 2.6.x | ||
35 | * Kernel 2.2.x no longer supported | ||
36 | * scsi_request interface removed, thanks to Christoph Hellwig | ||
37 | * | ||
38 | * Revision 1.73 2004/03/31 13:33:03 achim | ||
39 | * Special command 0xfd implemented to detect 64-bit DMA support | ||
40 | * | ||
41 | * Revision 1.72 2004/03/17 08:56:04 achim | ||
42 | * 64-bit DMA only enabled if FW >= x.43 | ||
43 | * | ||
44 | * Revision 1.71 2004/03/05 15:51:29 achim | ||
45 | * Screen service: separate message buffer, bugfixes | ||
46 | * | ||
47 | * Revision 1.70 2004/02/27 12:19:07 achim | ||
48 | * Bugfix: Reset bit in config (0xfe) call removed | ||
49 | * | ||
50 | * Revision 1.69 2004/02/20 09:50:24 achim | ||
51 | * Compatibility changes for kernels < 2.4.20 | ||
52 | * Bugfix screen service command size | ||
53 | * pci_set_dma_mask() error handling added | ||
54 | * | ||
55 | * Revision 1.68 2004/02/19 15:46:54 achim | ||
56 | * 64-bit DMA bugfixes | ||
57 | * Drive size bugfix for drives > 1TB | ||
58 | * | ||
59 | * Revision 1.67 2004/01/14 13:11:57 achim | ||
60 | * Tool access over /proc no longer supported | ||
61 | * Bugfixes IOCTLs | ||
62 | * | ||
63 | * Revision 1.66 2003/12/19 15:04:06 achim | ||
64 | * Bugfixes support for drives > 2TB | ||
65 | * | ||
66 | * Revision 1.65 2003/12/15 11:21:56 achim | ||
67 | * 64-bit DMA support added | ||
68 | * Support for drives > 2 TB implemented | ||
69 | * Kernels 2.2.x, 2.4.x, 2.6.x supported | ||
70 | * | ||
71 | * Revision 1.64 2003/09/17 08:30:26 achim | ||
72 | * EISA/ISA controller scan disabled | ||
73 | * Command line switch probe_eisa_isa added | ||
74 | * | ||
75 | * Revision 1.63 2003/07/12 14:01:00 Daniele Bellucci <bellucda@tiscali.it> | ||
76 | * Minor cleanups in gdth_ioctl. | ||
77 | * | ||
78 | * Revision 1.62 2003/02/27 15:01:59 achim | ||
79 | * Dynamic DMA mapping implemented | ||
80 | * New (character device) IOCTL interface added | ||
81 | * Other controller related changes made | ||
82 | * | ||
83 | * Revision 1.61 2002/11/08 13:09:52 boji | ||
84 | * Added support for XSCALE based RAID Controllers | ||
85 | * Fixed SCREENSERVICE initialization in SMP cases | ||
86 | * Added checks for gdth_polling before GDTH_HA_LOCK | ||
87 | * | ||
88 | * Revision 1.60 2002/02/05 09:35:22 achim | ||
89 | * MODULE_LICENSE only if kernel >= 2.4.11 | ||
90 | * | ||
91 | * Revision 1.59 2002/01/30 09:46:33 achim | ||
92 | * Small changes | ||
93 | * | ||
94 | * Revision 1.58 2002/01/29 15:30:02 achim | ||
95 | * Set default value of shared_access to Y | ||
96 | * New status S_CACHE_RESERV for clustering added | ||
97 | * | ||
98 | * Revision 1.57 2001/08/21 11:16:35 achim | ||
99 | * Bugfix free_irq() | ||
100 | * | ||
101 | * Revision 1.56 2001/08/09 11:19:39 achim | ||
102 | * Scsi_Host_Template changes | ||
103 | * | ||
104 | * Revision 1.55 2001/08/09 10:11:28 achim | ||
105 | * Command HOST_UNFREEZE_IO before cache service init. | ||
106 | * | ||
107 | * Revision 1.54 2001/07/20 13:48:12 achim | ||
108 | * Expand: gdth_analyse_hdrive() removed | ||
109 | * | ||
110 | * Revision 1.53 2001/07/17 09:52:49 achim | ||
111 | * Small OEM related change | ||
112 | * | ||
113 | * Revision 1.52 2001/06/19 15:06:20 achim | ||
114 | * New host command GDT_UNFREEZE_IO added | ||
115 | * | ||
116 | * Revision 1.51 2001/05/22 06:42:37 achim | ||
117 | * PCI: Subdevice ID added | ||
118 | * | ||
119 | * Revision 1.50 2001/05/17 13:42:16 achim | ||
120 | * Support for Intel Storage RAID Controllers added | ||
121 | * | ||
122 | * Revision 1.50 2001/05/17 12:12:34 achim | ||
123 | * Support for Intel Storage RAID Controllers added | ||
124 | * | ||
125 | * Revision 1.49 2001/03/15 15:07:17 achim | ||
126 | * New __setup interface for boot command line options added | ||
127 | * | ||
128 | * Revision 1.48 2001/02/06 12:36:28 achim | ||
129 | * Bugfix Cluster protocol | ||
130 | * | ||
131 | * Revision 1.47 2001/01/10 14:42:06 achim | ||
132 | * New switch shared_access added | ||
133 | * | ||
134 | * Revision 1.46 2001/01/09 08:11:35 achim | ||
135 | * gdth_command() removed | ||
136 | * meaning of Scsi_Pointer members changed | ||
137 | * | ||
138 | * Revision 1.45 2000/11/16 12:02:24 achim | ||
139 | * Changes for kernel 2.4 | ||
140 | * | ||
141 | * Revision 1.44 2000/10/11 08:44:10 achim | ||
142 | * Clustering changes: New flag media_changed added | ||
143 | * | ||
144 | * Revision 1.43 2000/09/20 12:59:01 achim | ||
145 | * DPMEM remap functions for all PCI controller types implemented | ||
146 | * Small changes for ia64 platform | ||
147 | * | ||
148 | * Revision 1.42 2000/07/20 09:04:50 achim | ||
149 | * Small changes for kernel 2.4 | ||
150 | * | ||
151 | * Revision 1.41 2000/07/04 14:11:11 achim | ||
152 | * gdth_analyse_hdrive() added to rescan drives after online expansion | ||
153 | * | ||
154 | * Revision 1.40 2000/06/27 11:24:16 achim | ||
155 | * Changes Clustering, Screenservice | ||
156 | * | ||
157 | * Revision 1.39 2000/06/15 13:09:04 achim | ||
158 | * Changes for gdth_do_cmd() | ||
159 | * | ||
160 | * Revision 1.38 2000/06/15 12:08:43 achim | ||
161 | * Bugfix gdth_sync_event(), service SCREENSERVICE | ||
162 | * Data direction for command 0xc2 changed to DOU | ||
163 | * | ||
164 | * Revision 1.37 2000/05/25 13:50:10 achim | ||
165 | * New driver parameter virt_ctr added | ||
166 | * | ||
167 | * Revision 1.36 2000/05/04 08:50:46 achim | ||
168 | * Event buffer now in gdth_ha_str | ||
169 | * | ||
170 | * Revision 1.35 2000/03/03 10:44:08 achim | ||
171 | * New event_string only valid for the RP controller family | ||
172 | * | ||
173 | * Revision 1.34 2000/03/02 14:55:29 achim | ||
174 | * New mechanism for async. event handling implemented | ||
175 | * | ||
176 | * Revision 1.33 2000/02/21 15:37:37 achim | ||
177 | * Bugfix Alpha platform + DPMEM above 4GB | ||
178 | * | ||
179 | * Revision 1.32 2000/02/14 16:17:37 achim | ||
180 | * Bugfix sense_buffer[] + raw devices | ||
181 | * | ||
182 | * Revision 1.31 2000/02/10 10:29:00 achim | ||
183 | * Delete sense_buffer[0], if command OK | ||
184 | * | ||
185 | * Revision 1.30 1999/11/02 13:42:39 achim | ||
186 | * ARRAY_DRV_LIST2 implemented | ||
187 | * Now 255 log. and 100 host drives supported | ||
188 | * | ||
189 | * Revision 1.29 1999/10/05 13:28:47 achim | ||
190 | * GDT_CLUST_RESET added | ||
191 | * | ||
192 | * Revision 1.28 1999/08/12 13:44:54 achim | ||
193 | * MOUNTALL removed | ||
194 | * Cluster drives -> removeable drives | ||
195 | * | ||
196 | * Revision 1.27 1999/06/22 07:22:38 achim | ||
197 | * Small changes | ||
198 | * | ||
199 | * Revision 1.26 1999/06/10 16:09:12 achim | ||
200 | * Cluster Host Drive support: Bugfixes | ||
201 | * | ||
202 | * Revision 1.25 1999/06/01 16:03:56 achim | ||
203 | * gdth_init_pci(): Manipulate config. space to start RP controller | ||
204 | * | ||
205 | * Revision 1.24 1999/05/26 11:53:06 achim | ||
206 | * Cluster Host Drive support added | ||
207 | * | ||
208 | * Revision 1.23 1999/03/26 09:12:31 achim | ||
209 | * Default value for hdr_channel set to 0 | ||
210 | * | ||
211 | * Revision 1.22 1999/03/22 16:27:16 achim | ||
212 | * Bugfix: gdth_store_event() must not be locked with GDTH_LOCK_HA() | ||
213 | * | ||
214 | * Revision 1.21 1999/03/16 13:40:34 achim | ||
215 | * Problems with reserved drives solved | ||
216 | * gdth_eh_bus_reset() implemented | ||
217 | * | ||
218 | * Revision 1.20 1999/03/10 09:08:13 achim | ||
219 | * Bugfix: Corrections in gdth_direction_tab[] made | ||
220 | * Bugfix: Increase command timeout (gdth_update_timeout()) NOT in gdth_putq() | ||
221 | * | ||
222 | * Revision 1.19 1999/03/05 14:38:16 achim | ||
223 | * Bugfix: Heads/Sectors mapping for reserved devices possibly wrong | ||
224 | * -> gdth_eval_mapping() implemented, changes in gdth_bios_param() | ||
225 | * INIT_RETRIES set to 100s to avoid DEINIT-Timeout for controllers | ||
226 | * with BIOS disabled and memory test set to Intensive | ||
227 | * Enhanced /proc support | ||
228 | * | ||
229 | * Revision 1.18 1999/02/24 09:54:33 achim | ||
230 | * Command line parameter hdr_channel implemented | ||
231 | * Bugfix for EISA controllers + Linux 2.2.x | ||
232 | * | ||
233 | * Revision 1.17 1998/12/17 15:58:11 achim | ||
234 | * Command line parameters implemented | ||
235 | * Changes for Alpha platforms | ||
236 | * PCI controller scan changed | ||
237 | * SMP support improved (spin_lock_irqsave(),...) | ||
238 | * New async. events, new scan/reserve commands included | ||
239 | * | ||
240 | * Revision 1.16 1998/09/28 16:08:46 achim | ||
241 | * GDT_PCIMPR: DPMEM remapping, if required | ||
242 | * mdelay() added | ||
243 | * | ||
244 | * Revision 1.15 1998/06/03 14:54:06 achim | ||
245 | * gdth_delay(), gdth_flush() implemented | ||
246 | * Bugfix: gdth_release() changed | ||
247 | * | ||
248 | * Revision 1.14 1998/05/22 10:01:17 achim | ||
249 | * mj: pcibios_strerror() removed | ||
250 | * Improved SMP support (if version >= 2.1.95) | ||
251 | * gdth_halt(): halt_called flag added (if version < 2.1) | ||
252 | * | ||
253 | * Revision 1.13 1998/04/16 09:14:57 achim | ||
254 | * Reserve drives (for raw service) implemented | ||
255 | * New error handling code enabled | ||
256 | * Get controller name from board_info() IOCTL | ||
257 | * Final round of PCI device driver patches by Martin Mares | ||
258 | * | ||
259 | * Revision 1.12 1998/03/03 09:32:37 achim | ||
260 | * Fibre channel controller support added | ||
261 | * | ||
262 | * Revision 1.11 1998/01/27 16:19:14 achim | ||
263 | * SA_SHIRQ added | ||
264 | * add_timer()/del_timer() instead of GDTH_TIMER | ||
265 | * scsi_add_timer()/scsi_del_timer() instead of SCSI_TIMER | ||
266 | * New error handling included | ||
267 | * | ||
268 | * Revision 1.10 1997/10/31 12:29:57 achim | ||
269 | * Read heads/sectors from host drive | ||
270 | * | ||
271 | * Revision 1.9 1997/09/04 10:07:25 achim | ||
272 | * IO-mapping with virt_to_bus(), gdth_readb(), gdth_writeb(), ... | ||
273 | * register_reboot_notifier() to get a notify on shutown used | ||
274 | * | ||
275 | * Revision 1.8 1997/04/02 12:14:30 achim | ||
276 | * Version 1.00 (see gdth.h), tested with kernel 2.0.29 | ||
277 | * | ||
278 | * Revision 1.7 1997/03/12 13:33:37 achim | ||
279 | * gdth_reset() changed, new async. events | ||
280 | * | ||
281 | * Revision 1.6 1997/03/04 14:01:11 achim | ||
282 | * Shutdown routine gdth_halt() implemented | ||
283 | * | ||
284 | * Revision 1.5 1997/02/21 09:08:36 achim | ||
285 | * New controller included (RP, RP1, RP2 series) | ||
286 | * IOCTL interface implemented | ||
287 | * | ||
288 | * Revision 1.4 1996/07/05 12:48:55 achim | ||
289 | * Function gdth_bios_param() implemented | ||
290 | * New constant GDTH_MAXC_P_L inserted | ||
291 | * GDT_WRITE_THR, GDT_EXT_INFO implemented | ||
292 | * Function gdth_reset() changed | ||
293 | * | ||
294 | * Revision 1.3 1996/05/10 09:04:41 achim | ||
295 | * Small changes for Linux 1.2.13 | ||
296 | * | ||
297 | * Revision 1.2 1996/05/09 12:45:27 achim | ||
298 | * Loadable module support implemented | ||
299 | * /proc support corrections made | ||
300 | * | ||
301 | * Revision 1.1 1996/04/11 07:35:57 achim | ||
302 | * Initial revision | ||
303 | * | ||
304 | ************************************************************************/ | 32 | ************************************************************************/ |
305 | 33 | ||
306 | /* All GDT Disk Array Controllers are fully supported by this driver. | 34 | /* All GDT Disk Array Controllers are fully supported by this driver. |
@@ -328,8 +56,6 @@ | |||
328 | * max_ids:x x - target ID count per channel (1..MAXID) | 56 | * max_ids:x x - target ID count per channel (1..MAXID) |
329 | * rescan:Y rescan all channels/IDs | 57 | * rescan:Y rescan all channels/IDs |
330 | * rescan:N use all devices found until now | 58 | * rescan:N use all devices found until now |
331 | * virt_ctr:Y map every channel to a virtual controller | ||
332 | * virt_ctr:N use multi channel support | ||
333 | * hdr_channel:x x - number of virtual bus for host drives | 59 | * hdr_channel:x x - number of virtual bus for host drives |
334 | * shared_access:Y disable driver reserve/release protocol to | 60 | * shared_access:Y disable driver reserve/release protocol to |
335 | * access a shared resource from several nodes, | 61 | * access a shared resource from several nodes, |
@@ -341,7 +67,7 @@ | |||
341 | * force_dma32:N use 64 bit DMA mode, if supported | 67 | * force_dma32:N use 64 bit DMA mode, if supported |
342 | * | 68 | * |
343 | * The default values are: "gdth=disable:N,reserve_mode:1,reverse_scan:N, | 69 | * The default values are: "gdth=disable:N,reserve_mode:1,reverse_scan:N, |
344 | * max_ids:127,rescan:N,virt_ctr:N,hdr_channel:0, | 70 | * max_ids:127,rescan:N,hdr_channel:0, |
345 | * shared_access:Y,probe_eisa_isa:N,force_dma32:N". | 71 | * shared_access:Y,probe_eisa_isa:N,force_dma32:N". |
346 | * Here is another example: "gdth=reserve_list:0,1,2,0,0,1,3,0,rescan:Y". | 72 | * Here is another example: "gdth=reserve_list:0,1,2,0,0,1,3,0,rescan:Y". |
347 | * | 73 | * |
@@ -352,22 +78,22 @@ | |||
352 | * '1' in place of 'Y' and '0' in place of 'N'. | 78 | * '1' in place of 'Y' and '0' in place of 'N'. |
353 | * | 79 | * |
354 | * Default: "modprobe gdth disable=0 reserve_mode=1 reverse_scan=0 | 80 | * Default: "modprobe gdth disable=0 reserve_mode=1 reverse_scan=0 |
355 | * max_ids=127 rescan=0 virt_ctr=0 hdr_channel=0 shared_access=0 | 81 | * max_ids=127 rescan=0 hdr_channel=0 shared_access=0 |
356 | * probe_eisa_isa=0 force_dma32=0" | 82 | * probe_eisa_isa=0 force_dma32=0" |
357 | * The other example: "modprobe gdth reserve_list=0,1,2,0,0,1,3,0 rescan=1". | 83 | * The other example: "modprobe gdth reserve_list=0,1,2,0,0,1,3,0 rescan=1". |
358 | */ | 84 | */ |
359 | 85 | ||
360 | /* The meaning of the Scsi_Pointer members in this driver is as follows: | 86 | /* The meaning of the Scsi_Pointer members in this driver is as follows: |
361 | * ptr: Chaining | 87 | * ptr: Chaining |
362 | * this_residual: Command priority | 88 | * this_residual: gdth_bufflen |
363 | * buffer: phys. DMA sense buffer | 89 | * buffer: gdth_sglist |
364 | * dma_handle: phys. DMA buffer (kernel >= 2.4.0) | 90 | * dma_handle: unused |
365 | * buffers_residual: Timeout value | 91 | * buffers_residual: gdth_sg_count |
366 | * Status: Command status (gdth_do_cmd()), DMA mem. mappings | 92 | * Status: unused |
367 | * Message: Additional info (gdth_do_cmd()), DMA direction | 93 | * Message: unused |
368 | * have_data_in: Flag for gdth_wait_completion() | 94 | * have_data_in: unused |
369 | * sent_command: Opcode special command | 95 | * sent_command: unused |
370 | * phase: Service/parameter/return code special command | 96 | * phase: unused |
371 | */ | 97 | */ |
372 | 98 | ||
373 | 99 | ||
@@ -392,12 +118,8 @@ | |||
392 | #include <linux/proc_fs.h> | 118 | #include <linux/proc_fs.h> |
393 | #include <linux/time.h> | 119 | #include <linux/time.h> |
394 | #include <linux/timer.h> | 120 | #include <linux/timer.h> |
395 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,6) | ||
396 | #include <linux/dma-mapping.h> | 121 | #include <linux/dma-mapping.h> |
397 | #else | 122 | #include <linux/list.h> |
398 | #define DMA_32BIT_MASK 0x00000000ffffffffULL | ||
399 | #define DMA_64BIT_MASK 0xffffffffffffffffULL | ||
400 | #endif | ||
401 | 123 | ||
402 | #ifdef GDTH_RTC | 124 | #ifdef GDTH_RTC |
403 | #include <linux/mc146818rtc.h> | 125 | #include <linux/mc146818rtc.h> |
@@ -409,29 +131,27 @@ | |||
409 | #include <asm/io.h> | 131 | #include <asm/io.h> |
410 | #include <asm/uaccess.h> | 132 | #include <asm/uaccess.h> |
411 | #include <linux/spinlock.h> | 133 | #include <linux/spinlock.h> |
412 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
413 | #include <linux/blkdev.h> | 134 | #include <linux/blkdev.h> |
414 | #else | 135 | #include <linux/scatterlist.h> |
415 | #include <linux/blk.h> | ||
416 | #include "sd.h" | ||
417 | #endif | ||
418 | 136 | ||
419 | #include "scsi.h" | 137 | #include "scsi.h" |
420 | #include <scsi/scsi_host.h> | 138 | #include <scsi/scsi_host.h> |
421 | #include "gdth_kcompat.h" | ||
422 | #include "gdth.h" | 139 | #include "gdth.h" |
423 | 140 | ||
424 | static void gdth_delay(int milliseconds); | 141 | static void gdth_delay(int milliseconds); |
425 | static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs); | 142 | static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs); |
426 | static irqreturn_t gdth_interrupt(int irq, void *dev_id); | 143 | static irqreturn_t gdth_interrupt(int irq, void *dev_id); |
427 | static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp); | 144 | static irqreturn_t __gdth_interrupt(gdth_ha_str *ha, int irq, |
428 | static int gdth_async_event(int hanum); | 145 | int gdth_from_wait, int* pIndex); |
146 | static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, | ||
147 | Scsi_Cmnd *scp); | ||
148 | static int gdth_async_event(gdth_ha_str *ha); | ||
429 | static void gdth_log_event(gdth_evt_data *dvr, char *buffer); | 149 | static void gdth_log_event(gdth_evt_data *dvr, char *buffer); |
430 | 150 | ||
431 | static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority); | 151 | static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority); |
432 | static void gdth_next(int hanum); | 152 | static void gdth_next(gdth_ha_str *ha); |
433 | static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b); | 153 | static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b); |
434 | static int gdth_special_cmd(int hanum,Scsi_Cmnd *scp); | 154 | static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp); |
435 | static gdth_evt_str *gdth_store_event(gdth_ha_str *ha, ushort source, | 155 | static gdth_evt_str *gdth_store_event(gdth_ha_str *ha, ushort source, |
436 | ushort idx, gdth_evt_data *evt); | 156 | ushort idx, gdth_evt_data *evt); |
437 | static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr); | 157 | static int gdth_read_event(gdth_ha_str *ha, int handle, gdth_evt_str *estr); |
@@ -439,42 +159,34 @@ static void gdth_readapp_event(gdth_ha_str *ha, unchar application, | |||
439 | gdth_evt_str *estr); | 159 | gdth_evt_str *estr); |
440 | static void gdth_clear_events(void); | 160 | static void gdth_clear_events(void); |
441 | 161 | ||
442 | static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, | 162 | static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, |
443 | char *buffer,ushort count); | 163 | char *buffer, ushort count, int to_buffer); |
444 | static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp); | 164 | static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp); |
445 | static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive); | 165 | static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive); |
446 | 166 | ||
447 | static int gdth_search_eisa(ushort eisa_adr); | 167 | static void gdth_enable_int(gdth_ha_str *ha); |
448 | static int gdth_search_isa(ulong32 bios_adr); | 168 | static unchar gdth_get_status(gdth_ha_str *ha, int irq); |
449 | static int gdth_search_pci(gdth_pci_str *pcistr); | 169 | static int gdth_test_busy(gdth_ha_str *ha); |
450 | static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, | 170 | static int gdth_get_cmd_index(gdth_ha_str *ha); |
451 | ushort vendor, ushort dev); | 171 | static void gdth_release_event(gdth_ha_str *ha); |
452 | static void gdth_sort_pci(gdth_pci_str *pcistr, int cnt); | 172 | static int gdth_wait(gdth_ha_str *ha, int index,ulong32 time); |
453 | static int gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha); | 173 | static int gdth_internal_cmd(gdth_ha_str *ha, unchar service, ushort opcode, |
454 | static int gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha); | 174 | ulong32 p1, ulong64 p2,ulong64 p3); |
455 | static int gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha); | 175 | static int gdth_search_drives(gdth_ha_str *ha); |
456 | 176 | static int gdth_analyse_hdrive(gdth_ha_str *ha, ushort hdrive); | |
457 | static void gdth_enable_int(int hanum); | 177 | |
458 | static int gdth_get_status(unchar *pIStatus,int irq); | 178 | static const char *gdth_ctr_name(gdth_ha_str *ha); |
459 | static int gdth_test_busy(int hanum); | ||
460 | static int gdth_get_cmd_index(int hanum); | ||
461 | static void gdth_release_event(int hanum); | ||
462 | static int gdth_wait(int hanum,int index,ulong32 time); | ||
463 | static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, | ||
464 | ulong64 p2,ulong64 p3); | ||
465 | static int gdth_search_drives(int hanum); | ||
466 | static int gdth_analyse_hdrive(int hanum, ushort hdrive); | ||
467 | |||
468 | static const char *gdth_ctr_name(int hanum); | ||
469 | 179 | ||
470 | static int gdth_open(struct inode *inode, struct file *filep); | 180 | static int gdth_open(struct inode *inode, struct file *filep); |
471 | static int gdth_close(struct inode *inode, struct file *filep); | 181 | static int gdth_close(struct inode *inode, struct file *filep); |
472 | static int gdth_ioctl(struct inode *inode, struct file *filep, | 182 | static int gdth_ioctl(struct inode *inode, struct file *filep, |
473 | unsigned int cmd, unsigned long arg); | 183 | unsigned int cmd, unsigned long arg); |
474 | 184 | ||
475 | static void gdth_flush(int hanum); | 185 | static void gdth_flush(gdth_ha_str *ha); |
476 | static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); | 186 | static int gdth_halt(struct notifier_block *nb, ulong event, void *buf); |
477 | static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); | 187 | static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)); |
188 | static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp, | ||
189 | struct gdth_cmndinfo *cmndinfo); | ||
478 | static void gdth_scsi_done(struct scsi_cmnd *scp); | 190 | static void gdth_scsi_done(struct scsi_cmnd *scp); |
479 | 191 | ||
480 | #ifdef DEBUG_GDTH | 192 | #ifdef DEBUG_GDTH |
@@ -571,29 +283,17 @@ static struct timer_list gdth_timer; | |||
571 | #define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b) | 283 | #define GDTOFFSOF(a,b) (size_t)&(((a*)0)->b) |
572 | #define INDEX_OK(i,t) ((i)<ARRAY_SIZE(t)) | 284 | #define INDEX_OK(i,t) ((i)<ARRAY_SIZE(t)) |
573 | 285 | ||
574 | #define NUMDATA(a) ( (gdth_num_str *)((a)->hostdata)) | ||
575 | #define HADATA(a) (&((gdth_ext_str *)((a)->hostdata))->haext) | ||
576 | #define CMDDATA(a) (&((gdth_ext_str *)((a)->hostdata))->cmdext) | ||
577 | |||
578 | #define BUS_L2P(a,b) ((b)>(a)->virt_bus ? (b-1):(b)) | 286 | #define BUS_L2P(a,b) ((b)>(a)->virt_bus ? (b-1):(b)) |
579 | 287 | ||
580 | #define gdth_readb(addr) readb(addr) | 288 | #ifdef CONFIG_ISA |
581 | #define gdth_readw(addr) readw(addr) | ||
582 | #define gdth_readl(addr) readl(addr) | ||
583 | #define gdth_writeb(b,addr) writeb((b),(addr)) | ||
584 | #define gdth_writew(b,addr) writew((b),(addr)) | ||
585 | #define gdth_writel(b,addr) writel((b),(addr)) | ||
586 | |||
587 | static unchar gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */ | 289 | static unchar gdth_drq_tab[4] = {5,6,7,7}; /* DRQ table */ |
290 | #endif | ||
291 | #if defined(CONFIG_EISA) || defined(CONFIG_ISA) | ||
588 | static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */ | 292 | static unchar gdth_irq_tab[6] = {0,10,11,12,14,0}; /* IRQ table */ |
293 | #endif | ||
589 | static unchar gdth_polling; /* polling if TRUE */ | 294 | static unchar gdth_polling; /* polling if TRUE */ |
590 | static unchar gdth_from_wait = FALSE; /* gdth_wait() */ | ||
591 | static int wait_index,wait_hanum; /* gdth_wait() */ | ||
592 | static int gdth_ctr_count = 0; /* controller count */ | 295 | static int gdth_ctr_count = 0; /* controller count */ |
593 | static int gdth_ctr_vcount = 0; /* virt. ctr. count */ | 296 | static LIST_HEAD(gdth_instances); /* controller list */ |
594 | static int gdth_ctr_released = 0; /* gdth_release() */ | ||
595 | static struct Scsi_Host *gdth_ctr_tab[MAXHA]; /* controller table */ | ||
596 | static struct Scsi_Host *gdth_ctr_vtab[MAXHA*MAXBUS]; /* virt. ctr. table */ | ||
597 | static unchar gdth_write_through = FALSE; /* write through */ | 297 | static unchar gdth_write_through = FALSE; /* write through */ |
598 | static gdth_evt_str ebuffer[MAX_EVENTS]; /* event buffer */ | 298 | static gdth_evt_str ebuffer[MAX_EVENTS]; /* event buffer */ |
599 | static int elastidx; | 299 | static int elastidx; |
@@ -645,8 +345,6 @@ static int hdr_channel = 0; | |||
645 | static int max_ids = MAXID; | 345 | static int max_ids = MAXID; |
646 | /* rescan all IDs */ | 346 | /* rescan all IDs */ |
647 | static int rescan = 0; | 347 | static int rescan = 0; |
648 | /* map channels to virtual controllers */ | ||
649 | static int virt_ctr = 0; | ||
650 | /* shared access */ | 348 | /* shared access */ |
651 | static int shared_access = 1; | 349 | static int shared_access = 1; |
652 | /* enable support for EISA and ISA controllers */ | 350 | /* enable support for EISA and ISA controllers */ |
@@ -655,7 +353,6 @@ static int probe_eisa_isa = 0; | |||
655 | static int force_dma32 = 0; | 353 | static int force_dma32 = 0; |
656 | 354 | ||
657 | /* parameters for modprobe/insmod */ | 355 | /* parameters for modprobe/insmod */ |
658 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,11) | ||
659 | module_param_array(irq, int, NULL, 0); | 356 | module_param_array(irq, int, NULL, 0); |
660 | module_param(disable, int, 0); | 357 | module_param(disable, int, 0); |
661 | module_param(reserve_mode, int, 0); | 358 | module_param(reserve_mode, int, 0); |
@@ -664,24 +361,9 @@ module_param(reverse_scan, int, 0); | |||
664 | module_param(hdr_channel, int, 0); | 361 | module_param(hdr_channel, int, 0); |
665 | module_param(max_ids, int, 0); | 362 | module_param(max_ids, int, 0); |
666 | module_param(rescan, int, 0); | 363 | module_param(rescan, int, 0); |
667 | module_param(virt_ctr, int, 0); | ||
668 | module_param(shared_access, int, 0); | 364 | module_param(shared_access, int, 0); |
669 | module_param(probe_eisa_isa, int, 0); | 365 | module_param(probe_eisa_isa, int, 0); |
670 | module_param(force_dma32, int, 0); | 366 | module_param(force_dma32, int, 0); |
671 | #else | ||
672 | MODULE_PARM(irq, "i"); | ||
673 | MODULE_PARM(disable, "i"); | ||
674 | MODULE_PARM(reserve_mode, "i"); | ||
675 | MODULE_PARM(reserve_list, "4-" __MODULE_STRING(MAX_RES_ARGS) "i"); | ||
676 | MODULE_PARM(reverse_scan, "i"); | ||
677 | MODULE_PARM(hdr_channel, "i"); | ||
678 | MODULE_PARM(max_ids, "i"); | ||
679 | MODULE_PARM(rescan, "i"); | ||
680 | MODULE_PARM(virt_ctr, "i"); | ||
681 | MODULE_PARM(shared_access, "i"); | ||
682 | MODULE_PARM(probe_eisa_isa, "i"); | ||
683 | MODULE_PARM(force_dma32, "i"); | ||
684 | #endif | ||
685 | MODULE_AUTHOR("Achim Leubner"); | 367 | MODULE_AUTHOR("Achim Leubner"); |
686 | MODULE_LICENSE("GPL"); | 368 | MODULE_LICENSE("GPL"); |
687 | 369 | ||
@@ -692,6 +374,47 @@ static const struct file_operations gdth_fops = { | |||
692 | .release = gdth_close, | 374 | .release = gdth_close, |
693 | }; | 375 | }; |
694 | 376 | ||
377 | /* | ||
378 | * gdth scsi_command access wrappers. | ||
379 | * below 6 functions are used throughout the driver to access scsi_command's | ||
380 | * io parameters. The reason we do not use the regular accessors from | ||
381 | * scsi_cmnd.h is because of gdth_execute(). Since it is unrecommended for | ||
382 | * llds to directly set scsi_cmnd's IO members. This driver will use SCp | ||
383 | * members for IO parameters, and will copy scsi_cmnd's members to Scp | ||
384 | * members in queuecommand. For internal commands through gdth_execute() | ||
385 | * SCp's members will be set directly. | ||
386 | */ | ||
387 | static inline unsigned gdth_bufflen(struct scsi_cmnd *cmd) | ||
388 | { | ||
389 | return (unsigned)cmd->SCp.this_residual; | ||
390 | } | ||
391 | |||
392 | static inline void gdth_set_bufflen(struct scsi_cmnd *cmd, unsigned bufflen) | ||
393 | { | ||
394 | cmd->SCp.this_residual = bufflen; | ||
395 | } | ||
396 | |||
397 | static inline unsigned gdth_sg_count(struct scsi_cmnd *cmd) | ||
398 | { | ||
399 | return (unsigned)cmd->SCp.buffers_residual; | ||
400 | } | ||
401 | |||
402 | static inline void gdth_set_sg_count(struct scsi_cmnd *cmd, unsigned sg_count) | ||
403 | { | ||
404 | cmd->SCp.buffers_residual = sg_count; | ||
405 | } | ||
406 | |||
407 | static inline struct scatterlist *gdth_sglist(struct scsi_cmnd *cmd) | ||
408 | { | ||
409 | return cmd->SCp.buffer; | ||
410 | } | ||
411 | |||
412 | static inline void gdth_set_sglist(struct scsi_cmnd *cmd, | ||
413 | struct scatterlist *sglist) | ||
414 | { | ||
415 | cmd->SCp.buffer = sglist; | ||
416 | } | ||
417 | |||
695 | #include "gdth_proc.h" | 418 | #include "gdth_proc.h" |
696 | #include "gdth_proc.c" | 419 | #include "gdth_proc.c" |
697 | 420 | ||
@@ -701,6 +424,45 @@ static struct notifier_block gdth_notifier = { | |||
701 | }; | 424 | }; |
702 | static int notifier_disabled = 0; | 425 | static int notifier_disabled = 0; |
703 | 426 | ||
427 | static gdth_ha_str *gdth_find_ha(int hanum) | ||
428 | { | ||
429 | gdth_ha_str *ha; | ||
430 | |||
431 | list_for_each_entry(ha, &gdth_instances, list) | ||
432 | if (hanum == ha->hanum) | ||
433 | return ha; | ||
434 | |||
435 | return NULL; | ||
436 | } | ||
437 | |||
438 | static struct gdth_cmndinfo *gdth_get_cmndinfo(gdth_ha_str *ha) | ||
439 | { | ||
440 | struct gdth_cmndinfo *priv = NULL; | ||
441 | ulong flags; | ||
442 | int i; | ||
443 | |||
444 | spin_lock_irqsave(&ha->smp_lock, flags); | ||
445 | |||
446 | for (i=0; i<GDTH_MAXCMDS; ++i) { | ||
447 | if (ha->cmndinfo[i].index == 0) { | ||
448 | priv = &ha->cmndinfo[i]; | ||
449 | priv->index = i+1; | ||
450 | memset(priv, 0, sizeof(*priv)); | ||
451 | break; | ||
452 | } | ||
453 | } | ||
454 | |||
455 | spin_unlock_irqrestore(&ha->smp_lock, flags); | ||
456 | |||
457 | return priv; | ||
458 | } | ||
459 | |||
460 | static void gdth_put_cmndinfo(struct gdth_cmndinfo *priv) | ||
461 | { | ||
462 | BUG_ON(!priv); | ||
463 | priv->index = 0; | ||
464 | } | ||
465 | |||
704 | static void gdth_delay(int milliseconds) | 466 | static void gdth_delay(int milliseconds) |
705 | { | 467 | { |
706 | if (milliseconds == 0) { | 468 | if (milliseconds == 0) { |
@@ -710,80 +472,62 @@ static void gdth_delay(int milliseconds) | |||
710 | } | 472 | } |
711 | } | 473 | } |
712 | 474 | ||
713 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
714 | static void gdth_scsi_done(struct scsi_cmnd *scp) | 475 | static void gdth_scsi_done(struct scsi_cmnd *scp) |
715 | { | 476 | { |
716 | TRACE2(("gdth_scsi_done()\n")); | 477 | struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); |
478 | int internal_command = cmndinfo->internal_command; | ||
479 | |||
480 | TRACE2(("gdth_scsi_done()\n")); | ||
481 | |||
482 | gdth_put_cmndinfo(cmndinfo); | ||
483 | scp->host_scribble = NULL; | ||
717 | 484 | ||
718 | if (scp->request) | 485 | if (internal_command) |
719 | complete((struct completion *)scp->request); | 486 | complete((struct completion *)scp->request); |
487 | else | ||
488 | scp->scsi_done(scp); | ||
720 | } | 489 | } |
721 | 490 | ||
722 | int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, | 491 | int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, |
723 | int timeout, u32 *info) | 492 | int timeout, u32 *info) |
724 | { | 493 | { |
494 | gdth_ha_str *ha = shost_priv(sdev->host); | ||
725 | Scsi_Cmnd *scp; | 495 | Scsi_Cmnd *scp; |
496 | struct gdth_cmndinfo cmndinfo; | ||
497 | struct scatterlist one_sg; | ||
726 | DECLARE_COMPLETION_ONSTACK(wait); | 498 | DECLARE_COMPLETION_ONSTACK(wait); |
727 | int rval; | 499 | int rval; |
728 | 500 | ||
729 | scp = kmalloc(sizeof(*scp), GFP_KERNEL); | 501 | scp = kzalloc(sizeof(*scp), GFP_KERNEL); |
730 | if (!scp) | 502 | if (!scp) |
731 | return -ENOMEM; | 503 | return -ENOMEM; |
732 | memset(scp, 0, sizeof(*scp)); | 504 | |
733 | scp->device = sdev; | 505 | scp->device = sdev; |
506 | memset(&cmndinfo, 0, sizeof(cmndinfo)); | ||
507 | |||
734 | /* use request field to save the ptr. to completion struct. */ | 508 | /* use request field to save the ptr. to completion struct. */ |
735 | scp->request = (struct request *)&wait; | 509 | scp->request = (struct request *)&wait; |
736 | scp->timeout_per_command = timeout*HZ; | 510 | scp->timeout_per_command = timeout*HZ; |
737 | scp->request_buffer = gdtcmd; | 511 | sg_init_one(&one_sg, gdtcmd, sizeof(*gdtcmd)); |
512 | gdth_set_sglist(scp, &one_sg); | ||
513 | gdth_set_sg_count(scp, 1); | ||
514 | gdth_set_bufflen(scp, sizeof(*gdtcmd)); | ||
738 | scp->cmd_len = 12; | 515 | scp->cmd_len = 12; |
739 | memcpy(scp->cmnd, cmnd, 12); | 516 | memcpy(scp->cmnd, cmnd, 12); |
740 | scp->SCp.this_residual = IOCTL_PRI; /* priority */ | 517 | cmndinfo.priority = IOCTL_PRI; |
741 | scp->done = gdth_scsi_done; /* some fn. test this */ | 518 | cmndinfo.internal_command = 1; |
742 | gdth_queuecommand(scp, gdth_scsi_done); | ||
743 | wait_for_completion(&wait); | ||
744 | |||
745 | rval = scp->SCp.Status; | ||
746 | if (info) | ||
747 | *info = scp->SCp.Message; | ||
748 | kfree(scp); | ||
749 | return rval; | ||
750 | } | ||
751 | #else | ||
752 | static void gdth_scsi_done(Scsi_Cmnd *scp) | ||
753 | { | ||
754 | TRACE2(("gdth_scsi_done()\n")); | ||
755 | |||
756 | scp->request.rq_status = RQ_SCSI_DONE; | ||
757 | if (scp->request.waiting) | ||
758 | complete(scp->request.waiting); | ||
759 | } | ||
760 | 519 | ||
761 | int __gdth_execute(struct scsi_device *sdev, gdth_cmd_str *gdtcmd, char *cmnd, | 520 | TRACE(("__gdth_execute() cmd 0x%x\n", scp->cmnd[0])); |
762 | int timeout, u32 *info) | 521 | __gdth_queuecommand(ha, scp, &cmndinfo); |
763 | { | ||
764 | Scsi_Cmnd *scp = scsi_allocate_device(sdev, 1, FALSE); | ||
765 | unsigned bufflen = gdtcmd ? sizeof(gdth_cmd_str) : 0; | ||
766 | DECLARE_COMPLETION_ONSTACK(wait); | ||
767 | int rval; | ||
768 | 522 | ||
769 | if (!scp) | ||
770 | return -ENOMEM; | ||
771 | scp->cmd_len = 12; | ||
772 | scp->use_sg = 0; | ||
773 | scp->SCp.this_residual = IOCTL_PRI; /* priority */ | ||
774 | scp->request.rq_status = RQ_SCSI_BUSY; | ||
775 | scp->request.waiting = &wait; | ||
776 | scsi_do_cmd(scp, cmnd, gdtcmd, bufflen, gdth_scsi_done, timeout*HZ, 1); | ||
777 | wait_for_completion(&wait); | 523 | wait_for_completion(&wait); |
778 | 524 | ||
779 | rval = scp->SCp.Status; | 525 | rval = cmndinfo.status; |
780 | if (info) | 526 | if (info) |
781 | *info = scp->SCp.Message; | 527 | *info = cmndinfo.info; |
782 | 528 | kfree(scp); | |
783 | scsi_release_command(scp); | ||
784 | return rval; | 529 | return rval; |
785 | } | 530 | } |
786 | #endif | ||
787 | 531 | ||
788 | int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd, | 532 | int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd, |
789 | int timeout, u32 *info) | 533 | int timeout, u32 *info) |
@@ -815,7 +559,7 @@ static void gdth_eval_mapping(ulong32 size, ulong32 *cyls, int *heads, int *secs | |||
815 | } | 559 | } |
816 | 560 | ||
817 | /* controller search and initialization functions */ | 561 | /* controller search and initialization functions */ |
818 | 562 | #ifdef CONFIG_EISA | |
819 | static int __init gdth_search_eisa(ushort eisa_adr) | 563 | static int __init gdth_search_eisa(ushort eisa_adr) |
820 | { | 564 | { |
821 | ulong32 id; | 565 | ulong32 id; |
@@ -832,8 +576,9 @@ static int __init gdth_search_eisa(ushort eisa_adr) | |||
832 | 576 | ||
833 | return 0; | 577 | return 0; |
834 | } | 578 | } |
579 | #endif /* CONFIG_EISA */ | ||
835 | 580 | ||
836 | 581 | #ifdef CONFIG_ISA | |
837 | static int __init gdth_search_isa(ulong32 bios_adr) | 582 | static int __init gdth_search_isa(ulong32 bios_adr) |
838 | { | 583 | { |
839 | void __iomem *addr; | 584 | void __iomem *addr; |
@@ -841,14 +586,18 @@ static int __init gdth_search_isa(ulong32 bios_adr) | |||
841 | 586 | ||
842 | TRACE(("gdth_search_isa() bios adr. %x\n",bios_adr)); | 587 | TRACE(("gdth_search_isa() bios adr. %x\n",bios_adr)); |
843 | if ((addr = ioremap(bios_adr+BIOS_ID_OFFS, sizeof(ulong32))) != NULL) { | 588 | if ((addr = ioremap(bios_adr+BIOS_ID_OFFS, sizeof(ulong32))) != NULL) { |
844 | id = gdth_readl(addr); | 589 | id = readl(addr); |
845 | iounmap(addr); | 590 | iounmap(addr); |
846 | if (id == GDT2_ID) /* GDT2000 */ | 591 | if (id == GDT2_ID) /* GDT2000 */ |
847 | return 1; | 592 | return 1; |
848 | } | 593 | } |
849 | return 0; | 594 | return 0; |
850 | } | 595 | } |
596 | #endif /* CONFIG_ISA */ | ||
851 | 597 | ||
598 | #ifdef CONFIG_PCI | ||
599 | static void gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, | ||
600 | ushort vendor, ushort dev); | ||
852 | 601 | ||
853 | static int __init gdth_search_pci(gdth_pci_str *pcistr) | 602 | static int __init gdth_search_pci(gdth_pci_str *pcistr) |
854 | { | 603 | { |
@@ -928,7 +677,6 @@ static void __init gdth_search_dev(gdth_pci_str *pcistr, ushort *cnt, | |||
928 | } | 677 | } |
929 | } | 678 | } |
930 | 679 | ||
931 | |||
932 | static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt) | 680 | static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt) |
933 | { | 681 | { |
934 | gdth_pci_str temp; | 682 | gdth_pci_str temp; |
@@ -965,8 +713,9 @@ static void __init gdth_sort_pci(gdth_pci_str *pcistr, int cnt) | |||
965 | } | 713 | } |
966 | } while (changed); | 714 | } while (changed); |
967 | } | 715 | } |
716 | #endif /* CONFIG_PCI */ | ||
968 | 717 | ||
969 | 718 | #ifdef CONFIG_EISA | |
970 | static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha) | 719 | static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha) |
971 | { | 720 | { |
972 | ulong32 retries,id; | 721 | ulong32 retries,id; |
@@ -1058,8 +807,9 @@ static int __init gdth_init_eisa(ushort eisa_adr,gdth_ha_str *ha) | |||
1058 | ha->dma64_support = 0; | 807 | ha->dma64_support = 0; |
1059 | return 1; | 808 | return 1; |
1060 | } | 809 | } |
810 | #endif /* CONFIG_EISA */ | ||
1061 | 811 | ||
1062 | 812 | #ifdef CONFIG_ISA | |
1063 | static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | 813 | static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) |
1064 | { | 814 | { |
1065 | register gdt2_dpram_str __iomem *dp2_ptr; | 815 | register gdt2_dpram_str __iomem *dp2_ptr; |
@@ -1075,22 +825,22 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | |||
1075 | return 0; | 825 | return 0; |
1076 | } | 826 | } |
1077 | dp2_ptr = ha->brd; | 827 | dp2_ptr = ha->brd; |
1078 | gdth_writeb(1, &dp2_ptr->io.memlock); /* switch off write protection */ | 828 | writeb(1, &dp2_ptr->io.memlock); /* switch off write protection */ |
1079 | /* reset interface area */ | 829 | /* reset interface area */ |
1080 | memset_io(&dp2_ptr->u, 0, sizeof(dp2_ptr->u)); | 830 | memset_io(&dp2_ptr->u, 0, sizeof(dp2_ptr->u)); |
1081 | if (gdth_readl(&dp2_ptr->u) != 0) { | 831 | if (readl(&dp2_ptr->u) != 0) { |
1082 | printk("GDT-ISA: Initialization error (DPMEM write error)\n"); | 832 | printk("GDT-ISA: Initialization error (DPMEM write error)\n"); |
1083 | iounmap(ha->brd); | 833 | iounmap(ha->brd); |
1084 | return 0; | 834 | return 0; |
1085 | } | 835 | } |
1086 | 836 | ||
1087 | /* disable board interrupts, read DRQ and IRQ */ | 837 | /* disable board interrupts, read DRQ and IRQ */ |
1088 | gdth_writeb(0xff, &dp2_ptr->io.irqdel); | 838 | writeb(0xff, &dp2_ptr->io.irqdel); |
1089 | gdth_writeb(0x00, &dp2_ptr->io.irqen); | 839 | writeb(0x00, &dp2_ptr->io.irqen); |
1090 | gdth_writeb(0x00, &dp2_ptr->u.ic.S_Status); | 840 | writeb(0x00, &dp2_ptr->u.ic.S_Status); |
1091 | gdth_writeb(0x00, &dp2_ptr->u.ic.Cmd_Index); | 841 | writeb(0x00, &dp2_ptr->u.ic.Cmd_Index); |
1092 | 842 | ||
1093 | irq_drq = gdth_readb(&dp2_ptr->io.rq); | 843 | irq_drq = readb(&dp2_ptr->io.rq); |
1094 | for (i=0; i<3; ++i) { | 844 | for (i=0; i<3; ++i) { |
1095 | if ((irq_drq & 1)==0) | 845 | if ((irq_drq & 1)==0) |
1096 | break; | 846 | break; |
@@ -1098,7 +848,7 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | |||
1098 | } | 848 | } |
1099 | ha->drq = gdth_drq_tab[i]; | 849 | ha->drq = gdth_drq_tab[i]; |
1100 | 850 | ||
1101 | irq_drq = gdth_readb(&dp2_ptr->io.rq) >> 3; | 851 | irq_drq = readb(&dp2_ptr->io.rq) >> 3; |
1102 | for (i=1; i<5; ++i) { | 852 | for (i=1; i<5; ++i) { |
1103 | if ((irq_drq & 1)==0) | 853 | if ((irq_drq & 1)==0) |
1104 | break; | 854 | break; |
@@ -1107,12 +857,12 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | |||
1107 | ha->irq = gdth_irq_tab[i]; | 857 | ha->irq = gdth_irq_tab[i]; |
1108 | 858 | ||
1109 | /* deinitialize services */ | 859 | /* deinitialize services */ |
1110 | gdth_writel(bios_adr, &dp2_ptr->u.ic.S_Info[0]); | 860 | writel(bios_adr, &dp2_ptr->u.ic.S_Info[0]); |
1111 | gdth_writeb(0xff, &dp2_ptr->u.ic.S_Cmd_Indx); | 861 | writeb(0xff, &dp2_ptr->u.ic.S_Cmd_Indx); |
1112 | gdth_writeb(0, &dp2_ptr->io.event); | 862 | writeb(0, &dp2_ptr->io.event); |
1113 | retries = INIT_RETRIES; | 863 | retries = INIT_RETRIES; |
1114 | gdth_delay(20); | 864 | gdth_delay(20); |
1115 | while (gdth_readb(&dp2_ptr->u.ic.S_Status) != 0xff) { | 865 | while (readb(&dp2_ptr->u.ic.S_Status) != 0xff) { |
1116 | if (--retries == 0) { | 866 | if (--retries == 0) { |
1117 | printk("GDT-ISA: Initialization error (DEINIT failed)\n"); | 867 | printk("GDT-ISA: Initialization error (DEINIT failed)\n"); |
1118 | iounmap(ha->brd); | 868 | iounmap(ha->brd); |
@@ -1120,9 +870,9 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | |||
1120 | } | 870 | } |
1121 | gdth_delay(1); | 871 | gdth_delay(1); |
1122 | } | 872 | } |
1123 | prot_ver = (unchar)gdth_readl(&dp2_ptr->u.ic.S_Info[0]); | 873 | prot_ver = (unchar)readl(&dp2_ptr->u.ic.S_Info[0]); |
1124 | gdth_writeb(0, &dp2_ptr->u.ic.Status); | 874 | writeb(0, &dp2_ptr->u.ic.Status); |
1125 | gdth_writeb(0xff, &dp2_ptr->io.irqdel); | 875 | writeb(0xff, &dp2_ptr->io.irqdel); |
1126 | if (prot_ver != PROTOCOL_VERSION) { | 876 | if (prot_ver != PROTOCOL_VERSION) { |
1127 | printk("GDT-ISA: Illegal protocol version\n"); | 877 | printk("GDT-ISA: Illegal protocol version\n"); |
1128 | iounmap(ha->brd); | 878 | iounmap(ha->brd); |
@@ -1136,15 +886,15 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | |||
1136 | ha->brd_phys = bios_adr >> 4; | 886 | ha->brd_phys = bios_adr >> 4; |
1137 | 887 | ||
1138 | /* special request to controller BIOS */ | 888 | /* special request to controller BIOS */ |
1139 | gdth_writel(0x00, &dp2_ptr->u.ic.S_Info[0]); | 889 | writel(0x00, &dp2_ptr->u.ic.S_Info[0]); |
1140 | gdth_writel(0x00, &dp2_ptr->u.ic.S_Info[1]); | 890 | writel(0x00, &dp2_ptr->u.ic.S_Info[1]); |
1141 | gdth_writel(0x01, &dp2_ptr->u.ic.S_Info[2]); | 891 | writel(0x01, &dp2_ptr->u.ic.S_Info[2]); |
1142 | gdth_writel(0x00, &dp2_ptr->u.ic.S_Info[3]); | 892 | writel(0x00, &dp2_ptr->u.ic.S_Info[3]); |
1143 | gdth_writeb(0xfe, &dp2_ptr->u.ic.S_Cmd_Indx); | 893 | writeb(0xfe, &dp2_ptr->u.ic.S_Cmd_Indx); |
1144 | gdth_writeb(0, &dp2_ptr->io.event); | 894 | writeb(0, &dp2_ptr->io.event); |
1145 | retries = INIT_RETRIES; | 895 | retries = INIT_RETRIES; |
1146 | gdth_delay(20); | 896 | gdth_delay(20); |
1147 | while (gdth_readb(&dp2_ptr->u.ic.S_Status) != 0xfe) { | 897 | while (readb(&dp2_ptr->u.ic.S_Status) != 0xfe) { |
1148 | if (--retries == 0) { | 898 | if (--retries == 0) { |
1149 | printk("GDT-ISA: Initialization error\n"); | 899 | printk("GDT-ISA: Initialization error\n"); |
1150 | iounmap(ha->brd); | 900 | iounmap(ha->brd); |
@@ -1152,14 +902,15 @@ static int __init gdth_init_isa(ulong32 bios_adr,gdth_ha_str *ha) | |||
1152 | } | 902 | } |
1153 | gdth_delay(1); | 903 | gdth_delay(1); |
1154 | } | 904 | } |
1155 | gdth_writeb(0, &dp2_ptr->u.ic.Status); | 905 | writeb(0, &dp2_ptr->u.ic.Status); |
1156 | gdth_writeb(0xff, &dp2_ptr->io.irqdel); | 906 | writeb(0xff, &dp2_ptr->io.irqdel); |
1157 | 907 | ||
1158 | ha->dma64_support = 0; | 908 | ha->dma64_support = 0; |
1159 | return 1; | 909 | return 1; |
1160 | } | 910 | } |
911 | #endif /* CONFIG_ISA */ | ||
1161 | 912 | ||
1162 | 913 | #ifdef CONFIG_PCI | |
1163 | static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | 914 | static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) |
1164 | { | 915 | { |
1165 | register gdt6_dpram_str __iomem *dp6_ptr; | 916 | register gdt6_dpram_str __iomem *dp6_ptr; |
@@ -1190,8 +941,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1190 | } | 941 | } |
1191 | /* check and reset interface area */ | 942 | /* check and reset interface area */ |
1192 | dp6_ptr = ha->brd; | 943 | dp6_ptr = ha->brd; |
1193 | gdth_writel(DPMEM_MAGIC, &dp6_ptr->u); | 944 | writel(DPMEM_MAGIC, &dp6_ptr->u); |
1194 | if (gdth_readl(&dp6_ptr->u) != DPMEM_MAGIC) { | 945 | if (readl(&dp6_ptr->u) != DPMEM_MAGIC) { |
1195 | printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", | 946 | printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", |
1196 | pcistr->dpmem); | 947 | pcistr->dpmem); |
1197 | found = FALSE; | 948 | found = FALSE; |
@@ -1202,7 +953,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1202 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); | 953 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); |
1203 | return 0; | 954 | return 0; |
1204 | } | 955 | } |
1205 | if (gdth_readw(ha->brd) != 0xffff) { | 956 | if (readw(ha->brd) != 0xffff) { |
1206 | TRACE2(("init_pci_old() address 0x%x busy\n", i)); | 957 | TRACE2(("init_pci_old() address 0x%x busy\n", i)); |
1207 | continue; | 958 | continue; |
1208 | } | 959 | } |
@@ -1215,8 +966,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1215 | return 0; | 966 | return 0; |
1216 | } | 967 | } |
1217 | dp6_ptr = ha->brd; | 968 | dp6_ptr = ha->brd; |
1218 | gdth_writel(DPMEM_MAGIC, &dp6_ptr->u); | 969 | writel(DPMEM_MAGIC, &dp6_ptr->u); |
1219 | if (gdth_readl(&dp6_ptr->u) == DPMEM_MAGIC) { | 970 | if (readl(&dp6_ptr->u) == DPMEM_MAGIC) { |
1220 | printk("GDT-PCI: Use free address at 0x%x\n", i); | 971 | printk("GDT-PCI: Use free address at 0x%x\n", i); |
1221 | found = TRUE; | 972 | found = TRUE; |
1222 | break; | 973 | break; |
@@ -1229,24 +980,24 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1229 | } | 980 | } |
1230 | } | 981 | } |
1231 | memset_io(&dp6_ptr->u, 0, sizeof(dp6_ptr->u)); | 982 | memset_io(&dp6_ptr->u, 0, sizeof(dp6_ptr->u)); |
1232 | if (gdth_readl(&dp6_ptr->u) != 0) { | 983 | if (readl(&dp6_ptr->u) != 0) { |
1233 | printk("GDT-PCI: Initialization error (DPMEM write error)\n"); | 984 | printk("GDT-PCI: Initialization error (DPMEM write error)\n"); |
1234 | iounmap(ha->brd); | 985 | iounmap(ha->brd); |
1235 | return 0; | 986 | return 0; |
1236 | } | 987 | } |
1237 | 988 | ||
1238 | /* disable board interrupts, deinit services */ | 989 | /* disable board interrupts, deinit services */ |
1239 | gdth_writeb(0xff, &dp6_ptr->io.irqdel); | 990 | writeb(0xff, &dp6_ptr->io.irqdel); |
1240 | gdth_writeb(0x00, &dp6_ptr->io.irqen); | 991 | writeb(0x00, &dp6_ptr->io.irqen); |
1241 | gdth_writeb(0x00, &dp6_ptr->u.ic.S_Status); | 992 | writeb(0x00, &dp6_ptr->u.ic.S_Status); |
1242 | gdth_writeb(0x00, &dp6_ptr->u.ic.Cmd_Index); | 993 | writeb(0x00, &dp6_ptr->u.ic.Cmd_Index); |
1243 | 994 | ||
1244 | gdth_writel(pcistr->dpmem, &dp6_ptr->u.ic.S_Info[0]); | 995 | writel(pcistr->dpmem, &dp6_ptr->u.ic.S_Info[0]); |
1245 | gdth_writeb(0xff, &dp6_ptr->u.ic.S_Cmd_Indx); | 996 | writeb(0xff, &dp6_ptr->u.ic.S_Cmd_Indx); |
1246 | gdth_writeb(0, &dp6_ptr->io.event); | 997 | writeb(0, &dp6_ptr->io.event); |
1247 | retries = INIT_RETRIES; | 998 | retries = INIT_RETRIES; |
1248 | gdth_delay(20); | 999 | gdth_delay(20); |
1249 | while (gdth_readb(&dp6_ptr->u.ic.S_Status) != 0xff) { | 1000 | while (readb(&dp6_ptr->u.ic.S_Status) != 0xff) { |
1250 | if (--retries == 0) { | 1001 | if (--retries == 0) { |
1251 | printk("GDT-PCI: Initialization error (DEINIT failed)\n"); | 1002 | printk("GDT-PCI: Initialization error (DEINIT failed)\n"); |
1252 | iounmap(ha->brd); | 1003 | iounmap(ha->brd); |
@@ -1254,9 +1005,9 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1254 | } | 1005 | } |
1255 | gdth_delay(1); | 1006 | gdth_delay(1); |
1256 | } | 1007 | } |
1257 | prot_ver = (unchar)gdth_readl(&dp6_ptr->u.ic.S_Info[0]); | 1008 | prot_ver = (unchar)readl(&dp6_ptr->u.ic.S_Info[0]); |
1258 | gdth_writeb(0, &dp6_ptr->u.ic.S_Status); | 1009 | writeb(0, &dp6_ptr->u.ic.S_Status); |
1259 | gdth_writeb(0xff, &dp6_ptr->io.irqdel); | 1010 | writeb(0xff, &dp6_ptr->io.irqdel); |
1260 | if (prot_ver != PROTOCOL_VERSION) { | 1011 | if (prot_ver != PROTOCOL_VERSION) { |
1261 | printk("GDT-PCI: Illegal protocol version\n"); | 1012 | printk("GDT-PCI: Illegal protocol version\n"); |
1262 | iounmap(ha->brd); | 1013 | iounmap(ha->brd); |
@@ -1267,15 +1018,15 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1267 | ha->ic_all_size = sizeof(dp6_ptr->u); | 1018 | ha->ic_all_size = sizeof(dp6_ptr->u); |
1268 | 1019 | ||
1269 | /* special command to controller BIOS */ | 1020 | /* special command to controller BIOS */ |
1270 | gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[0]); | 1021 | writel(0x00, &dp6_ptr->u.ic.S_Info[0]); |
1271 | gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[1]); | 1022 | writel(0x00, &dp6_ptr->u.ic.S_Info[1]); |
1272 | gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[2]); | 1023 | writel(0x00, &dp6_ptr->u.ic.S_Info[2]); |
1273 | gdth_writel(0x00, &dp6_ptr->u.ic.S_Info[3]); | 1024 | writel(0x00, &dp6_ptr->u.ic.S_Info[3]); |
1274 | gdth_writeb(0xfe, &dp6_ptr->u.ic.S_Cmd_Indx); | 1025 | writeb(0xfe, &dp6_ptr->u.ic.S_Cmd_Indx); |
1275 | gdth_writeb(0, &dp6_ptr->io.event); | 1026 | writeb(0, &dp6_ptr->io.event); |
1276 | retries = INIT_RETRIES; | 1027 | retries = INIT_RETRIES; |
1277 | gdth_delay(20); | 1028 | gdth_delay(20); |
1278 | while (gdth_readb(&dp6_ptr->u.ic.S_Status) != 0xfe) { | 1029 | while (readb(&dp6_ptr->u.ic.S_Status) != 0xfe) { |
1279 | if (--retries == 0) { | 1030 | if (--retries == 0) { |
1280 | printk("GDT-PCI: Initialization error\n"); | 1031 | printk("GDT-PCI: Initialization error\n"); |
1281 | iounmap(ha->brd); | 1032 | iounmap(ha->brd); |
@@ -1283,8 +1034,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1283 | } | 1034 | } |
1284 | gdth_delay(1); | 1035 | gdth_delay(1); |
1285 | } | 1036 | } |
1286 | gdth_writeb(0, &dp6_ptr->u.ic.S_Status); | 1037 | writeb(0, &dp6_ptr->u.ic.S_Status); |
1287 | gdth_writeb(0xff, &dp6_ptr->io.irqdel); | 1038 | writeb(0xff, &dp6_ptr->io.irqdel); |
1288 | 1039 | ||
1289 | ha->dma64_support = 0; | 1040 | ha->dma64_support = 0; |
1290 | 1041 | ||
@@ -1300,8 +1051,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1300 | } | 1051 | } |
1301 | /* check and reset interface area */ | 1052 | /* check and reset interface area */ |
1302 | dp6c_ptr = ha->brd; | 1053 | dp6c_ptr = ha->brd; |
1303 | gdth_writel(DPMEM_MAGIC, &dp6c_ptr->u); | 1054 | writel(DPMEM_MAGIC, &dp6c_ptr->u); |
1304 | if (gdth_readl(&dp6c_ptr->u) != DPMEM_MAGIC) { | 1055 | if (readl(&dp6c_ptr->u) != DPMEM_MAGIC) { |
1305 | printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", | 1056 | printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", |
1306 | pcistr->dpmem); | 1057 | pcistr->dpmem); |
1307 | found = FALSE; | 1058 | found = FALSE; |
@@ -1312,7 +1063,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1312 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); | 1063 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); |
1313 | return 0; | 1064 | return 0; |
1314 | } | 1065 | } |
1315 | if (gdth_readw(ha->brd) != 0xffff) { | 1066 | if (readw(ha->brd) != 0xffff) { |
1316 | TRACE2(("init_pci_plx() address 0x%x busy\n", i)); | 1067 | TRACE2(("init_pci_plx() address 0x%x busy\n", i)); |
1317 | continue; | 1068 | continue; |
1318 | } | 1069 | } |
@@ -1325,8 +1076,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1325 | return 0; | 1076 | return 0; |
1326 | } | 1077 | } |
1327 | dp6c_ptr = ha->brd; | 1078 | dp6c_ptr = ha->brd; |
1328 | gdth_writel(DPMEM_MAGIC, &dp6c_ptr->u); | 1079 | writel(DPMEM_MAGIC, &dp6c_ptr->u); |
1329 | if (gdth_readl(&dp6c_ptr->u) == DPMEM_MAGIC) { | 1080 | if (readl(&dp6c_ptr->u) == DPMEM_MAGIC) { |
1330 | printk("GDT-PCI: Use free address at 0x%x\n", i); | 1081 | printk("GDT-PCI: Use free address at 0x%x\n", i); |
1331 | found = TRUE; | 1082 | found = TRUE; |
1332 | break; | 1083 | break; |
@@ -1339,7 +1090,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1339 | } | 1090 | } |
1340 | } | 1091 | } |
1341 | memset_io(&dp6c_ptr->u, 0, sizeof(dp6c_ptr->u)); | 1092 | memset_io(&dp6c_ptr->u, 0, sizeof(dp6c_ptr->u)); |
1342 | if (gdth_readl(&dp6c_ptr->u) != 0) { | 1093 | if (readl(&dp6c_ptr->u) != 0) { |
1343 | printk("GDT-PCI: Initialization error (DPMEM write error)\n"); | 1094 | printk("GDT-PCI: Initialization error (DPMEM write error)\n"); |
1344 | iounmap(ha->brd); | 1095 | iounmap(ha->brd); |
1345 | return 0; | 1096 | return 0; |
@@ -1349,17 +1100,17 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1349 | outb(0x00,PTR2USHORT(&ha->plx->control1)); | 1100 | outb(0x00,PTR2USHORT(&ha->plx->control1)); |
1350 | outb(0xff,PTR2USHORT(&ha->plx->edoor_reg)); | 1101 | outb(0xff,PTR2USHORT(&ha->plx->edoor_reg)); |
1351 | 1102 | ||
1352 | gdth_writeb(0x00, &dp6c_ptr->u.ic.S_Status); | 1103 | writeb(0x00, &dp6c_ptr->u.ic.S_Status); |
1353 | gdth_writeb(0x00, &dp6c_ptr->u.ic.Cmd_Index); | 1104 | writeb(0x00, &dp6c_ptr->u.ic.Cmd_Index); |
1354 | 1105 | ||
1355 | gdth_writel(pcistr->dpmem, &dp6c_ptr->u.ic.S_Info[0]); | 1106 | writel(pcistr->dpmem, &dp6c_ptr->u.ic.S_Info[0]); |
1356 | gdth_writeb(0xff, &dp6c_ptr->u.ic.S_Cmd_Indx); | 1107 | writeb(0xff, &dp6c_ptr->u.ic.S_Cmd_Indx); |
1357 | 1108 | ||
1358 | outb(1,PTR2USHORT(&ha->plx->ldoor_reg)); | 1109 | outb(1,PTR2USHORT(&ha->plx->ldoor_reg)); |
1359 | 1110 | ||
1360 | retries = INIT_RETRIES; | 1111 | retries = INIT_RETRIES; |
1361 | gdth_delay(20); | 1112 | gdth_delay(20); |
1362 | while (gdth_readb(&dp6c_ptr->u.ic.S_Status) != 0xff) { | 1113 | while (readb(&dp6c_ptr->u.ic.S_Status) != 0xff) { |
1363 | if (--retries == 0) { | 1114 | if (--retries == 0) { |
1364 | printk("GDT-PCI: Initialization error (DEINIT failed)\n"); | 1115 | printk("GDT-PCI: Initialization error (DEINIT failed)\n"); |
1365 | iounmap(ha->brd); | 1116 | iounmap(ha->brd); |
@@ -1367,8 +1118,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1367 | } | 1118 | } |
1368 | gdth_delay(1); | 1119 | gdth_delay(1); |
1369 | } | 1120 | } |
1370 | prot_ver = (unchar)gdth_readl(&dp6c_ptr->u.ic.S_Info[0]); | 1121 | prot_ver = (unchar)readl(&dp6c_ptr->u.ic.S_Info[0]); |
1371 | gdth_writeb(0, &dp6c_ptr->u.ic.Status); | 1122 | writeb(0, &dp6c_ptr->u.ic.Status); |
1372 | if (prot_ver != PROTOCOL_VERSION) { | 1123 | if (prot_ver != PROTOCOL_VERSION) { |
1373 | printk("GDT-PCI: Illegal protocol version\n"); | 1124 | printk("GDT-PCI: Illegal protocol version\n"); |
1374 | iounmap(ha->brd); | 1125 | iounmap(ha->brd); |
@@ -1379,17 +1130,17 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1379 | ha->ic_all_size = sizeof(dp6c_ptr->u); | 1130 | ha->ic_all_size = sizeof(dp6c_ptr->u); |
1380 | 1131 | ||
1381 | /* special command to controller BIOS */ | 1132 | /* special command to controller BIOS */ |
1382 | gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[0]); | 1133 | writel(0x00, &dp6c_ptr->u.ic.S_Info[0]); |
1383 | gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[1]); | 1134 | writel(0x00, &dp6c_ptr->u.ic.S_Info[1]); |
1384 | gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[2]); | 1135 | writel(0x00, &dp6c_ptr->u.ic.S_Info[2]); |
1385 | gdth_writel(0x00, &dp6c_ptr->u.ic.S_Info[3]); | 1136 | writel(0x00, &dp6c_ptr->u.ic.S_Info[3]); |
1386 | gdth_writeb(0xfe, &dp6c_ptr->u.ic.S_Cmd_Indx); | 1137 | writeb(0xfe, &dp6c_ptr->u.ic.S_Cmd_Indx); |
1387 | 1138 | ||
1388 | outb(1,PTR2USHORT(&ha->plx->ldoor_reg)); | 1139 | outb(1,PTR2USHORT(&ha->plx->ldoor_reg)); |
1389 | 1140 | ||
1390 | retries = INIT_RETRIES; | 1141 | retries = INIT_RETRIES; |
1391 | gdth_delay(20); | 1142 | gdth_delay(20); |
1392 | while (gdth_readb(&dp6c_ptr->u.ic.S_Status) != 0xfe) { | 1143 | while (readb(&dp6c_ptr->u.ic.S_Status) != 0xfe) { |
1393 | if (--retries == 0) { | 1144 | if (--retries == 0) { |
1394 | printk("GDT-PCI: Initialization error\n"); | 1145 | printk("GDT-PCI: Initialization error\n"); |
1395 | iounmap(ha->brd); | 1146 | iounmap(ha->brd); |
@@ -1397,7 +1148,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1397 | } | 1148 | } |
1398 | gdth_delay(1); | 1149 | gdth_delay(1); |
1399 | } | 1150 | } |
1400 | gdth_writeb(0, &dp6c_ptr->u.ic.S_Status); | 1151 | writeb(0, &dp6c_ptr->u.ic.S_Status); |
1401 | 1152 | ||
1402 | ha->dma64_support = 0; | 1153 | ha->dma64_support = 0; |
1403 | 1154 | ||
@@ -1425,12 +1176,12 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1425 | 1176 | ||
1426 | /* Ensure that it is safe to access the non HW portions of DPMEM. | 1177 | /* Ensure that it is safe to access the non HW portions of DPMEM. |
1427 | * Aditional check needed for Xscale based RAID controllers */ | 1178 | * Aditional check needed for Xscale based RAID controllers */ |
1428 | while( ((int)gdth_readb(&dp6m_ptr->i960r.sema0_reg) ) & 3 ) | 1179 | while( ((int)readb(&dp6m_ptr->i960r.sema0_reg) ) & 3 ) |
1429 | gdth_delay(1); | 1180 | gdth_delay(1); |
1430 | 1181 | ||
1431 | /* check and reset interface area */ | 1182 | /* check and reset interface area */ |
1432 | gdth_writel(DPMEM_MAGIC, &dp6m_ptr->u); | 1183 | writel(DPMEM_MAGIC, &dp6m_ptr->u); |
1433 | if (gdth_readl(&dp6m_ptr->u) != DPMEM_MAGIC) { | 1184 | if (readl(&dp6m_ptr->u) != DPMEM_MAGIC) { |
1434 | printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", | 1185 | printk("GDT-PCI: Cannot access DPMEM at 0x%lx (shadowed?)\n", |
1435 | pcistr->dpmem); | 1186 | pcistr->dpmem); |
1436 | found = FALSE; | 1187 | found = FALSE; |
@@ -1441,7 +1192,7 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1441 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); | 1192 | printk("GDT-PCI: Initialization error (DPMEM remap error)\n"); |
1442 | return 0; | 1193 | return 0; |
1443 | } | 1194 | } |
1444 | if (gdth_readw(ha->brd) != 0xffff) { | 1195 | if (readw(ha->brd) != 0xffff) { |
1445 | TRACE2(("init_pci_mpr() address 0x%x busy\n", i)); | 1196 | TRACE2(("init_pci_mpr() address 0x%x busy\n", i)); |
1446 | continue; | 1197 | continue; |
1447 | } | 1198 | } |
@@ -1454,8 +1205,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1454 | return 0; | 1205 | return 0; |
1455 | } | 1206 | } |
1456 | dp6m_ptr = ha->brd; | 1207 | dp6m_ptr = ha->brd; |
1457 | gdth_writel(DPMEM_MAGIC, &dp6m_ptr->u); | 1208 | writel(DPMEM_MAGIC, &dp6m_ptr->u); |
1458 | if (gdth_readl(&dp6m_ptr->u) == DPMEM_MAGIC) { | 1209 | if (readl(&dp6m_ptr->u) == DPMEM_MAGIC) { |
1459 | printk("GDT-PCI: Use free address at 0x%x\n", i); | 1210 | printk("GDT-PCI: Use free address at 0x%x\n", i); |
1460 | found = TRUE; | 1211 | found = TRUE; |
1461 | break; | 1212 | break; |
@@ -1470,18 +1221,18 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1470 | memset_io(&dp6m_ptr->u, 0, sizeof(dp6m_ptr->u)); | 1221 | memset_io(&dp6m_ptr->u, 0, sizeof(dp6m_ptr->u)); |
1471 | 1222 | ||
1472 | /* disable board interrupts, deinit services */ | 1223 | /* disable board interrupts, deinit services */ |
1473 | gdth_writeb(gdth_readb(&dp6m_ptr->i960r.edoor_en_reg) | 4, | 1224 | writeb(readb(&dp6m_ptr->i960r.edoor_en_reg) | 4, |
1474 | &dp6m_ptr->i960r.edoor_en_reg); | 1225 | &dp6m_ptr->i960r.edoor_en_reg); |
1475 | gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg); | 1226 | writeb(0xff, &dp6m_ptr->i960r.edoor_reg); |
1476 | gdth_writeb(0x00, &dp6m_ptr->u.ic.S_Status); | 1227 | writeb(0x00, &dp6m_ptr->u.ic.S_Status); |
1477 | gdth_writeb(0x00, &dp6m_ptr->u.ic.Cmd_Index); | 1228 | writeb(0x00, &dp6m_ptr->u.ic.Cmd_Index); |
1478 | 1229 | ||
1479 | gdth_writel(pcistr->dpmem, &dp6m_ptr->u.ic.S_Info[0]); | 1230 | writel(pcistr->dpmem, &dp6m_ptr->u.ic.S_Info[0]); |
1480 | gdth_writeb(0xff, &dp6m_ptr->u.ic.S_Cmd_Indx); | 1231 | writeb(0xff, &dp6m_ptr->u.ic.S_Cmd_Indx); |
1481 | gdth_writeb(1, &dp6m_ptr->i960r.ldoor_reg); | 1232 | writeb(1, &dp6m_ptr->i960r.ldoor_reg); |
1482 | retries = INIT_RETRIES; | 1233 | retries = INIT_RETRIES; |
1483 | gdth_delay(20); | 1234 | gdth_delay(20); |
1484 | while (gdth_readb(&dp6m_ptr->u.ic.S_Status) != 0xff) { | 1235 | while (readb(&dp6m_ptr->u.ic.S_Status) != 0xff) { |
1485 | if (--retries == 0) { | 1236 | if (--retries == 0) { |
1486 | printk("GDT-PCI: Initialization error (DEINIT failed)\n"); | 1237 | printk("GDT-PCI: Initialization error (DEINIT failed)\n"); |
1487 | iounmap(ha->brd); | 1238 | iounmap(ha->brd); |
@@ -1489,8 +1240,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1489 | } | 1240 | } |
1490 | gdth_delay(1); | 1241 | gdth_delay(1); |
1491 | } | 1242 | } |
1492 | prot_ver = (unchar)gdth_readl(&dp6m_ptr->u.ic.S_Info[0]); | 1243 | prot_ver = (unchar)readl(&dp6m_ptr->u.ic.S_Info[0]); |
1493 | gdth_writeb(0, &dp6m_ptr->u.ic.S_Status); | 1244 | writeb(0, &dp6m_ptr->u.ic.S_Status); |
1494 | if (prot_ver != PROTOCOL_VERSION) { | 1245 | if (prot_ver != PROTOCOL_VERSION) { |
1495 | printk("GDT-PCI: Illegal protocol version\n"); | 1246 | printk("GDT-PCI: Illegal protocol version\n"); |
1496 | iounmap(ha->brd); | 1247 | iounmap(ha->brd); |
@@ -1501,15 +1252,15 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1501 | ha->ic_all_size = sizeof(dp6m_ptr->u); | 1252 | ha->ic_all_size = sizeof(dp6m_ptr->u); |
1502 | 1253 | ||
1503 | /* special command to controller BIOS */ | 1254 | /* special command to controller BIOS */ |
1504 | gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[0]); | 1255 | writel(0x00, &dp6m_ptr->u.ic.S_Info[0]); |
1505 | gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[1]); | 1256 | writel(0x00, &dp6m_ptr->u.ic.S_Info[1]); |
1506 | gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[2]); | 1257 | writel(0x00, &dp6m_ptr->u.ic.S_Info[2]); |
1507 | gdth_writel(0x00, &dp6m_ptr->u.ic.S_Info[3]); | 1258 | writel(0x00, &dp6m_ptr->u.ic.S_Info[3]); |
1508 | gdth_writeb(0xfe, &dp6m_ptr->u.ic.S_Cmd_Indx); | 1259 | writeb(0xfe, &dp6m_ptr->u.ic.S_Cmd_Indx); |
1509 | gdth_writeb(1, &dp6m_ptr->i960r.ldoor_reg); | 1260 | writeb(1, &dp6m_ptr->i960r.ldoor_reg); |
1510 | retries = INIT_RETRIES; | 1261 | retries = INIT_RETRIES; |
1511 | gdth_delay(20); | 1262 | gdth_delay(20); |
1512 | while (gdth_readb(&dp6m_ptr->u.ic.S_Status) != 0xfe) { | 1263 | while (readb(&dp6m_ptr->u.ic.S_Status) != 0xfe) { |
1513 | if (--retries == 0) { | 1264 | if (--retries == 0) { |
1514 | printk("GDT-PCI: Initialization error\n"); | 1265 | printk("GDT-PCI: Initialization error\n"); |
1515 | iounmap(ha->brd); | 1266 | iounmap(ha->brd); |
@@ -1517,14 +1268,14 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1517 | } | 1268 | } |
1518 | gdth_delay(1); | 1269 | gdth_delay(1); |
1519 | } | 1270 | } |
1520 | gdth_writeb(0, &dp6m_ptr->u.ic.S_Status); | 1271 | writeb(0, &dp6m_ptr->u.ic.S_Status); |
1521 | 1272 | ||
1522 | /* read FW version to detect 64-bit DMA support */ | 1273 | /* read FW version to detect 64-bit DMA support */ |
1523 | gdth_writeb(0xfd, &dp6m_ptr->u.ic.S_Cmd_Indx); | 1274 | writeb(0xfd, &dp6m_ptr->u.ic.S_Cmd_Indx); |
1524 | gdth_writeb(1, &dp6m_ptr->i960r.ldoor_reg); | 1275 | writeb(1, &dp6m_ptr->i960r.ldoor_reg); |
1525 | retries = INIT_RETRIES; | 1276 | retries = INIT_RETRIES; |
1526 | gdth_delay(20); | 1277 | gdth_delay(20); |
1527 | while (gdth_readb(&dp6m_ptr->u.ic.S_Status) != 0xfd) { | 1278 | while (readb(&dp6m_ptr->u.ic.S_Status) != 0xfd) { |
1528 | if (--retries == 0) { | 1279 | if (--retries == 0) { |
1529 | printk("GDT-PCI: Initialization error (DEINIT failed)\n"); | 1280 | printk("GDT-PCI: Initialization error (DEINIT failed)\n"); |
1530 | iounmap(ha->brd); | 1281 | iounmap(ha->brd); |
@@ -1532,8 +1283,8 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1532 | } | 1283 | } |
1533 | gdth_delay(1); | 1284 | gdth_delay(1); |
1534 | } | 1285 | } |
1535 | prot_ver = (unchar)(gdth_readl(&dp6m_ptr->u.ic.S_Info[0]) >> 16); | 1286 | prot_ver = (unchar)(readl(&dp6m_ptr->u.ic.S_Info[0]) >> 16); |
1536 | gdth_writeb(0, &dp6m_ptr->u.ic.S_Status); | 1287 | writeb(0, &dp6m_ptr->u.ic.S_Status); |
1537 | if (prot_ver < 0x2b) /* FW < x.43: no 64-bit DMA support */ | 1288 | if (prot_ver < 0x2b) /* FW < x.43: no 64-bit DMA support */ |
1538 | ha->dma64_support = 0; | 1289 | ha->dma64_support = 0; |
1539 | else | 1290 | else |
@@ -1542,20 +1293,18 @@ static int __init gdth_init_pci(gdth_pci_str *pcistr,gdth_ha_str *ha) | |||
1542 | 1293 | ||
1543 | return 1; | 1294 | return 1; |
1544 | } | 1295 | } |
1545 | 1296 | #endif /* CONFIG_PCI */ | |
1546 | 1297 | ||
1547 | /* controller protocol functions */ | 1298 | /* controller protocol functions */ |
1548 | 1299 | ||
1549 | static void __init gdth_enable_int(int hanum) | 1300 | static void __init gdth_enable_int(gdth_ha_str *ha) |
1550 | { | 1301 | { |
1551 | gdth_ha_str *ha; | ||
1552 | ulong flags; | 1302 | ulong flags; |
1553 | gdt2_dpram_str __iomem *dp2_ptr; | 1303 | gdt2_dpram_str __iomem *dp2_ptr; |
1554 | gdt6_dpram_str __iomem *dp6_ptr; | 1304 | gdt6_dpram_str __iomem *dp6_ptr; |
1555 | gdt6m_dpram_str __iomem *dp6m_ptr; | 1305 | gdt6m_dpram_str __iomem *dp6m_ptr; |
1556 | 1306 | ||
1557 | TRACE(("gdth_enable_int() hanum %d\n",hanum)); | 1307 | TRACE(("gdth_enable_int() hanum %d\n",ha->hanum)); |
1558 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1559 | spin_lock_irqsave(&ha->smp_lock, flags); | 1308 | spin_lock_irqsave(&ha->smp_lock, flags); |
1560 | 1309 | ||
1561 | if (ha->type == GDT_EISA) { | 1310 | if (ha->type == GDT_EISA) { |
@@ -1564,93 +1313,80 @@ static void __init gdth_enable_int(int hanum) | |||
1564 | outb(0x01, ha->bmic + EINTENABREG); | 1313 | outb(0x01, ha->bmic + EINTENABREG); |
1565 | } else if (ha->type == GDT_ISA) { | 1314 | } else if (ha->type == GDT_ISA) { |
1566 | dp2_ptr = ha->brd; | 1315 | dp2_ptr = ha->brd; |
1567 | gdth_writeb(1, &dp2_ptr->io.irqdel); | 1316 | writeb(1, &dp2_ptr->io.irqdel); |
1568 | gdth_writeb(0, &dp2_ptr->u.ic.Cmd_Index); | 1317 | writeb(0, &dp2_ptr->u.ic.Cmd_Index); |
1569 | gdth_writeb(1, &dp2_ptr->io.irqen); | 1318 | writeb(1, &dp2_ptr->io.irqen); |
1570 | } else if (ha->type == GDT_PCI) { | 1319 | } else if (ha->type == GDT_PCI) { |
1571 | dp6_ptr = ha->brd; | 1320 | dp6_ptr = ha->brd; |
1572 | gdth_writeb(1, &dp6_ptr->io.irqdel); | 1321 | writeb(1, &dp6_ptr->io.irqdel); |
1573 | gdth_writeb(0, &dp6_ptr->u.ic.Cmd_Index); | 1322 | writeb(0, &dp6_ptr->u.ic.Cmd_Index); |
1574 | gdth_writeb(1, &dp6_ptr->io.irqen); | 1323 | writeb(1, &dp6_ptr->io.irqen); |
1575 | } else if (ha->type == GDT_PCINEW) { | 1324 | } else if (ha->type == GDT_PCINEW) { |
1576 | outb(0xff, PTR2USHORT(&ha->plx->edoor_reg)); | 1325 | outb(0xff, PTR2USHORT(&ha->plx->edoor_reg)); |
1577 | outb(0x03, PTR2USHORT(&ha->plx->control1)); | 1326 | outb(0x03, PTR2USHORT(&ha->plx->control1)); |
1578 | } else if (ha->type == GDT_PCIMPR) { | 1327 | } else if (ha->type == GDT_PCIMPR) { |
1579 | dp6m_ptr = ha->brd; | 1328 | dp6m_ptr = ha->brd; |
1580 | gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg); | 1329 | writeb(0xff, &dp6m_ptr->i960r.edoor_reg); |
1581 | gdth_writeb(gdth_readb(&dp6m_ptr->i960r.edoor_en_reg) & ~4, | 1330 | writeb(readb(&dp6m_ptr->i960r.edoor_en_reg) & ~4, |
1582 | &dp6m_ptr->i960r.edoor_en_reg); | 1331 | &dp6m_ptr->i960r.edoor_en_reg); |
1583 | } | 1332 | } |
1584 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 1333 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
1585 | } | 1334 | } |
1586 | 1335 | ||
1587 | 1336 | /* return IStatus if interrupt was from this card else 0 */ | |
1588 | static int gdth_get_status(unchar *pIStatus,int irq) | 1337 | static unchar gdth_get_status(gdth_ha_str *ha, int irq) |
1589 | { | 1338 | { |
1590 | register gdth_ha_str *ha; | 1339 | unchar IStatus = 0; |
1591 | int i; | 1340 | |
1341 | TRACE(("gdth_get_status() irq %d ctr_count %d\n", irq, gdth_ctr_count)); | ||
1592 | 1342 | ||
1593 | TRACE(("gdth_get_status() irq %d ctr_count %d\n", | ||
1594 | irq,gdth_ctr_count)); | ||
1595 | |||
1596 | *pIStatus = 0; | ||
1597 | for (i=0; i<gdth_ctr_count; ++i) { | ||
1598 | ha = HADATA(gdth_ctr_tab[i]); | ||
1599 | if (ha->irq != (unchar)irq) /* check IRQ */ | 1343 | if (ha->irq != (unchar)irq) /* check IRQ */ |
1600 | continue; | 1344 | return false; |
1601 | if (ha->type == GDT_EISA) | 1345 | if (ha->type == GDT_EISA) |
1602 | *pIStatus = inb((ushort)ha->bmic + EDOORREG); | 1346 | IStatus = inb((ushort)ha->bmic + EDOORREG); |
1603 | else if (ha->type == GDT_ISA) | 1347 | else if (ha->type == GDT_ISA) |
1604 | *pIStatus = | 1348 | IStatus = |
1605 | gdth_readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index); | 1349 | readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index); |
1606 | else if (ha->type == GDT_PCI) | 1350 | else if (ha->type == GDT_PCI) |
1607 | *pIStatus = | 1351 | IStatus = |
1608 | gdth_readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index); | 1352 | readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Cmd_Index); |
1609 | else if (ha->type == GDT_PCINEW) | 1353 | else if (ha->type == GDT_PCINEW) |
1610 | *pIStatus = inb(PTR2USHORT(&ha->plx->edoor_reg)); | 1354 | IStatus = inb(PTR2USHORT(&ha->plx->edoor_reg)); |
1611 | else if (ha->type == GDT_PCIMPR) | 1355 | else if (ha->type == GDT_PCIMPR) |
1612 | *pIStatus = | 1356 | IStatus = |
1613 | gdth_readb(&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.edoor_reg); | 1357 | readb(&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.edoor_reg); |
1614 | 1358 | ||
1615 | if (*pIStatus) | 1359 | return IStatus; |
1616 | return i; /* board found */ | ||
1617 | } | ||
1618 | return -1; | ||
1619 | } | 1360 | } |
1620 | 1361 | ||
1621 | 1362 | static int gdth_test_busy(gdth_ha_str *ha) | |
1622 | static int gdth_test_busy(int hanum) | ||
1623 | { | 1363 | { |
1624 | register gdth_ha_str *ha; | ||
1625 | register int gdtsema0 = 0; | 1364 | register int gdtsema0 = 0; |
1626 | 1365 | ||
1627 | TRACE(("gdth_test_busy() hanum %d\n",hanum)); | 1366 | TRACE(("gdth_test_busy() hanum %d\n", ha->hanum)); |
1628 | 1367 | ||
1629 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1630 | if (ha->type == GDT_EISA) | 1368 | if (ha->type == GDT_EISA) |
1631 | gdtsema0 = (int)inb(ha->bmic + SEMA0REG); | 1369 | gdtsema0 = (int)inb(ha->bmic + SEMA0REG); |
1632 | else if (ha->type == GDT_ISA) | 1370 | else if (ha->type == GDT_ISA) |
1633 | gdtsema0 = (int)gdth_readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Sema0); | 1371 | gdtsema0 = (int)readb(&((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Sema0); |
1634 | else if (ha->type == GDT_PCI) | 1372 | else if (ha->type == GDT_PCI) |
1635 | gdtsema0 = (int)gdth_readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0); | 1373 | gdtsema0 = (int)readb(&((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0); |
1636 | else if (ha->type == GDT_PCINEW) | 1374 | else if (ha->type == GDT_PCINEW) |
1637 | gdtsema0 = (int)inb(PTR2USHORT(&ha->plx->sema0_reg)); | 1375 | gdtsema0 = (int)inb(PTR2USHORT(&ha->plx->sema0_reg)); |
1638 | else if (ha->type == GDT_PCIMPR) | 1376 | else if (ha->type == GDT_PCIMPR) |
1639 | gdtsema0 = | 1377 | gdtsema0 = |
1640 | (int)gdth_readb(&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.sema0_reg); | 1378 | (int)readb(&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.sema0_reg); |
1641 | 1379 | ||
1642 | return (gdtsema0 & 1); | 1380 | return (gdtsema0 & 1); |
1643 | } | 1381 | } |
1644 | 1382 | ||
1645 | 1383 | ||
1646 | static int gdth_get_cmd_index(int hanum) | 1384 | static int gdth_get_cmd_index(gdth_ha_str *ha) |
1647 | { | 1385 | { |
1648 | register gdth_ha_str *ha; | ||
1649 | int i; | 1386 | int i; |
1650 | 1387 | ||
1651 | TRACE(("gdth_get_cmd_index() hanum %d\n",hanum)); | 1388 | TRACE(("gdth_get_cmd_index() hanum %d\n", ha->hanum)); |
1652 | 1389 | ||
1653 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1654 | for (i=0; i<GDTH_MAXCMDS; ++i) { | 1390 | for (i=0; i<GDTH_MAXCMDS; ++i) { |
1655 | if (ha->cmd_tab[i].cmnd == UNUSED_CMND) { | 1391 | if (ha->cmd_tab[i].cmnd == UNUSED_CMND) { |
1656 | ha->cmd_tab[i].cmnd = ha->pccb->RequestBuffer; | 1392 | ha->cmd_tab[i].cmnd = ha->pccb->RequestBuffer; |
@@ -1663,30 +1399,26 @@ static int gdth_get_cmd_index(int hanum) | |||
1663 | } | 1399 | } |
1664 | 1400 | ||
1665 | 1401 | ||
1666 | static void gdth_set_sema0(int hanum) | 1402 | static void gdth_set_sema0(gdth_ha_str *ha) |
1667 | { | 1403 | { |
1668 | register gdth_ha_str *ha; | 1404 | TRACE(("gdth_set_sema0() hanum %d\n", ha->hanum)); |
1669 | 1405 | ||
1670 | TRACE(("gdth_set_sema0() hanum %d\n",hanum)); | ||
1671 | |||
1672 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1673 | if (ha->type == GDT_EISA) { | 1406 | if (ha->type == GDT_EISA) { |
1674 | outb(1, ha->bmic + SEMA0REG); | 1407 | outb(1, ha->bmic + SEMA0REG); |
1675 | } else if (ha->type == GDT_ISA) { | 1408 | } else if (ha->type == GDT_ISA) { |
1676 | gdth_writeb(1, &((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Sema0); | 1409 | writeb(1, &((gdt2_dpram_str __iomem *)ha->brd)->u.ic.Sema0); |
1677 | } else if (ha->type == GDT_PCI) { | 1410 | } else if (ha->type == GDT_PCI) { |
1678 | gdth_writeb(1, &((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0); | 1411 | writeb(1, &((gdt6_dpram_str __iomem *)ha->brd)->u.ic.Sema0); |
1679 | } else if (ha->type == GDT_PCINEW) { | 1412 | } else if (ha->type == GDT_PCINEW) { |
1680 | outb(1, PTR2USHORT(&ha->plx->sema0_reg)); | 1413 | outb(1, PTR2USHORT(&ha->plx->sema0_reg)); |
1681 | } else if (ha->type == GDT_PCIMPR) { | 1414 | } else if (ha->type == GDT_PCIMPR) { |
1682 | gdth_writeb(1, &((gdt6m_dpram_str __iomem *)ha->brd)->i960r.sema0_reg); | 1415 | writeb(1, &((gdt6m_dpram_str __iomem *)ha->brd)->i960r.sema0_reg); |
1683 | } | 1416 | } |
1684 | } | 1417 | } |
1685 | 1418 | ||
1686 | 1419 | ||
1687 | static void gdth_copy_command(int hanum) | 1420 | static void gdth_copy_command(gdth_ha_str *ha) |
1688 | { | 1421 | { |
1689 | register gdth_ha_str *ha; | ||
1690 | register gdth_cmd_str *cmd_ptr; | 1422 | register gdth_cmd_str *cmd_ptr; |
1691 | register gdt6m_dpram_str __iomem *dp6m_ptr; | 1423 | register gdt6m_dpram_str __iomem *dp6m_ptr; |
1692 | register gdt6c_dpram_str __iomem *dp6c_ptr; | 1424 | register gdt6c_dpram_str __iomem *dp6c_ptr; |
@@ -1694,9 +1426,8 @@ static void gdth_copy_command(int hanum) | |||
1694 | gdt2_dpram_str __iomem *dp2_ptr; | 1426 | gdt2_dpram_str __iomem *dp2_ptr; |
1695 | ushort cp_count,dp_offset,cmd_no; | 1427 | ushort cp_count,dp_offset,cmd_no; |
1696 | 1428 | ||
1697 | TRACE(("gdth_copy_command() hanum %d\n",hanum)); | 1429 | TRACE(("gdth_copy_command() hanum %d\n", ha->hanum)); |
1698 | 1430 | ||
1699 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1700 | cp_count = ha->cmd_len; | 1431 | cp_count = ha->cmd_len; |
1701 | dp_offset= ha->cmd_offs_dpmem; | 1432 | dp_offset= ha->cmd_offs_dpmem; |
1702 | cmd_no = ha->cmd_cnt; | 1433 | cmd_no = ha->cmd_cnt; |
@@ -1715,42 +1446,39 @@ static void gdth_copy_command(int hanum) | |||
1715 | /* set offset and service, copy command to DPMEM */ | 1446 | /* set offset and service, copy command to DPMEM */ |
1716 | if (ha->type == GDT_ISA) { | 1447 | if (ha->type == GDT_ISA) { |
1717 | dp2_ptr = ha->brd; | 1448 | dp2_ptr = ha->brd; |
1718 | gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, | 1449 | writew(dp_offset + DPMEM_COMMAND_OFFSET, |
1719 | &dp2_ptr->u.ic.comm_queue[cmd_no].offset); | 1450 | &dp2_ptr->u.ic.comm_queue[cmd_no].offset); |
1720 | gdth_writew((ushort)cmd_ptr->Service, | 1451 | writew((ushort)cmd_ptr->Service, |
1721 | &dp2_ptr->u.ic.comm_queue[cmd_no].serv_id); | 1452 | &dp2_ptr->u.ic.comm_queue[cmd_no].serv_id); |
1722 | memcpy_toio(&dp2_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); | 1453 | memcpy_toio(&dp2_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); |
1723 | } else if (ha->type == GDT_PCI) { | 1454 | } else if (ha->type == GDT_PCI) { |
1724 | dp6_ptr = ha->brd; | 1455 | dp6_ptr = ha->brd; |
1725 | gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, | 1456 | writew(dp_offset + DPMEM_COMMAND_OFFSET, |
1726 | &dp6_ptr->u.ic.comm_queue[cmd_no].offset); | 1457 | &dp6_ptr->u.ic.comm_queue[cmd_no].offset); |
1727 | gdth_writew((ushort)cmd_ptr->Service, | 1458 | writew((ushort)cmd_ptr->Service, |
1728 | &dp6_ptr->u.ic.comm_queue[cmd_no].serv_id); | 1459 | &dp6_ptr->u.ic.comm_queue[cmd_no].serv_id); |
1729 | memcpy_toio(&dp6_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); | 1460 | memcpy_toio(&dp6_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); |
1730 | } else if (ha->type == GDT_PCINEW) { | 1461 | } else if (ha->type == GDT_PCINEW) { |
1731 | dp6c_ptr = ha->brd; | 1462 | dp6c_ptr = ha->brd; |
1732 | gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, | 1463 | writew(dp_offset + DPMEM_COMMAND_OFFSET, |
1733 | &dp6c_ptr->u.ic.comm_queue[cmd_no].offset); | 1464 | &dp6c_ptr->u.ic.comm_queue[cmd_no].offset); |
1734 | gdth_writew((ushort)cmd_ptr->Service, | 1465 | writew((ushort)cmd_ptr->Service, |
1735 | &dp6c_ptr->u.ic.comm_queue[cmd_no].serv_id); | 1466 | &dp6c_ptr->u.ic.comm_queue[cmd_no].serv_id); |
1736 | memcpy_toio(&dp6c_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); | 1467 | memcpy_toio(&dp6c_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); |
1737 | } else if (ha->type == GDT_PCIMPR) { | 1468 | } else if (ha->type == GDT_PCIMPR) { |
1738 | dp6m_ptr = ha->brd; | 1469 | dp6m_ptr = ha->brd; |
1739 | gdth_writew(dp_offset + DPMEM_COMMAND_OFFSET, | 1470 | writew(dp_offset + DPMEM_COMMAND_OFFSET, |
1740 | &dp6m_ptr->u.ic.comm_queue[cmd_no].offset); | 1471 | &dp6m_ptr->u.ic.comm_queue[cmd_no].offset); |
1741 | gdth_writew((ushort)cmd_ptr->Service, | 1472 | writew((ushort)cmd_ptr->Service, |
1742 | &dp6m_ptr->u.ic.comm_queue[cmd_no].serv_id); | 1473 | &dp6m_ptr->u.ic.comm_queue[cmd_no].serv_id); |
1743 | memcpy_toio(&dp6m_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); | 1474 | memcpy_toio(&dp6m_ptr->u.ic.gdt_dpr_cmd[dp_offset],cmd_ptr,cp_count); |
1744 | } | 1475 | } |
1745 | } | 1476 | } |
1746 | 1477 | ||
1747 | 1478 | ||
1748 | static void gdth_release_event(int hanum) | 1479 | static void gdth_release_event(gdth_ha_str *ha) |
1749 | { | 1480 | { |
1750 | register gdth_ha_str *ha; | 1481 | TRACE(("gdth_release_event() hanum %d\n", ha->hanum)); |
1751 | |||
1752 | TRACE(("gdth_release_event() hanum %d\n",hanum)); | ||
1753 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1754 | 1482 | ||
1755 | #ifdef GDTH_STATISTICS | 1483 | #ifdef GDTH_STATISTICS |
1756 | { | 1484 | { |
@@ -1774,56 +1502,50 @@ static void gdth_release_event(int hanum) | |||
1774 | outl(ha->ccb_phys, ha->bmic + MAILBOXREG); | 1502 | outl(ha->ccb_phys, ha->bmic + MAILBOXREG); |
1775 | outb(ha->pccb->Service, ha->bmic + LDOORREG); | 1503 | outb(ha->pccb->Service, ha->bmic + LDOORREG); |
1776 | } else if (ha->type == GDT_ISA) { | 1504 | } else if (ha->type == GDT_ISA) { |
1777 | gdth_writeb(0, &((gdt2_dpram_str __iomem *)ha->brd)->io.event); | 1505 | writeb(0, &((gdt2_dpram_str __iomem *)ha->brd)->io.event); |
1778 | } else if (ha->type == GDT_PCI) { | 1506 | } else if (ha->type == GDT_PCI) { |
1779 | gdth_writeb(0, &((gdt6_dpram_str __iomem *)ha->brd)->io.event); | 1507 | writeb(0, &((gdt6_dpram_str __iomem *)ha->brd)->io.event); |
1780 | } else if (ha->type == GDT_PCINEW) { | 1508 | } else if (ha->type == GDT_PCINEW) { |
1781 | outb(1, PTR2USHORT(&ha->plx->ldoor_reg)); | 1509 | outb(1, PTR2USHORT(&ha->plx->ldoor_reg)); |
1782 | } else if (ha->type == GDT_PCIMPR) { | 1510 | } else if (ha->type == GDT_PCIMPR) { |
1783 | gdth_writeb(1, &((gdt6m_dpram_str __iomem *)ha->brd)->i960r.ldoor_reg); | 1511 | writeb(1, &((gdt6m_dpram_str __iomem *)ha->brd)->i960r.ldoor_reg); |
1784 | } | 1512 | } |
1785 | } | 1513 | } |
1786 | 1514 | ||
1787 | 1515 | static int gdth_wait(gdth_ha_str *ha, int index, ulong32 time) | |
1788 | static int gdth_wait(int hanum,int index,ulong32 time) | ||
1789 | { | 1516 | { |
1790 | gdth_ha_str *ha; | ||
1791 | int answer_found = FALSE; | 1517 | int answer_found = FALSE; |
1518 | int wait_index = 0; | ||
1792 | 1519 | ||
1793 | TRACE(("gdth_wait() hanum %d index %d time %d\n",hanum,index,time)); | 1520 | TRACE(("gdth_wait() hanum %d index %d time %d\n", ha->hanum, index, time)); |
1794 | 1521 | ||
1795 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1796 | if (index == 0) | 1522 | if (index == 0) |
1797 | return 1; /* no wait required */ | 1523 | return 1; /* no wait required */ |
1798 | 1524 | ||
1799 | gdth_from_wait = TRUE; | ||
1800 | do { | 1525 | do { |
1801 | gdth_interrupt((int)ha->irq,ha); | 1526 | __gdth_interrupt(ha, (int)ha->irq, true, &wait_index); |
1802 | if (wait_hanum==hanum && wait_index==index) { | 1527 | if (wait_index == index) { |
1803 | answer_found = TRUE; | 1528 | answer_found = TRUE; |
1804 | break; | 1529 | break; |
1805 | } | 1530 | } |
1806 | gdth_delay(1); | 1531 | gdth_delay(1); |
1807 | } while (--time); | 1532 | } while (--time); |
1808 | gdth_from_wait = FALSE; | 1533 | |
1809 | 1534 | while (gdth_test_busy(ha)) | |
1810 | while (gdth_test_busy(hanum)) | ||
1811 | gdth_delay(0); | 1535 | gdth_delay(0); |
1812 | 1536 | ||
1813 | return (answer_found); | 1537 | return (answer_found); |
1814 | } | 1538 | } |
1815 | 1539 | ||
1816 | 1540 | ||
1817 | static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, | 1541 | static int gdth_internal_cmd(gdth_ha_str *ha, unchar service, ushort opcode, |
1818 | ulong64 p2,ulong64 p3) | 1542 | ulong32 p1, ulong64 p2, ulong64 p3) |
1819 | { | 1543 | { |
1820 | register gdth_ha_str *ha; | ||
1821 | register gdth_cmd_str *cmd_ptr; | 1544 | register gdth_cmd_str *cmd_ptr; |
1822 | int retries,index; | 1545 | int retries,index; |
1823 | 1546 | ||
1824 | TRACE2(("gdth_internal_cmd() service %d opcode %d\n",service,opcode)); | 1547 | TRACE2(("gdth_internal_cmd() service %d opcode %d\n",service,opcode)); |
1825 | 1548 | ||
1826 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1827 | cmd_ptr = ha->pccb; | 1549 | cmd_ptr = ha->pccb; |
1828 | memset((char*)cmd_ptr,0,sizeof(gdth_cmd_str)); | 1550 | memset((char*)cmd_ptr,0,sizeof(gdth_cmd_str)); |
1829 | 1551 | ||
@@ -1831,11 +1553,11 @@ static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, | |||
1831 | for (retries = INIT_RETRIES;;) { | 1553 | for (retries = INIT_RETRIES;;) { |
1832 | cmd_ptr->Service = service; | 1554 | cmd_ptr->Service = service; |
1833 | cmd_ptr->RequestBuffer = INTERNAL_CMND; | 1555 | cmd_ptr->RequestBuffer = INTERNAL_CMND; |
1834 | if (!(index=gdth_get_cmd_index(hanum))) { | 1556 | if (!(index=gdth_get_cmd_index(ha))) { |
1835 | TRACE(("GDT: No free command index found\n")); | 1557 | TRACE(("GDT: No free command index found\n")); |
1836 | return 0; | 1558 | return 0; |
1837 | } | 1559 | } |
1838 | gdth_set_sema0(hanum); | 1560 | gdth_set_sema0(ha); |
1839 | cmd_ptr->OpCode = opcode; | 1561 | cmd_ptr->OpCode = opcode; |
1840 | cmd_ptr->BoardNode = LOCALBOARD; | 1562 | cmd_ptr->BoardNode = LOCALBOARD; |
1841 | if (service == CACHESERVICE) { | 1563 | if (service == CACHESERVICE) { |
@@ -1875,10 +1597,10 @@ static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, | |||
1875 | ha->cmd_len = sizeof(gdth_cmd_str); | 1597 | ha->cmd_len = sizeof(gdth_cmd_str); |
1876 | ha->cmd_offs_dpmem = 0; | 1598 | ha->cmd_offs_dpmem = 0; |
1877 | ha->cmd_cnt = 0; | 1599 | ha->cmd_cnt = 0; |
1878 | gdth_copy_command(hanum); | 1600 | gdth_copy_command(ha); |
1879 | gdth_release_event(hanum); | 1601 | gdth_release_event(ha); |
1880 | gdth_delay(20); | 1602 | gdth_delay(20); |
1881 | if (!gdth_wait(hanum,index,INIT_TIMEOUT)) { | 1603 | if (!gdth_wait(ha, index, INIT_TIMEOUT)) { |
1882 | printk("GDT: Initialization error (timeout service %d)\n",service); | 1604 | printk("GDT: Initialization error (timeout service %d)\n",service); |
1883 | return 0; | 1605 | return 0; |
1884 | } | 1606 | } |
@@ -1893,9 +1615,8 @@ static int gdth_internal_cmd(int hanum,unchar service,ushort opcode,ulong32 p1, | |||
1893 | 1615 | ||
1894 | /* search for devices */ | 1616 | /* search for devices */ |
1895 | 1617 | ||
1896 | static int __init gdth_search_drives(int hanum) | 1618 | static int __init gdth_search_drives(gdth_ha_str *ha) |
1897 | { | 1619 | { |
1898 | register gdth_ha_str *ha; | ||
1899 | ushort cdev_cnt, i; | 1620 | ushort cdev_cnt, i; |
1900 | int ok; | 1621 | int ok; |
1901 | ulong32 bus_no, drv_cnt, drv_no, j; | 1622 | ulong32 bus_no, drv_cnt, drv_no, j; |
@@ -1915,22 +1636,21 @@ static int __init gdth_search_drives(int hanum) | |||
1915 | ulong flags; | 1636 | ulong flags; |
1916 | #endif | 1637 | #endif |
1917 | 1638 | ||
1918 | TRACE(("gdth_search_drives() hanum %d\n",hanum)); | 1639 | TRACE(("gdth_search_drives() hanum %d\n", ha->hanum)); |
1919 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
1920 | ok = 0; | 1640 | ok = 0; |
1921 | 1641 | ||
1922 | /* initialize controller services, at first: screen service */ | 1642 | /* initialize controller services, at first: screen service */ |
1923 | ha->screen_feat = 0; | 1643 | ha->screen_feat = 0; |
1924 | if (!force_dma32) { | 1644 | if (!force_dma32) { |
1925 | ok = gdth_internal_cmd(hanum,SCREENSERVICE,GDT_X_INIT_SCR,0,0,0); | 1645 | ok = gdth_internal_cmd(ha, SCREENSERVICE, GDT_X_INIT_SCR, 0, 0, 0); |
1926 | if (ok) | 1646 | if (ok) |
1927 | ha->screen_feat = GDT_64BIT; | 1647 | ha->screen_feat = GDT_64BIT; |
1928 | } | 1648 | } |
1929 | if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) | 1649 | if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) |
1930 | ok = gdth_internal_cmd(hanum,SCREENSERVICE,GDT_INIT,0,0,0); | 1650 | ok = gdth_internal_cmd(ha, SCREENSERVICE, GDT_INIT, 0, 0, 0); |
1931 | if (!ok) { | 1651 | if (!ok) { |
1932 | printk("GDT-HA %d: Initialization error screen service (code %d)\n", | 1652 | printk("GDT-HA %d: Initialization error screen service (code %d)\n", |
1933 | hanum, ha->status); | 1653 | ha->hanum, ha->status); |
1934 | return 0; | 1654 | return 0; |
1935 | } | 1655 | } |
1936 | TRACE2(("gdth_search_drives(): SCREENSERVICE initialized\n")); | 1656 | TRACE2(("gdth_search_drives(): SCREENSERVICE initialized\n")); |
@@ -1954,25 +1674,26 @@ static int __init gdth_search_drives(int hanum) | |||
1954 | TRACE2(("gdth_search_drives(): RTC: %x/%x/%x\n",*(ulong32 *)&rtc[0], | 1674 | TRACE2(("gdth_search_drives(): RTC: %x/%x/%x\n",*(ulong32 *)&rtc[0], |
1955 | *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8])); | 1675 | *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8])); |
1956 | /* 3. send to controller firmware */ | 1676 | /* 3. send to controller firmware */ |
1957 | gdth_internal_cmd(hanum,SCREENSERVICE,GDT_REALTIME, *(ulong32 *)&rtc[0], | 1677 | gdth_internal_cmd(ha, SCREENSERVICE, GDT_REALTIME, *(ulong32 *)&rtc[0], |
1958 | *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]); | 1678 | *(ulong32 *)&rtc[4], *(ulong32 *)&rtc[8]); |
1959 | #endif | 1679 | #endif |
1960 | 1680 | ||
1961 | /* unfreeze all IOs */ | 1681 | /* unfreeze all IOs */ |
1962 | gdth_internal_cmd(hanum,CACHESERVICE,GDT_UNFREEZE_IO,0,0,0); | 1682 | gdth_internal_cmd(ha, CACHESERVICE, GDT_UNFREEZE_IO, 0, 0, 0); |
1963 | 1683 | ||
1964 | /* initialize cache service */ | 1684 | /* initialize cache service */ |
1965 | ha->cache_feat = 0; | 1685 | ha->cache_feat = 0; |
1966 | if (!force_dma32) { | 1686 | if (!force_dma32) { |
1967 | ok = gdth_internal_cmd(hanum,CACHESERVICE,GDT_X_INIT_HOST,LINUX_OS,0,0); | 1687 | ok = gdth_internal_cmd(ha, CACHESERVICE, GDT_X_INIT_HOST, LINUX_OS, |
1688 | 0, 0); | ||
1968 | if (ok) | 1689 | if (ok) |
1969 | ha->cache_feat = GDT_64BIT; | 1690 | ha->cache_feat = GDT_64BIT; |
1970 | } | 1691 | } |
1971 | if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) | 1692 | if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) |
1972 | ok = gdth_internal_cmd(hanum,CACHESERVICE,GDT_INIT,LINUX_OS,0,0); | 1693 | ok = gdth_internal_cmd(ha, CACHESERVICE, GDT_INIT, LINUX_OS, 0, 0); |
1973 | if (!ok) { | 1694 | if (!ok) { |
1974 | printk("GDT-HA %d: Initialization error cache service (code %d)\n", | 1695 | printk("GDT-HA %d: Initialization error cache service (code %d)\n", |
1975 | hanum, ha->status); | 1696 | ha->hanum, ha->status); |
1976 | return 0; | 1697 | return 0; |
1977 | } | 1698 | } |
1978 | TRACE2(("gdth_search_drives(): CACHESERVICE initialized\n")); | 1699 | TRACE2(("gdth_search_drives(): CACHESERVICE initialized\n")); |
@@ -2001,9 +1722,9 @@ static int __init gdth_search_drives(int hanum) | |||
2001 | pmod->cmd_buff_size = 0; | 1722 | pmod->cmd_buff_size = 0; |
2002 | pmod->reserved1 = 0; | 1723 | pmod->reserved1 = 0; |
2003 | pmod->reserved2 = 0; | 1724 | pmod->reserved2 = 0; |
2004 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,SET_PERF_MODES, | 1725 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, SET_PERF_MODES, |
2005 | INVALID_CHANNEL,sizeof(gdth_perf_modes))) { | 1726 | INVALID_CHANNEL,sizeof(gdth_perf_modes))) { |
2006 | printk("GDT-HA %d: Interrupt coalescing activated\n", hanum); | 1727 | printk("GDT-HA %d: Interrupt coalescing activated\n", ha->hanum); |
2007 | } | 1728 | } |
2008 | } | 1729 | } |
2009 | #endif | 1730 | #endif |
@@ -2015,7 +1736,7 @@ static int __init gdth_search_drives(int hanum) | |||
2015 | iocr->hdr.first_chan = 0; | 1736 | iocr->hdr.first_chan = 0; |
2016 | iocr->hdr.last_chan = MAXBUS-1; | 1737 | iocr->hdr.last_chan = MAXBUS-1; |
2017 | iocr->hdr.list_offset = GDTOFFSOF(gdth_raw_iochan_str, list[0]); | 1738 | iocr->hdr.list_offset = GDTOFFSOF(gdth_raw_iochan_str, list[0]); |
2018 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,IOCHAN_RAW_DESC, | 1739 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, IOCHAN_RAW_DESC, |
2019 | INVALID_CHANNEL,sizeof(gdth_raw_iochan_str))) { | 1740 | INVALID_CHANNEL,sizeof(gdth_raw_iochan_str))) { |
2020 | TRACE2(("IOCHAN_RAW_DESC supported!\n")); | 1741 | TRACE2(("IOCHAN_RAW_DESC supported!\n")); |
2021 | ha->bus_cnt = iocr->hdr.chan_count; | 1742 | ha->bus_cnt = iocr->hdr.chan_count; |
@@ -2030,13 +1751,13 @@ static int __init gdth_search_drives(int hanum) | |||
2030 | chn = (gdth_getch_str *)ha->pscratch; | 1751 | chn = (gdth_getch_str *)ha->pscratch; |
2031 | for (bus_no = 0; bus_no < MAXBUS; ++bus_no) { | 1752 | for (bus_no = 0; bus_no < MAXBUS; ++bus_no) { |
2032 | chn->channel_no = bus_no; | 1753 | chn->channel_no = bus_no; |
2033 | if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, | 1754 | if (!gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, |
2034 | SCSI_CHAN_CNT | L_CTRL_PATTERN, | 1755 | SCSI_CHAN_CNT | L_CTRL_PATTERN, |
2035 | IO_CHANNEL | INVALID_CHANNEL, | 1756 | IO_CHANNEL | INVALID_CHANNEL, |
2036 | sizeof(gdth_getch_str))) { | 1757 | sizeof(gdth_getch_str))) { |
2037 | if (bus_no == 0) { | 1758 | if (bus_no == 0) { |
2038 | printk("GDT-HA %d: Error detecting channel count (0x%x)\n", | 1759 | printk("GDT-HA %d: Error detecting channel count (0x%x)\n", |
2039 | hanum, ha->status); | 1760 | ha->hanum, ha->status); |
2040 | return 0; | 1761 | return 0; |
2041 | } | 1762 | } |
2042 | break; | 1763 | break; |
@@ -2051,10 +1772,10 @@ static int __init gdth_search_drives(int hanum) | |||
2051 | TRACE2(("gdth_search_drives() %d channels\n",ha->bus_cnt)); | 1772 | TRACE2(("gdth_search_drives() %d channels\n",ha->bus_cnt)); |
2052 | 1773 | ||
2053 | /* read cache configuration */ | 1774 | /* read cache configuration */ |
2054 | if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,CACHE_INFO, | 1775 | if (!gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_INFO, |
2055 | INVALID_CHANNEL,sizeof(gdth_cinfo_str))) { | 1776 | INVALID_CHANNEL,sizeof(gdth_cinfo_str))) { |
2056 | printk("GDT-HA %d: Initialization error cache service (code %d)\n", | 1777 | printk("GDT-HA %d: Initialization error cache service (code %d)\n", |
2057 | hanum, ha->status); | 1778 | ha->hanum, ha->status); |
2058 | return 0; | 1779 | return 0; |
2059 | } | 1780 | } |
2060 | ha->cpar = ((gdth_cinfo_str *)ha->pscratch)->cpar; | 1781 | ha->cpar = ((gdth_cinfo_str *)ha->pscratch)->cpar; |
@@ -2064,11 +1785,11 @@ static int __init gdth_search_drives(int hanum) | |||
2064 | 1785 | ||
2065 | /* read board info and features */ | 1786 | /* read board info and features */ |
2066 | ha->more_proc = FALSE; | 1787 | ha->more_proc = FALSE; |
2067 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,BOARD_INFO, | 1788 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, BOARD_INFO, |
2068 | INVALID_CHANNEL,sizeof(gdth_binfo_str))) { | 1789 | INVALID_CHANNEL,sizeof(gdth_binfo_str))) { |
2069 | memcpy(&ha->binfo, (gdth_binfo_str *)ha->pscratch, | 1790 | memcpy(&ha->binfo, (gdth_binfo_str *)ha->pscratch, |
2070 | sizeof(gdth_binfo_str)); | 1791 | sizeof(gdth_binfo_str)); |
2071 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,BOARD_FEATURES, | 1792 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, BOARD_FEATURES, |
2072 | INVALID_CHANNEL,sizeof(gdth_bfeat_str))) { | 1793 | INVALID_CHANNEL,sizeof(gdth_bfeat_str))) { |
2073 | TRACE2(("BOARD_INFO/BOARD_FEATURES supported\n")); | 1794 | TRACE2(("BOARD_INFO/BOARD_FEATURES supported\n")); |
2074 | ha->bfeat = *(gdth_bfeat_str *)ha->pscratch; | 1795 | ha->bfeat = *(gdth_bfeat_str *)ha->pscratch; |
@@ -2076,7 +1797,7 @@ static int __init gdth_search_drives(int hanum) | |||
2076 | } | 1797 | } |
2077 | } else { | 1798 | } else { |
2078 | TRACE2(("BOARD_INFO requires firmware >= 1.10/2.08\n")); | 1799 | TRACE2(("BOARD_INFO requires firmware >= 1.10/2.08\n")); |
2079 | strcpy(ha->binfo.type_string, gdth_ctr_name(hanum)); | 1800 | strcpy(ha->binfo.type_string, gdth_ctr_name(ha)); |
2080 | } | 1801 | } |
2081 | TRACE2(("Controller name: %s\n",ha->binfo.type_string)); | 1802 | TRACE2(("Controller name: %s\n",ha->binfo.type_string)); |
2082 | 1803 | ||
@@ -2089,7 +1810,7 @@ static int __init gdth_search_drives(int hanum) | |||
2089 | ioc->hdr.first_chan = 0; | 1810 | ioc->hdr.first_chan = 0; |
2090 | ioc->hdr.last_chan = MAXBUS-1; | 1811 | ioc->hdr.last_chan = MAXBUS-1; |
2091 | ioc->hdr.list_offset = GDTOFFSOF(gdth_iochan_str, list[0]); | 1812 | ioc->hdr.list_offset = GDTOFFSOF(gdth_iochan_str, list[0]); |
2092 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,IOCHAN_DESC, | 1813 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, IOCHAN_DESC, |
2093 | INVALID_CHANNEL,sizeof(gdth_iochan_str))) { | 1814 | INVALID_CHANNEL,sizeof(gdth_iochan_str))) { |
2094 | for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { | 1815 | for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { |
2095 | ha->raw[bus_no].address = ioc->list[bus_no].address; | 1816 | ha->raw[bus_no].address = ioc->list[bus_no].address; |
@@ -2104,7 +1825,7 @@ static int __init gdth_search_drives(int hanum) | |||
2104 | for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { | 1825 | for (bus_no = 0; bus_no < ha->bus_cnt; ++bus_no) { |
2105 | chn = (gdth_getch_str *)ha->pscratch; | 1826 | chn = (gdth_getch_str *)ha->pscratch; |
2106 | chn->channel_no = ha->raw[bus_no].local_no; | 1827 | chn->channel_no = ha->raw[bus_no].local_no; |
2107 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, | 1828 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, |
2108 | SCSI_CHAN_CNT | L_CTRL_PATTERN, | 1829 | SCSI_CHAN_CNT | L_CTRL_PATTERN, |
2109 | ha->raw[bus_no].address | INVALID_CHANNEL, | 1830 | ha->raw[bus_no].address | INVALID_CHANNEL, |
2110 | sizeof(gdth_getch_str))) { | 1831 | sizeof(gdth_getch_str))) { |
@@ -2116,7 +1837,7 @@ static int __init gdth_search_drives(int hanum) | |||
2116 | drl = (gdth_drlist_str *)ha->pscratch; | 1837 | drl = (gdth_drlist_str *)ha->pscratch; |
2117 | drl->sc_no = ha->raw[bus_no].local_no; | 1838 | drl->sc_no = ha->raw[bus_no].local_no; |
2118 | drl->sc_cnt = ha->raw[bus_no].pdev_cnt; | 1839 | drl->sc_cnt = ha->raw[bus_no].pdev_cnt; |
2119 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, | 1840 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, |
2120 | SCSI_DR_LIST | L_CTRL_PATTERN, | 1841 | SCSI_DR_LIST | L_CTRL_PATTERN, |
2121 | ha->raw[bus_no].address | INVALID_CHANNEL, | 1842 | ha->raw[bus_no].address | INVALID_CHANNEL, |
2122 | sizeof(gdth_drlist_str))) { | 1843 | sizeof(gdth_drlist_str))) { |
@@ -2129,10 +1850,10 @@ static int __init gdth_search_drives(int hanum) | |||
2129 | } | 1850 | } |
2130 | 1851 | ||
2131 | /* logical drives */ | 1852 | /* logical drives */ |
2132 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,CACHE_DRV_CNT, | 1853 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_DRV_CNT, |
2133 | INVALID_CHANNEL,sizeof(ulong32))) { | 1854 | INVALID_CHANNEL,sizeof(ulong32))) { |
2134 | drv_cnt = *(ulong32 *)ha->pscratch; | 1855 | drv_cnt = *(ulong32 *)ha->pscratch; |
2135 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL,CACHE_DRV_LIST, | 1856 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, CACHE_DRV_LIST, |
2136 | INVALID_CHANNEL,drv_cnt * sizeof(ulong32))) { | 1857 | INVALID_CHANNEL,drv_cnt * sizeof(ulong32))) { |
2137 | for (j = 0; j < drv_cnt; ++j) { | 1858 | for (j = 0; j < drv_cnt; ++j) { |
2138 | drv_no = ((ulong32 *)ha->pscratch)[j]; | 1859 | drv_no = ((ulong32 *)ha->pscratch)[j]; |
@@ -2146,7 +1867,7 @@ static int __init gdth_search_drives(int hanum) | |||
2146 | alst->entries_avail = MAX_LDRIVES; | 1867 | alst->entries_avail = MAX_LDRIVES; |
2147 | alst->first_entry = 0; | 1868 | alst->first_entry = 0; |
2148 | alst->list_offset = GDTOFFSOF(gdth_arcdl_str, list[0]); | 1869 | alst->list_offset = GDTOFFSOF(gdth_arcdl_str, list[0]); |
2149 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, | 1870 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, |
2150 | ARRAY_DRV_LIST2 | LA_CTRL_PATTERN, | 1871 | ARRAY_DRV_LIST2 | LA_CTRL_PATTERN, |
2151 | INVALID_CHANNEL, sizeof(gdth_arcdl_str) + | 1872 | INVALID_CHANNEL, sizeof(gdth_arcdl_str) + |
2152 | (alst->entries_avail-1) * sizeof(gdth_alist_str))) { | 1873 | (alst->entries_avail-1) * sizeof(gdth_alist_str))) { |
@@ -2157,7 +1878,7 @@ static int __init gdth_search_drives(int hanum) | |||
2157 | ha->hdr[j].is_hotfix = alst->list[j].is_hotfix; | 1878 | ha->hdr[j].is_hotfix = alst->list[j].is_hotfix; |
2158 | ha->hdr[j].master_no = alst->list[j].cd_handle; | 1879 | ha->hdr[j].master_no = alst->list[j].cd_handle; |
2159 | } | 1880 | } |
2160 | } else if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, | 1881 | } else if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, |
2161 | ARRAY_DRV_LIST | LA_CTRL_PATTERN, | 1882 | ARRAY_DRV_LIST | LA_CTRL_PATTERN, |
2162 | 0, 35 * sizeof(gdth_alist_str))) { | 1883 | 0, 35 * sizeof(gdth_alist_str))) { |
2163 | for (j = 0; j < 35; ++j) { | 1884 | for (j = 0; j < 35; ++j) { |
@@ -2175,24 +1896,24 @@ static int __init gdth_search_drives(int hanum) | |||
2175 | /* initialize raw service */ | 1896 | /* initialize raw service */ |
2176 | ha->raw_feat = 0; | 1897 | ha->raw_feat = 0; |
2177 | if (!force_dma32) { | 1898 | if (!force_dma32) { |
2178 | ok = gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_X_INIT_RAW,0,0,0); | 1899 | ok = gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_X_INIT_RAW, 0, 0, 0); |
2179 | if (ok) | 1900 | if (ok) |
2180 | ha->raw_feat = GDT_64BIT; | 1901 | ha->raw_feat = GDT_64BIT; |
2181 | } | 1902 | } |
2182 | if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) | 1903 | if (force_dma32 || (!ok && ha->status == (ushort)S_NOFUNC)) |
2183 | ok = gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_INIT,0,0,0); | 1904 | ok = gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_INIT, 0, 0, 0); |
2184 | if (!ok) { | 1905 | if (!ok) { |
2185 | printk("GDT-HA %d: Initialization error raw service (code %d)\n", | 1906 | printk("GDT-HA %d: Initialization error raw service (code %d)\n", |
2186 | hanum, ha->status); | 1907 | ha->hanum, ha->status); |
2187 | return 0; | 1908 | return 0; |
2188 | } | 1909 | } |
2189 | TRACE2(("gdth_search_drives(): RAWSERVICE initialized\n")); | 1910 | TRACE2(("gdth_search_drives(): RAWSERVICE initialized\n")); |
2190 | 1911 | ||
2191 | /* set/get features raw service (scatter/gather) */ | 1912 | /* set/get features raw service (scatter/gather) */ |
2192 | if (gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_SET_FEAT,SCATTER_GATHER, | 1913 | if (gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_SET_FEAT, SCATTER_GATHER, |
2193 | 0,0)) { | 1914 | 0, 0)) { |
2194 | TRACE2(("gdth_search_drives(): set features RAWSERVICE OK\n")); | 1915 | TRACE2(("gdth_search_drives(): set features RAWSERVICE OK\n")); |
2195 | if (gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_GET_FEAT,0,0,0)) { | 1916 | if (gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_GET_FEAT, 0, 0, 0)) { |
2196 | TRACE2(("gdth_search_dr(): get feat RAWSERVICE %d\n", | 1917 | TRACE2(("gdth_search_dr(): get feat RAWSERVICE %d\n", |
2197 | ha->info)); | 1918 | ha->info)); |
2198 | ha->raw_feat |= (ushort)ha->info; | 1919 | ha->raw_feat |= (ushort)ha->info; |
@@ -2200,10 +1921,10 @@ static int __init gdth_search_drives(int hanum) | |||
2200 | } | 1921 | } |
2201 | 1922 | ||
2202 | /* set/get features cache service (equal to raw service) */ | 1923 | /* set/get features cache service (equal to raw service) */ |
2203 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_SET_FEAT,0, | 1924 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_SET_FEAT, 0, |
2204 | SCATTER_GATHER,0)) { | 1925 | SCATTER_GATHER,0)) { |
2205 | TRACE2(("gdth_search_drives(): set features CACHESERVICE OK\n")); | 1926 | TRACE2(("gdth_search_drives(): set features CACHESERVICE OK\n")); |
2206 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_GET_FEAT,0,0,0)) { | 1927 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_GET_FEAT, 0, 0, 0)) { |
2207 | TRACE2(("gdth_search_dr(): get feat CACHESERV. %d\n", | 1928 | TRACE2(("gdth_search_dr(): get feat CACHESERV. %d\n", |
2208 | ha->info)); | 1929 | ha->info)); |
2209 | ha->cache_feat |= (ushort)ha->info; | 1930 | ha->cache_feat |= (ushort)ha->info; |
@@ -2212,22 +1933,22 @@ static int __init gdth_search_drives(int hanum) | |||
2212 | 1933 | ||
2213 | /* reserve drives for raw service */ | 1934 | /* reserve drives for raw service */ |
2214 | if (reserve_mode != 0) { | 1935 | if (reserve_mode != 0) { |
2215 | gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_RESERVE_ALL, | 1936 | gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_RESERVE_ALL, |
2216 | reserve_mode == 1 ? 1 : 3, 0, 0); | 1937 | reserve_mode == 1 ? 1 : 3, 0, 0); |
2217 | TRACE2(("gdth_search_drives(): RESERVE_ALL code %d\n", | 1938 | TRACE2(("gdth_search_drives(): RESERVE_ALL code %d\n", |
2218 | ha->status)); | 1939 | ha->status)); |
2219 | } | 1940 | } |
2220 | for (i = 0; i < MAX_RES_ARGS; i += 4) { | 1941 | for (i = 0; i < MAX_RES_ARGS; i += 4) { |
2221 | if (reserve_list[i] == hanum && reserve_list[i+1] < ha->bus_cnt && | 1942 | if (reserve_list[i] == ha->hanum && reserve_list[i+1] < ha->bus_cnt && |
2222 | reserve_list[i+2] < ha->tid_cnt && reserve_list[i+3] < MAXLUN) { | 1943 | reserve_list[i+2] < ha->tid_cnt && reserve_list[i+3] < MAXLUN) { |
2223 | TRACE2(("gdth_search_drives(): reserve ha %d bus %d id %d lun %d\n", | 1944 | TRACE2(("gdth_search_drives(): reserve ha %d bus %d id %d lun %d\n", |
2224 | reserve_list[i], reserve_list[i+1], | 1945 | reserve_list[i], reserve_list[i+1], |
2225 | reserve_list[i+2], reserve_list[i+3])); | 1946 | reserve_list[i+2], reserve_list[i+3])); |
2226 | if (!gdth_internal_cmd(hanum,SCSIRAWSERVICE,GDT_RESERVE,0, | 1947 | if (!gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_RESERVE, 0, |
2227 | reserve_list[i+1], reserve_list[i+2] | | 1948 | reserve_list[i+1], reserve_list[i+2] | |
2228 | (reserve_list[i+3] << 8))) { | 1949 | (reserve_list[i+3] << 8))) { |
2229 | printk("GDT-HA %d: Error raw service (RESERVE, code %d)\n", | 1950 | printk("GDT-HA %d: Error raw service (RESERVE, code %d)\n", |
2230 | hanum, ha->status); | 1951 | ha->hanum, ha->status); |
2231 | } | 1952 | } |
2232 | } | 1953 | } |
2233 | } | 1954 | } |
@@ -2236,58 +1957,44 @@ static int __init gdth_search_drives(int hanum) | |||
2236 | oemstr = (gdth_oem_str_ioctl *)ha->pscratch; | 1957 | oemstr = (gdth_oem_str_ioctl *)ha->pscratch; |
2237 | oemstr->params.ctl_version = 0x01; | 1958 | oemstr->params.ctl_version = 0x01; |
2238 | oemstr->params.buffer_size = sizeof(oemstr->text); | 1959 | oemstr->params.buffer_size = sizeof(oemstr->text); |
2239 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_IOCTL, | 1960 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_IOCTL, |
2240 | CACHE_READ_OEM_STRING_RECORD,INVALID_CHANNEL, | 1961 | CACHE_READ_OEM_STRING_RECORD,INVALID_CHANNEL, |
2241 | sizeof(gdth_oem_str_ioctl))) { | 1962 | sizeof(gdth_oem_str_ioctl))) { |
2242 | TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD OK\n")); | 1963 | TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD OK\n")); |
2243 | printk("GDT-HA %d: Vendor: %s Name: %s\n", | 1964 | printk("GDT-HA %d: Vendor: %s Name: %s\n", |
2244 | hanum,oemstr->text.oem_company_name,ha->binfo.type_string); | 1965 | ha->hanum, oemstr->text.oem_company_name, ha->binfo.type_string); |
2245 | /* Save the Host Drive inquiry data */ | 1966 | /* Save the Host Drive inquiry data */ |
2246 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
2247 | strlcpy(ha->oem_name,oemstr->text.scsi_host_drive_inquiry_vendor_id, | 1967 | strlcpy(ha->oem_name,oemstr->text.scsi_host_drive_inquiry_vendor_id, |
2248 | sizeof(ha->oem_name)); | 1968 | sizeof(ha->oem_name)); |
2249 | #else | ||
2250 | strncpy(ha->oem_name,oemstr->text.scsi_host_drive_inquiry_vendor_id,7); | ||
2251 | ha->oem_name[7] = '\0'; | ||
2252 | #endif | ||
2253 | } else { | 1969 | } else { |
2254 | /* Old method, based on PCI ID */ | 1970 | /* Old method, based on PCI ID */ |
2255 | TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD failed\n")); | 1971 | TRACE2(("gdth_search_drives(): CACHE_READ_OEM_STRING_RECORD failed\n")); |
2256 | printk("GDT-HA %d: Name: %s\n", | 1972 | printk("GDT-HA %d: Name: %s\n", |
2257 | hanum,ha->binfo.type_string); | 1973 | ha->hanum, ha->binfo.type_string); |
2258 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
2259 | if (ha->oem_id == OEM_ID_INTEL) | 1974 | if (ha->oem_id == OEM_ID_INTEL) |
2260 | strlcpy(ha->oem_name,"Intel ", sizeof(ha->oem_name)); | 1975 | strlcpy(ha->oem_name,"Intel ", sizeof(ha->oem_name)); |
2261 | else | 1976 | else |
2262 | strlcpy(ha->oem_name,"ICP ", sizeof(ha->oem_name)); | 1977 | strlcpy(ha->oem_name,"ICP ", sizeof(ha->oem_name)); |
2263 | #else | ||
2264 | if (ha->oem_id == OEM_ID_INTEL) | ||
2265 | strcpy(ha->oem_name,"Intel "); | ||
2266 | else | ||
2267 | strcpy(ha->oem_name,"ICP "); | ||
2268 | #endif | ||
2269 | } | 1978 | } |
2270 | 1979 | ||
2271 | /* scanning for host drives */ | 1980 | /* scanning for host drives */ |
2272 | for (i = 0; i < cdev_cnt; ++i) | 1981 | for (i = 0; i < cdev_cnt; ++i) |
2273 | gdth_analyse_hdrive(hanum,i); | 1982 | gdth_analyse_hdrive(ha, i); |
2274 | 1983 | ||
2275 | TRACE(("gdth_search_drives() OK\n")); | 1984 | TRACE(("gdth_search_drives() OK\n")); |
2276 | return 1; | 1985 | return 1; |
2277 | } | 1986 | } |
2278 | 1987 | ||
2279 | static int gdth_analyse_hdrive(int hanum,ushort hdrive) | 1988 | static int gdth_analyse_hdrive(gdth_ha_str *ha, ushort hdrive) |
2280 | { | 1989 | { |
2281 | register gdth_ha_str *ha; | ||
2282 | ulong32 drv_cyls; | 1990 | ulong32 drv_cyls; |
2283 | int drv_hds, drv_secs; | 1991 | int drv_hds, drv_secs; |
2284 | 1992 | ||
2285 | TRACE(("gdth_analyse_hdrive() hanum %d drive %d\n",hanum,hdrive)); | 1993 | TRACE(("gdth_analyse_hdrive() hanum %d drive %d\n", ha->hanum, hdrive)); |
2286 | if (hdrive >= MAX_HDRIVES) | 1994 | if (hdrive >= MAX_HDRIVES) |
2287 | return 0; | 1995 | return 0; |
2288 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
2289 | 1996 | ||
2290 | if (!gdth_internal_cmd(hanum,CACHESERVICE,GDT_INFO,hdrive,0,0)) | 1997 | if (!gdth_internal_cmd(ha, CACHESERVICE, GDT_INFO, hdrive, 0, 0)) |
2291 | return 0; | 1998 | return 0; |
2292 | ha->hdr[hdrive].present = TRUE; | 1999 | ha->hdr[hdrive].present = TRUE; |
2293 | ha->hdr[hdrive].size = ha->info; | 2000 | ha->hdr[hdrive].size = ha->info; |
@@ -2307,7 +2014,7 @@ static int gdth_analyse_hdrive(int hanum,ushort hdrive) | |||
2307 | ha->hdr[hdrive].size = drv_cyls * drv_hds * drv_secs; | 2014 | ha->hdr[hdrive].size = drv_cyls * drv_hds * drv_secs; |
2308 | 2015 | ||
2309 | if (ha->cache_feat & GDT_64BIT) { | 2016 | if (ha->cache_feat & GDT_64BIT) { |
2310 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_X_INFO,hdrive,0,0) | 2017 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_X_INFO, hdrive, 0, 0) |
2311 | && ha->info2 != 0) { | 2018 | && ha->info2 != 0) { |
2312 | ha->hdr[hdrive].size = ((ulong64)ha->info2 << 32) | ha->info; | 2019 | ha->hdr[hdrive].size = ((ulong64)ha->info2 << 32) | ha->info; |
2313 | } | 2020 | } |
@@ -2316,14 +2023,14 @@ static int gdth_analyse_hdrive(int hanum,ushort hdrive) | |||
2316 | hdrive,ha->hdr[hdrive].size,drv_hds,drv_secs)); | 2023 | hdrive,ha->hdr[hdrive].size,drv_hds,drv_secs)); |
2317 | 2024 | ||
2318 | /* get informations about device */ | 2025 | /* get informations about device */ |
2319 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_DEVTYPE,hdrive,0,0)) { | 2026 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_DEVTYPE, hdrive, 0, 0)) { |
2320 | TRACE2(("gdth_search_dr() cache drive %d devtype %d\n", | 2027 | TRACE2(("gdth_search_dr() cache drive %d devtype %d\n", |
2321 | hdrive,ha->info)); | 2028 | hdrive,ha->info)); |
2322 | ha->hdr[hdrive].devtype = (ushort)ha->info; | 2029 | ha->hdr[hdrive].devtype = (ushort)ha->info; |
2323 | } | 2030 | } |
2324 | 2031 | ||
2325 | /* cluster info */ | 2032 | /* cluster info */ |
2326 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_CLUST_INFO,hdrive,0,0)) { | 2033 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_CLUST_INFO, hdrive, 0, 0)) { |
2327 | TRACE2(("gdth_search_dr() cache drive %d cluster info %d\n", | 2034 | TRACE2(("gdth_search_dr() cache drive %d cluster info %d\n", |
2328 | hdrive,ha->info)); | 2035 | hdrive,ha->info)); |
2329 | if (!shared_access) | 2036 | if (!shared_access) |
@@ -2331,7 +2038,7 @@ static int gdth_analyse_hdrive(int hanum,ushort hdrive) | |||
2331 | } | 2038 | } |
2332 | 2039 | ||
2333 | /* R/W attributes */ | 2040 | /* R/W attributes */ |
2334 | if (gdth_internal_cmd(hanum,CACHESERVICE,GDT_RW_ATTRIBS,hdrive,0,0)) { | 2041 | if (gdth_internal_cmd(ha, CACHESERVICE, GDT_RW_ATTRIBS, hdrive, 0, 0)) { |
2335 | TRACE2(("gdth_search_dr() cache drive %d r/w attrib. %d\n", | 2042 | TRACE2(("gdth_search_dr() cache drive %d r/w attrib. %d\n", |
2336 | hdrive,ha->info)); | 2043 | hdrive,ha->info)); |
2337 | ha->hdr[hdrive].rw_attribs = (unchar)ha->info; | 2044 | ha->hdr[hdrive].rw_attribs = (unchar)ha->info; |
@@ -2343,27 +2050,26 @@ static int gdth_analyse_hdrive(int hanum,ushort hdrive) | |||
2343 | 2050 | ||
2344 | /* command queueing/sending functions */ | 2051 | /* command queueing/sending functions */ |
2345 | 2052 | ||
2346 | static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority) | 2053 | static void gdth_putq(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar priority) |
2347 | { | 2054 | { |
2348 | register gdth_ha_str *ha; | 2055 | struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); |
2349 | register Scsi_Cmnd *pscp; | 2056 | register Scsi_Cmnd *pscp; |
2350 | register Scsi_Cmnd *nscp; | 2057 | register Scsi_Cmnd *nscp; |
2351 | ulong flags; | 2058 | ulong flags; |
2352 | unchar b, t; | 2059 | unchar b, t; |
2353 | 2060 | ||
2354 | TRACE(("gdth_putq() priority %d\n",priority)); | 2061 | TRACE(("gdth_putq() priority %d\n",priority)); |
2355 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
2356 | spin_lock_irqsave(&ha->smp_lock, flags); | 2062 | spin_lock_irqsave(&ha->smp_lock, flags); |
2357 | 2063 | ||
2358 | if (scp->done != gdth_scsi_done) { | 2064 | if (!cmndinfo->internal_command) { |
2359 | scp->SCp.this_residual = (int)priority; | 2065 | cmndinfo->priority = priority; |
2360 | b = virt_ctr ? NUMDATA(scp->device->host)->busnum:scp->device->channel; | 2066 | b = scp->device->channel; |
2361 | t = scp->device->id; | 2067 | t = scp->device->id; |
2362 | if (priority >= DEFAULT_PRI) { | 2068 | if (priority >= DEFAULT_PRI) { |
2363 | if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || | 2069 | if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || |
2364 | (b==ha->virt_bus && t<MAX_HDRIVES && ha->hdr[t].lock)) { | 2070 | (b==ha->virt_bus && t<MAX_HDRIVES && ha->hdr[t].lock)) { |
2365 | TRACE2(("gdth_putq(): locked IO ->update_timeout()\n")); | 2071 | TRACE2(("gdth_putq(): locked IO ->update_timeout()\n")); |
2366 | scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); | 2072 | cmndinfo->timeout = gdth_update_timeout(scp, 0); |
2367 | } | 2073 | } |
2368 | } | 2074 | } |
2369 | } | 2075 | } |
@@ -2375,7 +2081,7 @@ static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority) | |||
2375 | pscp = ha->req_first; | 2081 | pscp = ha->req_first; |
2376 | nscp = (Scsi_Cmnd *)pscp->SCp.ptr; | 2082 | nscp = (Scsi_Cmnd *)pscp->SCp.ptr; |
2377 | /* priority: 0-highest,..,0xff-lowest */ | 2083 | /* priority: 0-highest,..,0xff-lowest */ |
2378 | while (nscp && (unchar)nscp->SCp.this_residual <= priority) { | 2084 | while (nscp && gdth_cmnd_priv(nscp)->priority <= priority) { |
2379 | pscp = nscp; | 2085 | pscp = nscp; |
2380 | nscp = (Scsi_Cmnd *)pscp->SCp.ptr; | 2086 | nscp = (Scsi_Cmnd *)pscp->SCp.ptr; |
2381 | } | 2087 | } |
@@ -2395,9 +2101,8 @@ static void gdth_putq(int hanum,Scsi_Cmnd *scp,unchar priority) | |||
2395 | #endif | 2101 | #endif |
2396 | } | 2102 | } |
2397 | 2103 | ||
2398 | static void gdth_next(int hanum) | 2104 | static void gdth_next(gdth_ha_str *ha) |
2399 | { | 2105 | { |
2400 | register gdth_ha_str *ha; | ||
2401 | register Scsi_Cmnd *pscp; | 2106 | register Scsi_Cmnd *pscp; |
2402 | register Scsi_Cmnd *nscp; | 2107 | register Scsi_Cmnd *nscp; |
2403 | unchar b, t, l, firsttime; | 2108 | unchar b, t, l, firsttime; |
@@ -2405,8 +2110,7 @@ static void gdth_next(int hanum) | |||
2405 | ulong flags = 0; | 2110 | ulong flags = 0; |
2406 | int cmd_index; | 2111 | int cmd_index; |
2407 | 2112 | ||
2408 | TRACE(("gdth_next() hanum %d\n",hanum)); | 2113 | TRACE(("gdth_next() hanum %d\n", ha->hanum)); |
2409 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
2410 | if (!gdth_polling) | 2114 | if (!gdth_polling) |
2411 | spin_lock_irqsave(&ha->smp_lock, flags); | 2115 | spin_lock_irqsave(&ha->smp_lock, flags); |
2412 | 2116 | ||
@@ -2416,14 +2120,14 @@ static void gdth_next(int hanum) | |||
2416 | cmd_index = 0; | 2120 | cmd_index = 0; |
2417 | 2121 | ||
2418 | for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { | 2122 | for (nscp = pscp = ha->req_first; nscp; nscp = (Scsi_Cmnd *)nscp->SCp.ptr) { |
2123 | struct gdth_cmndinfo *nscp_cmndinfo = gdth_cmnd_priv(nscp); | ||
2419 | if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) | 2124 | if (nscp != pscp && nscp != (Scsi_Cmnd *)pscp->SCp.ptr) |
2420 | pscp = (Scsi_Cmnd *)pscp->SCp.ptr; | 2125 | pscp = (Scsi_Cmnd *)pscp->SCp.ptr; |
2421 | if (nscp->done != gdth_scsi_done) { | 2126 | if (!nscp_cmndinfo->internal_command) { |
2422 | b = virt_ctr ? | 2127 | b = nscp->device->channel; |
2423 | NUMDATA(nscp->device->host)->busnum : nscp->device->channel; | ||
2424 | t = nscp->device->id; | 2128 | t = nscp->device->id; |
2425 | l = nscp->device->lun; | 2129 | l = nscp->device->lun; |
2426 | if (nscp->SCp.this_residual >= DEFAULT_PRI) { | 2130 | if (nscp_cmndinfo->priority >= DEFAULT_PRI) { |
2427 | if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || | 2131 | if ((b != ha->virt_bus && ha->raw[BUS_L2P(ha,b)].lock) || |
2428 | (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) | 2132 | (b == ha->virt_bus && t < MAX_HDRIVES && ha->hdr[t].lock)) |
2429 | continue; | 2133 | continue; |
@@ -2432,21 +2136,21 @@ static void gdth_next(int hanum) | |||
2432 | b = t = l = 0; | 2136 | b = t = l = 0; |
2433 | 2137 | ||
2434 | if (firsttime) { | 2138 | if (firsttime) { |
2435 | if (gdth_test_busy(hanum)) { /* controller busy ? */ | 2139 | if (gdth_test_busy(ha)) { /* controller busy ? */ |
2436 | TRACE(("gdth_next() controller %d busy !\n",hanum)); | 2140 | TRACE(("gdth_next() controller %d busy !\n", ha->hanum)); |
2437 | if (!gdth_polling) { | 2141 | if (!gdth_polling) { |
2438 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 2142 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
2439 | return; | 2143 | return; |
2440 | } | 2144 | } |
2441 | while (gdth_test_busy(hanum)) | 2145 | while (gdth_test_busy(ha)) |
2442 | gdth_delay(1); | 2146 | gdth_delay(1); |
2443 | } | 2147 | } |
2444 | firsttime = FALSE; | 2148 | firsttime = FALSE; |
2445 | } | 2149 | } |
2446 | 2150 | ||
2447 | if (nscp->done != gdth_scsi_done) { | 2151 | if (!nscp_cmndinfo->internal_command) { |
2448 | if (nscp->SCp.phase == -1) { | 2152 | if (nscp_cmndinfo->phase == -1) { |
2449 | nscp->SCp.phase = CACHESERVICE; /* default: cache svc. */ | 2153 | nscp_cmndinfo->phase = CACHESERVICE; /* default: cache svc. */ |
2450 | if (nscp->cmnd[0] == TEST_UNIT_READY) { | 2154 | if (nscp->cmnd[0] == TEST_UNIT_READY) { |
2451 | TRACE2(("TEST_UNIT_READY Bus %d Id %d LUN %d\n", | 2155 | TRACE2(("TEST_UNIT_READY Bus %d Id %d LUN %d\n", |
2452 | b, t, l)); | 2156 | b, t, l)); |
@@ -2459,8 +2163,8 @@ static void gdth_next(int hanum) | |||
2459 | } else if ((ha->scan_mode & 0x0f) == 1) { | 2163 | } else if ((ha->scan_mode & 0x0f) == 1) { |
2460 | if (b == 0 && ((t == 0 && l == 1) || | 2164 | if (b == 0 && ((t == 0 && l == 1) || |
2461 | (t == 1 && l == 0))) { | 2165 | (t == 1 && l == 0))) { |
2462 | nscp->SCp.sent_command = GDT_SCAN_START; | 2166 | nscp_cmndinfo->OpCode = GDT_SCAN_START; |
2463 | nscp->SCp.phase = ((ha->scan_mode & 0x10 ? 1:0) << 8) | 2167 | nscp_cmndinfo->phase = ((ha->scan_mode & 0x10 ? 1:0) << 8) |
2464 | | SCSIRAWSERVICE; | 2168 | | SCSIRAWSERVICE; |
2465 | ha->scan_mode = 0x12; | 2169 | ha->scan_mode = 0x12; |
2466 | TRACE2(("Scan mode: 0x%x (SCAN_START)\n", | 2170 | TRACE2(("Scan mode: 0x%x (SCAN_START)\n", |
@@ -2471,8 +2175,8 @@ static void gdth_next(int hanum) | |||
2471 | } | 2175 | } |
2472 | } else if (ha->scan_mode == 0x12) { | 2176 | } else if (ha->scan_mode == 0x12) { |
2473 | if (b == ha->bus_cnt && t == ha->tid_cnt-1) { | 2177 | if (b == ha->bus_cnt && t == ha->tid_cnt-1) { |
2474 | nscp->SCp.phase = SCSIRAWSERVICE; | 2178 | nscp_cmndinfo->phase = SCSIRAWSERVICE; |
2475 | nscp->SCp.sent_command = GDT_SCAN_END; | 2179 | nscp_cmndinfo->OpCode = GDT_SCAN_END; |
2476 | ha->scan_mode &= 0x10; | 2180 | ha->scan_mode &= 0x10; |
2477 | TRACE2(("Scan mode: 0x%x (SCAN_END)\n", | 2181 | TRACE2(("Scan mode: 0x%x (SCAN_END)\n", |
2478 | ha->scan_mode)); | 2182 | ha->scan_mode)); |
@@ -2483,18 +2187,18 @@ static void gdth_next(int hanum) | |||
2483 | nscp->cmnd[0] != READ_CAPACITY && nscp->cmnd[0] != MODE_SENSE && | 2187 | nscp->cmnd[0] != READ_CAPACITY && nscp->cmnd[0] != MODE_SENSE && |
2484 | (ha->hdr[t].cluster_type & CLUSTER_DRIVE)) { | 2188 | (ha->hdr[t].cluster_type & CLUSTER_DRIVE)) { |
2485 | /* always GDT_CLUST_INFO! */ | 2189 | /* always GDT_CLUST_INFO! */ |
2486 | nscp->SCp.sent_command = GDT_CLUST_INFO; | 2190 | nscp_cmndinfo->OpCode = GDT_CLUST_INFO; |
2487 | } | 2191 | } |
2488 | } | 2192 | } |
2489 | } | 2193 | } |
2490 | 2194 | ||
2491 | if (nscp->SCp.sent_command != -1) { | 2195 | if (nscp_cmndinfo->OpCode != -1) { |
2492 | if ((nscp->SCp.phase & 0xff) == CACHESERVICE) { | 2196 | if ((nscp_cmndinfo->phase & 0xff) == CACHESERVICE) { |
2493 | if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t))) | 2197 | if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) |
2494 | this_cmd = FALSE; | 2198 | this_cmd = FALSE; |
2495 | next_cmd = FALSE; | 2199 | next_cmd = FALSE; |
2496 | } else if ((nscp->SCp.phase & 0xff) == SCSIRAWSERVICE) { | 2200 | } else if ((nscp_cmndinfo->phase & 0xff) == SCSIRAWSERVICE) { |
2497 | if (!(cmd_index=gdth_fill_raw_cmd(hanum,nscp,BUS_L2P(ha,b)))) | 2201 | if (!(cmd_index=gdth_fill_raw_cmd(ha, nscp, BUS_L2P(ha, b)))) |
2498 | this_cmd = FALSE; | 2202 | this_cmd = FALSE; |
2499 | next_cmd = FALSE; | 2203 | next_cmd = FALSE; |
2500 | } else { | 2204 | } else { |
@@ -2502,18 +2206,18 @@ static void gdth_next(int hanum) | |||
2502 | nscp->sense_buffer[0] = 0x70; | 2206 | nscp->sense_buffer[0] = 0x70; |
2503 | nscp->sense_buffer[2] = NOT_READY; | 2207 | nscp->sense_buffer[2] = NOT_READY; |
2504 | nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); | 2208 | nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); |
2505 | if (!nscp->SCp.have_data_in) | 2209 | if (!nscp_cmndinfo->wait_for_completion) |
2506 | nscp->SCp.have_data_in++; | 2210 | nscp_cmndinfo->wait_for_completion++; |
2507 | else | 2211 | else |
2508 | nscp->scsi_done(nscp); | 2212 | gdth_scsi_done(nscp); |
2509 | } | 2213 | } |
2510 | } else if (nscp->done == gdth_scsi_done) { | 2214 | } else if (gdth_cmnd_priv(nscp)->internal_command) { |
2511 | if (!(cmd_index=gdth_special_cmd(hanum,nscp))) | 2215 | if (!(cmd_index=gdth_special_cmd(ha, nscp))) |
2512 | this_cmd = FALSE; | 2216 | this_cmd = FALSE; |
2513 | next_cmd = FALSE; | 2217 | next_cmd = FALSE; |
2514 | } else if (b != ha->virt_bus) { | 2218 | } else if (b != ha->virt_bus) { |
2515 | if (ha->raw[BUS_L2P(ha,b)].io_cnt[t] >= GDTH_MAX_RAW || | 2219 | if (ha->raw[BUS_L2P(ha,b)].io_cnt[t] >= GDTH_MAX_RAW || |
2516 | !(cmd_index=gdth_fill_raw_cmd(hanum,nscp,BUS_L2P(ha,b)))) | 2220 | !(cmd_index=gdth_fill_raw_cmd(ha, nscp, BUS_L2P(ha, b)))) |
2517 | this_cmd = FALSE; | 2221 | this_cmd = FALSE; |
2518 | else | 2222 | else |
2519 | ha->raw[BUS_L2P(ha,b)].io_cnt[t]++; | 2223 | ha->raw[BUS_L2P(ha,b)].io_cnt[t]++; |
@@ -2521,10 +2225,10 @@ static void gdth_next(int hanum) | |||
2521 | TRACE2(("Command 0x%x to bus %d id %d lun %d -> IGNORE\n", | 2225 | TRACE2(("Command 0x%x to bus %d id %d lun %d -> IGNORE\n", |
2522 | nscp->cmnd[0], b, t, l)); | 2226 | nscp->cmnd[0], b, t, l)); |
2523 | nscp->result = DID_BAD_TARGET << 16; | 2227 | nscp->result = DID_BAD_TARGET << 16; |
2524 | if (!nscp->SCp.have_data_in) | 2228 | if (!nscp_cmndinfo->wait_for_completion) |
2525 | nscp->SCp.have_data_in++; | 2229 | nscp_cmndinfo->wait_for_completion++; |
2526 | else | 2230 | else |
2527 | nscp->scsi_done(nscp); | 2231 | gdth_scsi_done(nscp); |
2528 | } else { | 2232 | } else { |
2529 | switch (nscp->cmnd[0]) { | 2233 | switch (nscp->cmnd[0]) { |
2530 | case TEST_UNIT_READY: | 2234 | case TEST_UNIT_READY: |
@@ -2547,12 +2251,12 @@ static void gdth_next(int hanum) | |||
2547 | nscp->sense_buffer[0] = 0x70; | 2251 | nscp->sense_buffer[0] = 0x70; |
2548 | nscp->sense_buffer[2] = UNIT_ATTENTION; | 2252 | nscp->sense_buffer[2] = UNIT_ATTENTION; |
2549 | nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); | 2253 | nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); |
2550 | if (!nscp->SCp.have_data_in) | 2254 | if (!nscp_cmndinfo->wait_for_completion) |
2551 | nscp->SCp.have_data_in++; | 2255 | nscp_cmndinfo->wait_for_completion++; |
2552 | else | 2256 | else |
2553 | nscp->scsi_done(nscp); | 2257 | gdth_scsi_done(nscp); |
2554 | } else if (gdth_internal_cache_cmd(hanum,nscp)) | 2258 | } else if (gdth_internal_cache_cmd(ha, nscp)) |
2555 | nscp->scsi_done(nscp); | 2259 | gdth_scsi_done(nscp); |
2556 | break; | 2260 | break; |
2557 | 2261 | ||
2558 | case ALLOW_MEDIUM_REMOVAL: | 2262 | case ALLOW_MEDIUM_REMOVAL: |
@@ -2563,15 +2267,15 @@ static void gdth_next(int hanum) | |||
2563 | TRACE(("Prevent r. nonremov. drive->do nothing\n")); | 2267 | TRACE(("Prevent r. nonremov. drive->do nothing\n")); |
2564 | nscp->result = DID_OK << 16; | 2268 | nscp->result = DID_OK << 16; |
2565 | nscp->sense_buffer[0] = 0; | 2269 | nscp->sense_buffer[0] = 0; |
2566 | if (!nscp->SCp.have_data_in) | 2270 | if (!nscp_cmndinfo->wait_for_completion) |
2567 | nscp->SCp.have_data_in++; | 2271 | nscp_cmndinfo->wait_for_completion++; |
2568 | else | 2272 | else |
2569 | nscp->scsi_done(nscp); | 2273 | gdth_scsi_done(nscp); |
2570 | } else { | 2274 | } else { |
2571 | nscp->cmnd[3] = (ha->hdr[t].devtype&1) ? 1:0; | 2275 | nscp->cmnd[3] = (ha->hdr[t].devtype&1) ? 1:0; |
2572 | TRACE(("Prevent/allow r. %d rem. drive %d\n", | 2276 | TRACE(("Prevent/allow r. %d rem. drive %d\n", |
2573 | nscp->cmnd[4],nscp->cmnd[3])); | 2277 | nscp->cmnd[4],nscp->cmnd[3])); |
2574 | if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t))) | 2278 | if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) |
2575 | this_cmd = FALSE; | 2279 | this_cmd = FALSE; |
2576 | } | 2280 | } |
2577 | break; | 2281 | break; |
@@ -2580,7 +2284,7 @@ static void gdth_next(int hanum) | |||
2580 | case RELEASE: | 2284 | case RELEASE: |
2581 | TRACE2(("cache cmd %s\n",nscp->cmnd[0] == RESERVE ? | 2285 | TRACE2(("cache cmd %s\n",nscp->cmnd[0] == RESERVE ? |
2582 | "RESERVE" : "RELEASE")); | 2286 | "RESERVE" : "RELEASE")); |
2583 | if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t))) | 2287 | if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) |
2584 | this_cmd = FALSE; | 2288 | this_cmd = FALSE; |
2585 | break; | 2289 | break; |
2586 | 2290 | ||
@@ -2599,11 +2303,11 @@ static void gdth_next(int hanum) | |||
2599 | nscp->sense_buffer[0] = 0x70; | 2303 | nscp->sense_buffer[0] = 0x70; |
2600 | nscp->sense_buffer[2] = UNIT_ATTENTION; | 2304 | nscp->sense_buffer[2] = UNIT_ATTENTION; |
2601 | nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); | 2305 | nscp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); |
2602 | if (!nscp->SCp.have_data_in) | 2306 | if (!nscp_cmndinfo->wait_for_completion) |
2603 | nscp->SCp.have_data_in++; | 2307 | nscp_cmndinfo->wait_for_completion++; |
2604 | else | 2308 | else |
2605 | nscp->scsi_done(nscp); | 2309 | gdth_scsi_done(nscp); |
2606 | } else if (!(cmd_index=gdth_fill_cache_cmd(hanum,nscp,t))) | 2310 | } else if (!(cmd_index=gdth_fill_cache_cmd(ha, nscp, t))) |
2607 | this_cmd = FALSE; | 2311 | this_cmd = FALSE; |
2608 | break; | 2312 | break; |
2609 | 2313 | ||
@@ -2612,12 +2316,12 @@ static void gdth_next(int hanum) | |||
2612 | nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3], | 2316 | nscp->cmnd[1],nscp->cmnd[2],nscp->cmnd[3], |
2613 | nscp->cmnd[4],nscp->cmnd[5])); | 2317 | nscp->cmnd[4],nscp->cmnd[5])); |
2614 | printk("GDT-HA %d: Unknown SCSI command 0x%x to cache service !\n", | 2318 | printk("GDT-HA %d: Unknown SCSI command 0x%x to cache service !\n", |
2615 | hanum, nscp->cmnd[0]); | 2319 | ha->hanum, nscp->cmnd[0]); |
2616 | nscp->result = DID_ABORT << 16; | 2320 | nscp->result = DID_ABORT << 16; |
2617 | if (!nscp->SCp.have_data_in) | 2321 | if (!nscp_cmndinfo->wait_for_completion) |
2618 | nscp->SCp.have_data_in++; | 2322 | nscp_cmndinfo->wait_for_completion++; |
2619 | else | 2323 | else |
2620 | nscp->scsi_done(nscp); | 2324 | gdth_scsi_done(nscp); |
2621 | break; | 2325 | break; |
2622 | } | 2326 | } |
2623 | } | 2327 | } |
@@ -2633,79 +2337,77 @@ static void gdth_next(int hanum) | |||
2633 | } | 2337 | } |
2634 | 2338 | ||
2635 | if (ha->cmd_cnt > 0) { | 2339 | if (ha->cmd_cnt > 0) { |
2636 | gdth_release_event(hanum); | 2340 | gdth_release_event(ha); |
2637 | } | 2341 | } |
2638 | 2342 | ||
2639 | if (!gdth_polling) | 2343 | if (!gdth_polling) |
2640 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 2344 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
2641 | 2345 | ||
2642 | if (gdth_polling && ha->cmd_cnt > 0) { | 2346 | if (gdth_polling && ha->cmd_cnt > 0) { |
2643 | if (!gdth_wait(hanum,cmd_index,POLL_TIMEOUT)) | 2347 | if (!gdth_wait(ha, cmd_index, POLL_TIMEOUT)) |
2644 | printk("GDT-HA %d: Command %d timed out !\n", | 2348 | printk("GDT-HA %d: Command %d timed out !\n", |
2645 | hanum,cmd_index); | 2349 | ha->hanum, cmd_index); |
2646 | } | 2350 | } |
2647 | } | 2351 | } |
2648 | 2352 | ||
2649 | static void gdth_copy_internal_data(int hanum,Scsi_Cmnd *scp, | 2353 | /* |
2650 | char *buffer,ushort count) | 2354 | * gdth_copy_internal_data() - copy to/from a buffer onto a scsi_cmnd's |
2355 | * buffers, kmap_atomic() as needed. | ||
2356 | */ | ||
2357 | static void gdth_copy_internal_data(gdth_ha_str *ha, Scsi_Cmnd *scp, | ||
2358 | char *buffer, ushort count, int to_buffer) | ||
2651 | { | 2359 | { |
2652 | ushort cpcount,i; | 2360 | ushort cpcount,i, max_sg = gdth_sg_count(scp); |
2653 | ushort cpsum,cpnow; | 2361 | ushort cpsum,cpnow; |
2654 | struct scatterlist *sl; | 2362 | struct scatterlist *sl; |
2655 | gdth_ha_str *ha; | ||
2656 | char *address; | 2363 | char *address; |
2657 | 2364 | ||
2658 | cpcount = count<=(ushort)scp->request_bufflen ? count:(ushort)scp->request_bufflen; | 2365 | cpcount = min_t(ushort, count, gdth_bufflen(scp)); |
2659 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
2660 | 2366 | ||
2661 | if (scp->use_sg) { | 2367 | if (cpcount) { |
2662 | sl = (struct scatterlist *)scp->request_buffer; | 2368 | cpsum=0; |
2663 | for (i=0,cpsum=0; i<scp->use_sg; ++i,++sl) { | 2369 | scsi_for_each_sg(scp, sl, max_sg, i) { |
2664 | unsigned long flags; | 2370 | unsigned long flags; |
2665 | cpnow = (ushort)sl->length; | 2371 | cpnow = (ushort)sl->length; |
2666 | TRACE(("copy_internal() now %d sum %d count %d %d\n", | 2372 | TRACE(("copy_internal() now %d sum %d count %d %d\n", |
2667 | cpnow,cpsum,cpcount,(ushort)scp->bufflen)); | 2373 | cpnow, cpsum, cpcount, gdth_bufflen(scp))); |
2668 | if (cpsum+cpnow > cpcount) | 2374 | if (cpsum+cpnow > cpcount) |
2669 | cpnow = cpcount - cpsum; | 2375 | cpnow = cpcount - cpsum; |
2670 | cpsum += cpnow; | 2376 | cpsum += cpnow; |
2671 | if (!sl->page) { | 2377 | if (!sl->page) { |
2672 | printk("GDT-HA %d: invalid sc/gt element in gdth_copy_internal_data()\n", | 2378 | printk("GDT-HA %d: invalid sc/gt element in gdth_copy_internal_data()\n", |
2673 | hanum); | 2379 | ha->hanum); |
2674 | return; | 2380 | return; |
2675 | } | 2381 | } |
2676 | local_irq_save(flags); | 2382 | local_irq_save(flags); |
2677 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
2678 | address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset; | 2383 | address = kmap_atomic(sl->page, KM_BIO_SRC_IRQ) + sl->offset; |
2679 | memcpy(address,buffer,cpnow); | 2384 | if (to_buffer) |
2385 | memcpy(buffer, address, cpnow); | ||
2386 | else | ||
2387 | memcpy(address, buffer, cpnow); | ||
2680 | flush_dcache_page(sl->page); | 2388 | flush_dcache_page(sl->page); |
2681 | kunmap_atomic(address, KM_BIO_SRC_IRQ); | 2389 | kunmap_atomic(address, KM_BIO_SRC_IRQ); |
2682 | #else | ||
2683 | address = kmap_atomic(sl->page, KM_BH_IRQ) + sl->offset; | ||
2684 | memcpy(address,buffer,cpnow); | ||
2685 | flush_dcache_page(sl->page); | ||
2686 | kunmap_atomic(address, KM_BH_IRQ); | ||
2687 | #endif | ||
2688 | local_irq_restore(flags); | 2390 | local_irq_restore(flags); |
2689 | if (cpsum == cpcount) | 2391 | if (cpsum == cpcount) |
2690 | break; | 2392 | break; |
2691 | buffer += cpnow; | 2393 | buffer += cpnow; |
2692 | } | 2394 | } |
2693 | } else { | 2395 | } else if (count) { |
2694 | TRACE(("copy_internal() count %d\n",cpcount)); | 2396 | printk("GDT-HA %d: SCSI command with no buffers but data transfer expected!\n", |
2695 | memcpy((char*)scp->request_buffer,buffer,cpcount); | 2397 | ha->hanum); |
2398 | WARN_ON(1); | ||
2696 | } | 2399 | } |
2697 | } | 2400 | } |
2698 | 2401 | ||
2699 | static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) | 2402 | static int gdth_internal_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) |
2700 | { | 2403 | { |
2701 | register gdth_ha_str *ha; | ||
2702 | unchar t; | 2404 | unchar t; |
2703 | gdth_inq_data inq; | 2405 | gdth_inq_data inq; |
2704 | gdth_rdcap_data rdc; | 2406 | gdth_rdcap_data rdc; |
2705 | gdth_sense_data sd; | 2407 | gdth_sense_data sd; |
2706 | gdth_modep_data mpd; | 2408 | gdth_modep_data mpd; |
2409 | struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); | ||
2707 | 2410 | ||
2708 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
2709 | t = scp->device->id; | 2411 | t = scp->device->id; |
2710 | TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n", | 2412 | TRACE(("gdth_internal_cache_cmd() cmd 0x%x hdrive %d\n", |
2711 | scp->cmnd[0],t)); | 2413 | scp->cmnd[0],t)); |
@@ -2736,7 +2438,7 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) | |||
2736 | strcpy(inq.vendor,ha->oem_name); | 2438 | strcpy(inq.vendor,ha->oem_name); |
2737 | sprintf(inq.product,"Host Drive #%02d",t); | 2439 | sprintf(inq.product,"Host Drive #%02d",t); |
2738 | strcpy(inq.revision," "); | 2440 | strcpy(inq.revision," "); |
2739 | gdth_copy_internal_data(hanum,scp,(char*)&inq,sizeof(gdth_inq_data)); | 2441 | gdth_copy_internal_data(ha, scp, (char*)&inq, sizeof(gdth_inq_data), 0); |
2740 | break; | 2442 | break; |
2741 | 2443 | ||
2742 | case REQUEST_SENSE: | 2444 | case REQUEST_SENSE: |
@@ -2746,7 +2448,7 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) | |||
2746 | sd.key = NO_SENSE; | 2448 | sd.key = NO_SENSE; |
2747 | sd.info = 0; | 2449 | sd.info = 0; |
2748 | sd.add_length= 0; | 2450 | sd.add_length= 0; |
2749 | gdth_copy_internal_data(hanum,scp,(char*)&sd,sizeof(gdth_sense_data)); | 2451 | gdth_copy_internal_data(ha, scp, (char*)&sd, sizeof(gdth_sense_data), 0); |
2750 | break; | 2452 | break; |
2751 | 2453 | ||
2752 | case MODE_SENSE: | 2454 | case MODE_SENSE: |
@@ -2758,7 +2460,7 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) | |||
2758 | mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16; | 2460 | mpd.bd.block_length[0] = (SECTOR_SIZE & 0x00ff0000) >> 16; |
2759 | mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8; | 2461 | mpd.bd.block_length[1] = (SECTOR_SIZE & 0x0000ff00) >> 8; |
2760 | mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff); | 2462 | mpd.bd.block_length[2] = (SECTOR_SIZE & 0x000000ff); |
2761 | gdth_copy_internal_data(hanum,scp,(char*)&mpd,sizeof(gdth_modep_data)); | 2463 | gdth_copy_internal_data(ha, scp, (char*)&mpd, sizeof(gdth_modep_data), 0); |
2762 | break; | 2464 | break; |
2763 | 2465 | ||
2764 | case READ_CAPACITY: | 2466 | case READ_CAPACITY: |
@@ -2768,7 +2470,7 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) | |||
2768 | else | 2470 | else |
2769 | rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1); | 2471 | rdc.last_block_no = cpu_to_be32(ha->hdr[t].size-1); |
2770 | rdc.block_length = cpu_to_be32(SECTOR_SIZE); | 2472 | rdc.block_length = cpu_to_be32(SECTOR_SIZE); |
2771 | gdth_copy_internal_data(hanum,scp,(char*)&rdc,sizeof(gdth_rdcap_data)); | 2473 | gdth_copy_internal_data(ha, scp, (char*)&rdc, sizeof(gdth_rdcap_data), 0); |
2772 | break; | 2474 | break; |
2773 | 2475 | ||
2774 | case SERVICE_ACTION_IN: | 2476 | case SERVICE_ACTION_IN: |
@@ -2779,7 +2481,8 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) | |||
2779 | TRACE2(("Read capacity (16) hdrive %d\n",t)); | 2481 | TRACE2(("Read capacity (16) hdrive %d\n",t)); |
2780 | rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1); | 2482 | rdc16.last_block_no = cpu_to_be64(ha->hdr[t].size-1); |
2781 | rdc16.block_length = cpu_to_be32(SECTOR_SIZE); | 2483 | rdc16.block_length = cpu_to_be32(SECTOR_SIZE); |
2782 | gdth_copy_internal_data(hanum,scp,(char*)&rdc16,sizeof(gdth_rdcap16_data)); | 2484 | gdth_copy_internal_data(ha, scp, (char*)&rdc16, |
2485 | sizeof(gdth_rdcap16_data), 0); | ||
2783 | } else { | 2486 | } else { |
2784 | scp->result = DID_ABORT << 16; | 2487 | scp->result = DID_ABORT << 16; |
2785 | } | 2488 | } |
@@ -2790,27 +2493,22 @@ static int gdth_internal_cache_cmd(int hanum,Scsi_Cmnd *scp) | |||
2790 | break; | 2493 | break; |
2791 | } | 2494 | } |
2792 | 2495 | ||
2793 | if (!scp->SCp.have_data_in) | 2496 | if (!cmndinfo->wait_for_completion) |
2794 | scp->SCp.have_data_in++; | 2497 | cmndinfo->wait_for_completion++; |
2795 | else | 2498 | else |
2796 | return 1; | 2499 | return 1; |
2797 | 2500 | ||
2798 | return 0; | 2501 | return 0; |
2799 | } | 2502 | } |
2800 | 2503 | ||
2801 | static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) | 2504 | static int gdth_fill_cache_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, ushort hdrive) |
2802 | { | 2505 | { |
2803 | register gdth_ha_str *ha; | ||
2804 | register gdth_cmd_str *cmdp; | 2506 | register gdth_cmd_str *cmdp; |
2805 | struct scatterlist *sl; | 2507 | struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); |
2806 | ulong32 cnt, blockcnt; | 2508 | ulong32 cnt, blockcnt; |
2807 | ulong64 no, blockno; | 2509 | ulong64 no, blockno; |
2808 | dma_addr_t phys_addr; | ||
2809 | int i, cmd_index, read_write, sgcnt, mode64; | 2510 | int i, cmd_index, read_write, sgcnt, mode64; |
2810 | struct page *page; | ||
2811 | ulong offset; | ||
2812 | 2511 | ||
2813 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
2814 | cmdp = ha->pccb; | 2512 | cmdp = ha->pccb; |
2815 | TRACE(("gdth_fill_cache_cmd() cmd 0x%x cmdsize %d hdrive %d\n", | 2513 | TRACE(("gdth_fill_cache_cmd() cmd 0x%x cmdsize %d hdrive %d\n", |
2816 | scp->cmnd[0],scp->cmd_len,hdrive)); | 2514 | scp->cmnd[0],scp->cmd_len,hdrive)); |
@@ -2826,18 +2524,18 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) | |||
2826 | cmdp->Service = CACHESERVICE; | 2524 | cmdp->Service = CACHESERVICE; |
2827 | cmdp->RequestBuffer = scp; | 2525 | cmdp->RequestBuffer = scp; |
2828 | /* search free command index */ | 2526 | /* search free command index */ |
2829 | if (!(cmd_index=gdth_get_cmd_index(hanum))) { | 2527 | if (!(cmd_index=gdth_get_cmd_index(ha))) { |
2830 | TRACE(("GDT: No free command index found\n")); | 2528 | TRACE(("GDT: No free command index found\n")); |
2831 | return 0; | 2529 | return 0; |
2832 | } | 2530 | } |
2833 | /* if it's the first command, set command semaphore */ | 2531 | /* if it's the first command, set command semaphore */ |
2834 | if (ha->cmd_cnt == 0) | 2532 | if (ha->cmd_cnt == 0) |
2835 | gdth_set_sema0(hanum); | 2533 | gdth_set_sema0(ha); |
2836 | 2534 | ||
2837 | /* fill command */ | 2535 | /* fill command */ |
2838 | read_write = 0; | 2536 | read_write = 0; |
2839 | if (scp->SCp.sent_command != -1) | 2537 | if (cmndinfo->OpCode != -1) |
2840 | cmdp->OpCode = scp->SCp.sent_command; /* special cache cmd. */ | 2538 | cmdp->OpCode = cmndinfo->OpCode; /* special cache cmd. */ |
2841 | else if (scp->cmnd[0] == RESERVE) | 2539 | else if (scp->cmnd[0] == RESERVE) |
2842 | cmdp->OpCode = GDT_RESERVE_DRV; | 2540 | cmdp->OpCode = GDT_RESERVE_DRV; |
2843 | else if (scp->cmnd[0] == RELEASE) | 2541 | else if (scp->cmnd[0] == RELEASE) |
@@ -2898,17 +2596,17 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) | |||
2898 | cmdp->u.cache.BlockCnt = blockcnt; | 2596 | cmdp->u.cache.BlockCnt = blockcnt; |
2899 | } | 2597 | } |
2900 | 2598 | ||
2901 | if (scp->use_sg) { | 2599 | if (gdth_bufflen(scp)) { |
2902 | sl = (struct scatterlist *)scp->request_buffer; | 2600 | cmndinfo->dma_dir = (read_write == 1 ? |
2903 | sgcnt = scp->use_sg; | ||
2904 | scp->SCp.Status = GDTH_MAP_SG; | ||
2905 | scp->SCp.Message = (read_write == 1 ? | ||
2906 | PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | 2601 | PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); |
2907 | sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,scp->SCp.Message); | 2602 | sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), |
2603 | cmndinfo->dma_dir); | ||
2908 | if (mode64) { | 2604 | if (mode64) { |
2605 | struct scatterlist *sl; | ||
2606 | |||
2909 | cmdp->u.cache64.DestAddr= (ulong64)-1; | 2607 | cmdp->u.cache64.DestAddr= (ulong64)-1; |
2910 | cmdp->u.cache64.sg_canz = sgcnt; | 2608 | cmdp->u.cache64.sg_canz = sgcnt; |
2911 | for (i=0; i<sgcnt; ++i,++sl) { | 2609 | scsi_for_each_sg(scp, sl, sgcnt, i) { |
2912 | cmdp->u.cache64.sg_lst[i].sg_ptr = sg_dma_address(sl); | 2610 | cmdp->u.cache64.sg_lst[i].sg_ptr = sg_dma_address(sl); |
2913 | #ifdef GDTH_DMA_STATISTICS | 2611 | #ifdef GDTH_DMA_STATISTICS |
2914 | if (cmdp->u.cache64.sg_lst[i].sg_ptr > (ulong64)0xffffffff) | 2612 | if (cmdp->u.cache64.sg_lst[i].sg_ptr > (ulong64)0xffffffff) |
@@ -2919,9 +2617,11 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) | |||
2919 | cmdp->u.cache64.sg_lst[i].sg_len = sg_dma_len(sl); | 2617 | cmdp->u.cache64.sg_lst[i].sg_len = sg_dma_len(sl); |
2920 | } | 2618 | } |
2921 | } else { | 2619 | } else { |
2620 | struct scatterlist *sl; | ||
2621 | |||
2922 | cmdp->u.cache.DestAddr= 0xffffffff; | 2622 | cmdp->u.cache.DestAddr= 0xffffffff; |
2923 | cmdp->u.cache.sg_canz = sgcnt; | 2623 | cmdp->u.cache.sg_canz = sgcnt; |
2924 | for (i=0; i<sgcnt; ++i,++sl) { | 2624 | scsi_for_each_sg(scp, sl, sgcnt, i) { |
2925 | cmdp->u.cache.sg_lst[i].sg_ptr = sg_dma_address(sl); | 2625 | cmdp->u.cache.sg_lst[i].sg_ptr = sg_dma_address(sl); |
2926 | #ifdef GDTH_DMA_STATISTICS | 2626 | #ifdef GDTH_DMA_STATISTICS |
2927 | ha->dma32_cnt++; | 2627 | ha->dma32_cnt++; |
@@ -2937,38 +2637,6 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) | |||
2937 | } | 2637 | } |
2938 | #endif | 2638 | #endif |
2939 | 2639 | ||
2940 | } else if (scp->request_bufflen) { | ||
2941 | scp->SCp.Status = GDTH_MAP_SINGLE; | ||
2942 | scp->SCp.Message = (read_write == 1 ? | ||
2943 | PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE); | ||
2944 | page = virt_to_page(scp->request_buffer); | ||
2945 | offset = (ulong)scp->request_buffer & ~PAGE_MASK; | ||
2946 | phys_addr = pci_map_page(ha->pdev,page,offset, | ||
2947 | scp->request_bufflen,scp->SCp.Message); | ||
2948 | scp->SCp.dma_handle = phys_addr; | ||
2949 | if (mode64) { | ||
2950 | if (ha->cache_feat & SCATTER_GATHER) { | ||
2951 | cmdp->u.cache64.DestAddr = (ulong64)-1; | ||
2952 | cmdp->u.cache64.sg_canz = 1; | ||
2953 | cmdp->u.cache64.sg_lst[0].sg_ptr = phys_addr; | ||
2954 | cmdp->u.cache64.sg_lst[0].sg_len = scp->request_bufflen; | ||
2955 | cmdp->u.cache64.sg_lst[1].sg_len = 0; | ||
2956 | } else { | ||
2957 | cmdp->u.cache64.DestAddr = phys_addr; | ||
2958 | cmdp->u.cache64.sg_canz= 0; | ||
2959 | } | ||
2960 | } else { | ||
2961 | if (ha->cache_feat & SCATTER_GATHER) { | ||
2962 | cmdp->u.cache.DestAddr = 0xffffffff; | ||
2963 | cmdp->u.cache.sg_canz = 1; | ||
2964 | cmdp->u.cache.sg_lst[0].sg_ptr = phys_addr; | ||
2965 | cmdp->u.cache.sg_lst[0].sg_len = scp->request_bufflen; | ||
2966 | cmdp->u.cache.sg_lst[1].sg_len = 0; | ||
2967 | } else { | ||
2968 | cmdp->u.cache.DestAddr = phys_addr; | ||
2969 | cmdp->u.cache.sg_canz= 0; | ||
2970 | } | ||
2971 | } | ||
2972 | } | 2640 | } |
2973 | } | 2641 | } |
2974 | /* evaluate command size, check space */ | 2642 | /* evaluate command size, check space */ |
@@ -3004,23 +2672,21 @@ static int gdth_fill_cache_cmd(int hanum,Scsi_Cmnd *scp,ushort hdrive) | |||
3004 | } | 2672 | } |
3005 | 2673 | ||
3006 | /* copy command */ | 2674 | /* copy command */ |
3007 | gdth_copy_command(hanum); | 2675 | gdth_copy_command(ha); |
3008 | return cmd_index; | 2676 | return cmd_index; |
3009 | } | 2677 | } |
3010 | 2678 | ||
3011 | static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | 2679 | static int gdth_fill_raw_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp, unchar b) |
3012 | { | 2680 | { |
3013 | register gdth_ha_str *ha; | ||
3014 | register gdth_cmd_str *cmdp; | 2681 | register gdth_cmd_str *cmdp; |
3015 | struct scatterlist *sl; | ||
3016 | ushort i; | 2682 | ushort i; |
3017 | dma_addr_t phys_addr, sense_paddr; | 2683 | dma_addr_t sense_paddr; |
3018 | int cmd_index, sgcnt, mode64; | 2684 | int cmd_index, sgcnt, mode64; |
3019 | unchar t,l; | 2685 | unchar t,l; |
3020 | struct page *page; | 2686 | struct page *page; |
3021 | ulong offset; | 2687 | ulong offset; |
2688 | struct gdth_cmndinfo *cmndinfo; | ||
3022 | 2689 | ||
3023 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
3024 | t = scp->device->id; | 2690 | t = scp->device->id; |
3025 | l = scp->device->lun; | 2691 | l = scp->device->lun; |
3026 | cmdp = ha->pccb; | 2692 | cmdp = ha->pccb; |
@@ -3035,26 +2701,27 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
3035 | cmdp->Service = SCSIRAWSERVICE; | 2701 | cmdp->Service = SCSIRAWSERVICE; |
3036 | cmdp->RequestBuffer = scp; | 2702 | cmdp->RequestBuffer = scp; |
3037 | /* search free command index */ | 2703 | /* search free command index */ |
3038 | if (!(cmd_index=gdth_get_cmd_index(hanum))) { | 2704 | if (!(cmd_index=gdth_get_cmd_index(ha))) { |
3039 | TRACE(("GDT: No free command index found\n")); | 2705 | TRACE(("GDT: No free command index found\n")); |
3040 | return 0; | 2706 | return 0; |
3041 | } | 2707 | } |
3042 | /* if it's the first command, set command semaphore */ | 2708 | /* if it's the first command, set command semaphore */ |
3043 | if (ha->cmd_cnt == 0) | 2709 | if (ha->cmd_cnt == 0) |
3044 | gdth_set_sema0(hanum); | 2710 | gdth_set_sema0(ha); |
3045 | 2711 | ||
2712 | cmndinfo = gdth_cmnd_priv(scp); | ||
3046 | /* fill command */ | 2713 | /* fill command */ |
3047 | if (scp->SCp.sent_command != -1) { | 2714 | if (cmndinfo->OpCode != -1) { |
3048 | cmdp->OpCode = scp->SCp.sent_command; /* special raw cmd. */ | 2715 | cmdp->OpCode = cmndinfo->OpCode; /* special raw cmd. */ |
3049 | cmdp->BoardNode = LOCALBOARD; | 2716 | cmdp->BoardNode = LOCALBOARD; |
3050 | if (mode64) { | 2717 | if (mode64) { |
3051 | cmdp->u.raw64.direction = (scp->SCp.phase >> 8); | 2718 | cmdp->u.raw64.direction = (cmndinfo->phase >> 8); |
3052 | TRACE2(("special raw cmd 0x%x param 0x%x\n", | 2719 | TRACE2(("special raw cmd 0x%x param 0x%x\n", |
3053 | cmdp->OpCode, cmdp->u.raw64.direction)); | 2720 | cmdp->OpCode, cmdp->u.raw64.direction)); |
3054 | /* evaluate command size */ | 2721 | /* evaluate command size */ |
3055 | ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw64.sg_lst); | 2722 | ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.raw64.sg_lst); |
3056 | } else { | 2723 | } else { |
3057 | cmdp->u.raw.direction = (scp->SCp.phase >> 8); | 2724 | cmdp->u.raw.direction = (cmndinfo->phase >> 8); |
3058 | TRACE2(("special raw cmd 0x%x param 0x%x\n", | 2725 | TRACE2(("special raw cmd 0x%x param 0x%x\n", |
3059 | cmdp->OpCode, cmdp->u.raw.direction)); | 2726 | cmdp->OpCode, cmdp->u.raw.direction)); |
3060 | /* evaluate command size */ | 2727 | /* evaluate command size */ |
@@ -3066,9 +2733,8 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
3066 | offset = (ulong)scp->sense_buffer & ~PAGE_MASK; | 2733 | offset = (ulong)scp->sense_buffer & ~PAGE_MASK; |
3067 | sense_paddr = pci_map_page(ha->pdev,page,offset, | 2734 | sense_paddr = pci_map_page(ha->pdev,page,offset, |
3068 | 16,PCI_DMA_FROMDEVICE); | 2735 | 16,PCI_DMA_FROMDEVICE); |
3069 | *(ulong32 *)&scp->SCp.buffer = (ulong32)sense_paddr; | 2736 | |
3070 | /* high part, if 64bit */ | 2737 | cmndinfo->sense_paddr = sense_paddr; |
3071 | *(ulong32 *)&scp->host_scribble = (ulong32)((ulong64)sense_paddr >> 32); | ||
3072 | cmdp->OpCode = GDT_WRITE; /* always */ | 2738 | cmdp->OpCode = GDT_WRITE; /* always */ |
3073 | cmdp->BoardNode = LOCALBOARD; | 2739 | cmdp->BoardNode = LOCALBOARD; |
3074 | if (mode64) { | 2740 | if (mode64) { |
@@ -3080,7 +2746,7 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
3080 | cmdp->u.raw64.lun = l; | 2746 | cmdp->u.raw64.lun = l; |
3081 | cmdp->u.raw64.bus = b; | 2747 | cmdp->u.raw64.bus = b; |
3082 | cmdp->u.raw64.priority = 0; | 2748 | cmdp->u.raw64.priority = 0; |
3083 | cmdp->u.raw64.sdlen = scp->request_bufflen; | 2749 | cmdp->u.raw64.sdlen = gdth_bufflen(scp); |
3084 | cmdp->u.raw64.sense_len = 16; | 2750 | cmdp->u.raw64.sense_len = 16; |
3085 | cmdp->u.raw64.sense_data = sense_paddr; | 2751 | cmdp->u.raw64.sense_data = sense_paddr; |
3086 | cmdp->u.raw64.direction = | 2752 | cmdp->u.raw64.direction = |
@@ -3097,7 +2763,7 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
3097 | cmdp->u.raw.bus = b; | 2763 | cmdp->u.raw.bus = b; |
3098 | cmdp->u.raw.priority = 0; | 2764 | cmdp->u.raw.priority = 0; |
3099 | cmdp->u.raw.link_p = 0; | 2765 | cmdp->u.raw.link_p = 0; |
3100 | cmdp->u.raw.sdlen = scp->request_bufflen; | 2766 | cmdp->u.raw.sdlen = gdth_bufflen(scp); |
3101 | cmdp->u.raw.sense_len = 16; | 2767 | cmdp->u.raw.sense_len = 16; |
3102 | cmdp->u.raw.sense_data = sense_paddr; | 2768 | cmdp->u.raw.sense_data = sense_paddr; |
3103 | cmdp->u.raw.direction = | 2769 | cmdp->u.raw.direction = |
@@ -3106,16 +2772,16 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
3106 | cmdp->u.raw.sg_ranz = 0; | 2772 | cmdp->u.raw.sg_ranz = 0; |
3107 | } | 2773 | } |
3108 | 2774 | ||
3109 | if (scp->use_sg) { | 2775 | if (gdth_bufflen(scp)) { |
3110 | sl = (struct scatterlist *)scp->request_buffer; | 2776 | cmndinfo->dma_dir = PCI_DMA_BIDIRECTIONAL; |
3111 | sgcnt = scp->use_sg; | 2777 | sgcnt = pci_map_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), |
3112 | scp->SCp.Status = GDTH_MAP_SG; | 2778 | cmndinfo->dma_dir); |
3113 | scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; | ||
3114 | sgcnt = pci_map_sg(ha->pdev,sl,scp->use_sg,scp->SCp.Message); | ||
3115 | if (mode64) { | 2779 | if (mode64) { |
2780 | struct scatterlist *sl; | ||
2781 | |||
3116 | cmdp->u.raw64.sdata = (ulong64)-1; | 2782 | cmdp->u.raw64.sdata = (ulong64)-1; |
3117 | cmdp->u.raw64.sg_ranz = sgcnt; | 2783 | cmdp->u.raw64.sg_ranz = sgcnt; |
3118 | for (i=0; i<sgcnt; ++i,++sl) { | 2784 | scsi_for_each_sg(scp, sl, sgcnt, i) { |
3119 | cmdp->u.raw64.sg_lst[i].sg_ptr = sg_dma_address(sl); | 2785 | cmdp->u.raw64.sg_lst[i].sg_ptr = sg_dma_address(sl); |
3120 | #ifdef GDTH_DMA_STATISTICS | 2786 | #ifdef GDTH_DMA_STATISTICS |
3121 | if (cmdp->u.raw64.sg_lst[i].sg_ptr > (ulong64)0xffffffff) | 2787 | if (cmdp->u.raw64.sg_lst[i].sg_ptr > (ulong64)0xffffffff) |
@@ -3126,9 +2792,11 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
3126 | cmdp->u.raw64.sg_lst[i].sg_len = sg_dma_len(sl); | 2792 | cmdp->u.raw64.sg_lst[i].sg_len = sg_dma_len(sl); |
3127 | } | 2793 | } |
3128 | } else { | 2794 | } else { |
2795 | struct scatterlist *sl; | ||
2796 | |||
3129 | cmdp->u.raw.sdata = 0xffffffff; | 2797 | cmdp->u.raw.sdata = 0xffffffff; |
3130 | cmdp->u.raw.sg_ranz = sgcnt; | 2798 | cmdp->u.raw.sg_ranz = sgcnt; |
3131 | for (i=0; i<sgcnt; ++i,++sl) { | 2799 | scsi_for_each_sg(scp, sl, sgcnt, i) { |
3132 | cmdp->u.raw.sg_lst[i].sg_ptr = sg_dma_address(sl); | 2800 | cmdp->u.raw.sg_lst[i].sg_ptr = sg_dma_address(sl); |
3133 | #ifdef GDTH_DMA_STATISTICS | 2801 | #ifdef GDTH_DMA_STATISTICS |
3134 | ha->dma32_cnt++; | 2802 | ha->dma32_cnt++; |
@@ -3144,38 +2812,6 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
3144 | } | 2812 | } |
3145 | #endif | 2813 | #endif |
3146 | 2814 | ||
3147 | } else if (scp->request_bufflen) { | ||
3148 | scp->SCp.Status = GDTH_MAP_SINGLE; | ||
3149 | scp->SCp.Message = PCI_DMA_BIDIRECTIONAL; | ||
3150 | page = virt_to_page(scp->request_buffer); | ||
3151 | offset = (ulong)scp->request_buffer & ~PAGE_MASK; | ||
3152 | phys_addr = pci_map_page(ha->pdev,page,offset, | ||
3153 | scp->request_bufflen,scp->SCp.Message); | ||
3154 | scp->SCp.dma_handle = phys_addr; | ||
3155 | |||
3156 | if (mode64) { | ||
3157 | if (ha->raw_feat & SCATTER_GATHER) { | ||
3158 | cmdp->u.raw64.sdata = (ulong64)-1; | ||
3159 | cmdp->u.raw64.sg_ranz= 1; | ||
3160 | cmdp->u.raw64.sg_lst[0].sg_ptr = phys_addr; | ||
3161 | cmdp->u.raw64.sg_lst[0].sg_len = scp->request_bufflen; | ||
3162 | cmdp->u.raw64.sg_lst[1].sg_len = 0; | ||
3163 | } else { | ||
3164 | cmdp->u.raw64.sdata = phys_addr; | ||
3165 | cmdp->u.raw64.sg_ranz= 0; | ||
3166 | } | ||
3167 | } else { | ||
3168 | if (ha->raw_feat & SCATTER_GATHER) { | ||
3169 | cmdp->u.raw.sdata = 0xffffffff; | ||
3170 | cmdp->u.raw.sg_ranz= 1; | ||
3171 | cmdp->u.raw.sg_lst[0].sg_ptr = phys_addr; | ||
3172 | cmdp->u.raw.sg_lst[0].sg_len = scp->request_bufflen; | ||
3173 | cmdp->u.raw.sg_lst[1].sg_len = 0; | ||
3174 | } else { | ||
3175 | cmdp->u.raw.sdata = phys_addr; | ||
3176 | cmdp->u.raw.sg_ranz= 0; | ||
3177 | } | ||
3178 | } | ||
3179 | } | 2815 | } |
3180 | if (mode64) { | 2816 | if (mode64) { |
3181 | TRACE(("raw cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n", | 2817 | TRACE(("raw cmd: addr. %x sganz %x sgptr0 %x sglen0 %x\n", |
@@ -3209,35 +2845,33 @@ static int gdth_fill_raw_cmd(int hanum,Scsi_Cmnd *scp,unchar b) | |||
3209 | } | 2845 | } |
3210 | 2846 | ||
3211 | /* copy command */ | 2847 | /* copy command */ |
3212 | gdth_copy_command(hanum); | 2848 | gdth_copy_command(ha); |
3213 | return cmd_index; | 2849 | return cmd_index; |
3214 | } | 2850 | } |
3215 | 2851 | ||
3216 | static int gdth_special_cmd(int hanum,Scsi_Cmnd *scp) | 2852 | static int gdth_special_cmd(gdth_ha_str *ha, Scsi_Cmnd *scp) |
3217 | { | 2853 | { |
3218 | register gdth_ha_str *ha; | ||
3219 | register gdth_cmd_str *cmdp; | 2854 | register gdth_cmd_str *cmdp; |
3220 | int cmd_index; | 2855 | int cmd_index; |
3221 | 2856 | ||
3222 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
3223 | cmdp= ha->pccb; | 2857 | cmdp= ha->pccb; |
3224 | TRACE2(("gdth_special_cmd(): ")); | 2858 | TRACE2(("gdth_special_cmd(): ")); |
3225 | 2859 | ||
3226 | if (ha->type==GDT_EISA && ha->cmd_cnt>0) | 2860 | if (ha->type==GDT_EISA && ha->cmd_cnt>0) |
3227 | return 0; | 2861 | return 0; |
3228 | 2862 | ||
3229 | memcpy( cmdp, scp->request_buffer, sizeof(gdth_cmd_str)); | 2863 | gdth_copy_internal_data(ha, scp, (char *)cmdp, sizeof(gdth_cmd_str), 1); |
3230 | cmdp->RequestBuffer = scp; | 2864 | cmdp->RequestBuffer = scp; |
3231 | 2865 | ||
3232 | /* search free command index */ | 2866 | /* search free command index */ |
3233 | if (!(cmd_index=gdth_get_cmd_index(hanum))) { | 2867 | if (!(cmd_index=gdth_get_cmd_index(ha))) { |
3234 | TRACE(("GDT: No free command index found\n")); | 2868 | TRACE(("GDT: No free command index found\n")); |
3235 | return 0; | 2869 | return 0; |
3236 | } | 2870 | } |
3237 | 2871 | ||
3238 | /* if it's the first command, set command semaphore */ | 2872 | /* if it's the first command, set command semaphore */ |
3239 | if (ha->cmd_cnt == 0) | 2873 | if (ha->cmd_cnt == 0) |
3240 | gdth_set_sema0(hanum); | 2874 | gdth_set_sema0(ha); |
3241 | 2875 | ||
3242 | /* evaluate command size, check space */ | 2876 | /* evaluate command size, check space */ |
3243 | if (cmdp->OpCode == GDT_IOCTL) { | 2877 | if (cmdp->OpCode == GDT_IOCTL) { |
@@ -3275,7 +2909,7 @@ static int gdth_special_cmd(int hanum,Scsi_Cmnd *scp) | |||
3275 | } | 2909 | } |
3276 | 2910 | ||
3277 | /* copy command */ | 2911 | /* copy command */ |
3278 | gdth_copy_command(hanum); | 2912 | gdth_copy_command(ha); |
3279 | return cmd_index; | 2913 | return cmd_index; |
3280 | } | 2914 | } |
3281 | 2915 | ||
@@ -3402,15 +3036,14 @@ static void gdth_clear_events(void) | |||
3402 | 3036 | ||
3403 | /* SCSI interface functions */ | 3037 | /* SCSI interface functions */ |
3404 | 3038 | ||
3405 | static irqreturn_t gdth_interrupt(int irq,void *dev_id) | 3039 | static irqreturn_t __gdth_interrupt(gdth_ha_str *ha, int irq, |
3040 | int gdth_from_wait, int* pIndex) | ||
3406 | { | 3041 | { |
3407 | gdth_ha_str *ha2 = (gdth_ha_str *)dev_id; | ||
3408 | register gdth_ha_str *ha; | ||
3409 | gdt6m_dpram_str __iomem *dp6m_ptr = NULL; | 3042 | gdt6m_dpram_str __iomem *dp6m_ptr = NULL; |
3410 | gdt6_dpram_str __iomem *dp6_ptr; | 3043 | gdt6_dpram_str __iomem *dp6_ptr; |
3411 | gdt2_dpram_str __iomem *dp2_ptr; | 3044 | gdt2_dpram_str __iomem *dp2_ptr; |
3412 | Scsi_Cmnd *scp; | 3045 | Scsi_Cmnd *scp; |
3413 | int hanum, rval, i; | 3046 | int rval, i; |
3414 | unchar IStatus; | 3047 | unchar IStatus; |
3415 | ushort Service; | 3048 | ushort Service; |
3416 | ulong flags = 0; | 3049 | ulong flags = 0; |
@@ -3431,17 +3064,15 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3431 | } | 3064 | } |
3432 | 3065 | ||
3433 | if (!gdth_polling) | 3066 | if (!gdth_polling) |
3434 | spin_lock_irqsave(&ha2->smp_lock, flags); | 3067 | spin_lock_irqsave(&ha->smp_lock, flags); |
3435 | wait_index = 0; | ||
3436 | 3068 | ||
3437 | /* search controller */ | 3069 | /* search controller */ |
3438 | if ((hanum = gdth_get_status(&IStatus,irq)) == -1) { | 3070 | if (0 == (IStatus = gdth_get_status(ha, irq))) { |
3439 | /* spurious interrupt */ | 3071 | /* spurious interrupt */ |
3440 | if (!gdth_polling) | 3072 | if (!gdth_polling) |
3441 | spin_unlock_irqrestore(&ha2->smp_lock, flags); | 3073 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
3442 | return IRQ_HANDLED; | 3074 | return IRQ_HANDLED; |
3443 | } | 3075 | } |
3444 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
3445 | 3076 | ||
3446 | #ifdef GDTH_STATISTICS | 3077 | #ifdef GDTH_STATISTICS |
3447 | ++act_ints; | 3078 | ++act_ints; |
@@ -3482,32 +3113,32 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3482 | dp2_ptr = ha->brd; | 3113 | dp2_ptr = ha->brd; |
3483 | if (IStatus & 0x80) { /* error flag */ | 3114 | if (IStatus & 0x80) { /* error flag */ |
3484 | IStatus &= ~0x80; | 3115 | IStatus &= ~0x80; |
3485 | ha->status = gdth_readw(&dp2_ptr->u.ic.Status); | 3116 | ha->status = readw(&dp2_ptr->u.ic.Status); |
3486 | TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); | 3117 | TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); |
3487 | } else /* no error */ | 3118 | } else /* no error */ |
3488 | ha->status = S_OK; | 3119 | ha->status = S_OK; |
3489 | ha->info = gdth_readl(&dp2_ptr->u.ic.Info[0]); | 3120 | ha->info = readl(&dp2_ptr->u.ic.Info[0]); |
3490 | ha->service = gdth_readw(&dp2_ptr->u.ic.Service); | 3121 | ha->service = readw(&dp2_ptr->u.ic.Service); |
3491 | ha->info2 = gdth_readl(&dp2_ptr->u.ic.Info[1]); | 3122 | ha->info2 = readl(&dp2_ptr->u.ic.Info[1]); |
3492 | 3123 | ||
3493 | gdth_writeb(0xff, &dp2_ptr->io.irqdel); /* acknowledge interrupt */ | 3124 | writeb(0xff, &dp2_ptr->io.irqdel); /* acknowledge interrupt */ |
3494 | gdth_writeb(0, &dp2_ptr->u.ic.Cmd_Index);/* reset command index */ | 3125 | writeb(0, &dp2_ptr->u.ic.Cmd_Index);/* reset command index */ |
3495 | gdth_writeb(0, &dp2_ptr->io.Sema1); /* reset status semaphore */ | 3126 | writeb(0, &dp2_ptr->io.Sema1); /* reset status semaphore */ |
3496 | } else if (ha->type == GDT_PCI) { | 3127 | } else if (ha->type == GDT_PCI) { |
3497 | dp6_ptr = ha->brd; | 3128 | dp6_ptr = ha->brd; |
3498 | if (IStatus & 0x80) { /* error flag */ | 3129 | if (IStatus & 0x80) { /* error flag */ |
3499 | IStatus &= ~0x80; | 3130 | IStatus &= ~0x80; |
3500 | ha->status = gdth_readw(&dp6_ptr->u.ic.Status); | 3131 | ha->status = readw(&dp6_ptr->u.ic.Status); |
3501 | TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); | 3132 | TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); |
3502 | } else /* no error */ | 3133 | } else /* no error */ |
3503 | ha->status = S_OK; | 3134 | ha->status = S_OK; |
3504 | ha->info = gdth_readl(&dp6_ptr->u.ic.Info[0]); | 3135 | ha->info = readl(&dp6_ptr->u.ic.Info[0]); |
3505 | ha->service = gdth_readw(&dp6_ptr->u.ic.Service); | 3136 | ha->service = readw(&dp6_ptr->u.ic.Service); |
3506 | ha->info2 = gdth_readl(&dp6_ptr->u.ic.Info[1]); | 3137 | ha->info2 = readl(&dp6_ptr->u.ic.Info[1]); |
3507 | 3138 | ||
3508 | gdth_writeb(0xff, &dp6_ptr->io.irqdel); /* acknowledge interrupt */ | 3139 | writeb(0xff, &dp6_ptr->io.irqdel); /* acknowledge interrupt */ |
3509 | gdth_writeb(0, &dp6_ptr->u.ic.Cmd_Index);/* reset command index */ | 3140 | writeb(0, &dp6_ptr->u.ic.Cmd_Index);/* reset command index */ |
3510 | gdth_writeb(0, &dp6_ptr->io.Sema1); /* reset status semaphore */ | 3141 | writeb(0, &dp6_ptr->io.Sema1); /* reset status semaphore */ |
3511 | } else if (ha->type == GDT_PCINEW) { | 3142 | } else if (ha->type == GDT_PCINEW) { |
3512 | if (IStatus & 0x80) { /* error flag */ | 3143 | if (IStatus & 0x80) { /* error flag */ |
3513 | IStatus &= ~0x80; | 3144 | IStatus &= ~0x80; |
@@ -3530,7 +3161,7 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3530 | ha->status = pcs->ext_status & 0xffff; | 3161 | ha->status = pcs->ext_status & 0xffff; |
3531 | else | 3162 | else |
3532 | #endif | 3163 | #endif |
3533 | ha->status = gdth_readw(&dp6m_ptr->i960r.status); | 3164 | ha->status = readw(&dp6m_ptr->i960r.status); |
3534 | TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); | 3165 | TRACE2(("gdth_interrupt() error %d/%d\n",IStatus,ha->status)); |
3535 | } else /* no error */ | 3166 | } else /* no error */ |
3536 | ha->status = S_OK; | 3167 | ha->status = S_OK; |
@@ -3543,18 +3174,18 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3543 | } else | 3174 | } else |
3544 | #endif | 3175 | #endif |
3545 | { | 3176 | { |
3546 | ha->info = gdth_readl(&dp6m_ptr->i960r.info[0]); | 3177 | ha->info = readl(&dp6m_ptr->i960r.info[0]); |
3547 | ha->service = gdth_readw(&dp6m_ptr->i960r.service); | 3178 | ha->service = readw(&dp6m_ptr->i960r.service); |
3548 | ha->info2 = gdth_readl(&dp6m_ptr->i960r.info[1]); | 3179 | ha->info2 = readl(&dp6m_ptr->i960r.info[1]); |
3549 | } | 3180 | } |
3550 | /* event string */ | 3181 | /* event string */ |
3551 | if (IStatus == ASYNCINDEX) { | 3182 | if (IStatus == ASYNCINDEX) { |
3552 | if (ha->service != SCREENSERVICE && | 3183 | if (ha->service != SCREENSERVICE && |
3553 | (ha->fw_vers & 0xff) >= 0x1a) { | 3184 | (ha->fw_vers & 0xff) >= 0x1a) { |
3554 | ha->dvr.severity = gdth_readb | 3185 | ha->dvr.severity = readb |
3555 | (&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.severity); | 3186 | (&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.severity); |
3556 | for (i = 0; i < 256; ++i) { | 3187 | for (i = 0; i < 256; ++i) { |
3557 | ha->dvr.event_string[i] = gdth_readb | 3188 | ha->dvr.event_string[i] = readb |
3558 | (&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.evt_str[i]); | 3189 | (&((gdt6m_dpram_str __iomem *)ha->brd)->i960r.evt_str[i]); |
3559 | if (ha->dvr.event_string[i] == 0) | 3190 | if (ha->dvr.event_string[i] == 0) |
3560 | break; | 3191 | break; |
@@ -3567,13 +3198,13 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3567 | if (!coalesced) | 3198 | if (!coalesced) |
3568 | #endif | 3199 | #endif |
3569 | { | 3200 | { |
3570 | gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg); | 3201 | writeb(0xff, &dp6m_ptr->i960r.edoor_reg); |
3571 | gdth_writeb(0, &dp6m_ptr->i960r.sema1_reg); | 3202 | writeb(0, &dp6m_ptr->i960r.sema1_reg); |
3572 | } | 3203 | } |
3573 | } else { | 3204 | } else { |
3574 | TRACE2(("gdth_interrupt() unknown controller type\n")); | 3205 | TRACE2(("gdth_interrupt() unknown controller type\n")); |
3575 | if (!gdth_polling) | 3206 | if (!gdth_polling) |
3576 | spin_unlock_irqrestore(&ha2->smp_lock, flags); | 3207 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
3577 | return IRQ_HANDLED; | 3208 | return IRQ_HANDLED; |
3578 | } | 3209 | } |
3579 | 3210 | ||
@@ -3581,26 +3212,25 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3581 | IStatus,ha->status,ha->info)); | 3212 | IStatus,ha->status,ha->info)); |
3582 | 3213 | ||
3583 | if (gdth_from_wait) { | 3214 | if (gdth_from_wait) { |
3584 | wait_hanum = hanum; | 3215 | *pIndex = (int)IStatus; |
3585 | wait_index = (int)IStatus; | ||
3586 | } | 3216 | } |
3587 | 3217 | ||
3588 | if (IStatus == ASYNCINDEX) { | 3218 | if (IStatus == ASYNCINDEX) { |
3589 | TRACE2(("gdth_interrupt() async. event\n")); | 3219 | TRACE2(("gdth_interrupt() async. event\n")); |
3590 | gdth_async_event(hanum); | 3220 | gdth_async_event(ha); |
3591 | if (!gdth_polling) | 3221 | if (!gdth_polling) |
3592 | spin_unlock_irqrestore(&ha2->smp_lock, flags); | 3222 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
3593 | gdth_next(hanum); | 3223 | gdth_next(ha); |
3594 | return IRQ_HANDLED; | 3224 | return IRQ_HANDLED; |
3595 | } | 3225 | } |
3596 | 3226 | ||
3597 | if (IStatus == SPEZINDEX) { | 3227 | if (IStatus == SPEZINDEX) { |
3598 | TRACE2(("Service unknown or not initialized !\n")); | 3228 | TRACE2(("Service unknown or not initialized !\n")); |
3599 | ha->dvr.size = sizeof(ha->dvr.eu.driver); | 3229 | ha->dvr.size = sizeof(ha->dvr.eu.driver); |
3600 | ha->dvr.eu.driver.ionode = hanum; | 3230 | ha->dvr.eu.driver.ionode = ha->hanum; |
3601 | gdth_store_event(ha, ES_DRIVER, 4, &ha->dvr); | 3231 | gdth_store_event(ha, ES_DRIVER, 4, &ha->dvr); |
3602 | if (!gdth_polling) | 3232 | if (!gdth_polling) |
3603 | spin_unlock_irqrestore(&ha2->smp_lock, flags); | 3233 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
3604 | return IRQ_HANDLED; | 3234 | return IRQ_HANDLED; |
3605 | } | 3235 | } |
3606 | scp = ha->cmd_tab[IStatus-2].cmnd; | 3236 | scp = ha->cmd_tab[IStatus-2].cmnd; |
@@ -3609,28 +3239,28 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3609 | if (scp == UNUSED_CMND) { | 3239 | if (scp == UNUSED_CMND) { |
3610 | TRACE2(("gdth_interrupt() index to unused command (%d)\n",IStatus)); | 3240 | TRACE2(("gdth_interrupt() index to unused command (%d)\n",IStatus)); |
3611 | ha->dvr.size = sizeof(ha->dvr.eu.driver); | 3241 | ha->dvr.size = sizeof(ha->dvr.eu.driver); |
3612 | ha->dvr.eu.driver.ionode = hanum; | 3242 | ha->dvr.eu.driver.ionode = ha->hanum; |
3613 | ha->dvr.eu.driver.index = IStatus; | 3243 | ha->dvr.eu.driver.index = IStatus; |
3614 | gdth_store_event(ha, ES_DRIVER, 1, &ha->dvr); | 3244 | gdth_store_event(ha, ES_DRIVER, 1, &ha->dvr); |
3615 | if (!gdth_polling) | 3245 | if (!gdth_polling) |
3616 | spin_unlock_irqrestore(&ha2->smp_lock, flags); | 3246 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
3617 | return IRQ_HANDLED; | 3247 | return IRQ_HANDLED; |
3618 | } | 3248 | } |
3619 | if (scp == INTERNAL_CMND) { | 3249 | if (scp == INTERNAL_CMND) { |
3620 | TRACE(("gdth_interrupt() answer to internal command\n")); | 3250 | TRACE(("gdth_interrupt() answer to internal command\n")); |
3621 | if (!gdth_polling) | 3251 | if (!gdth_polling) |
3622 | spin_unlock_irqrestore(&ha2->smp_lock, flags); | 3252 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
3623 | return IRQ_HANDLED; | 3253 | return IRQ_HANDLED; |
3624 | } | 3254 | } |
3625 | 3255 | ||
3626 | TRACE(("gdth_interrupt() sync. status\n")); | 3256 | TRACE(("gdth_interrupt() sync. status\n")); |
3627 | rval = gdth_sync_event(hanum,Service,IStatus,scp); | 3257 | rval = gdth_sync_event(ha,Service,IStatus,scp); |
3628 | if (!gdth_polling) | 3258 | if (!gdth_polling) |
3629 | spin_unlock_irqrestore(&ha2->smp_lock, flags); | 3259 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
3630 | if (rval == 2) { | 3260 | if (rval == 2) { |
3631 | gdth_putq(hanum,scp,scp->SCp.this_residual); | 3261 | gdth_putq(ha, scp, gdth_cmnd_priv(scp)->priority); |
3632 | } else if (rval == 1) { | 3262 | } else if (rval == 1) { |
3633 | scp->scsi_done(scp); | 3263 | gdth_scsi_done(scp); |
3634 | } | 3264 | } |
3635 | 3265 | ||
3636 | #ifdef INT_COAL | 3266 | #ifdef INT_COAL |
@@ -3653,23 +3283,30 @@ static irqreturn_t gdth_interrupt(int irq,void *dev_id) | |||
3653 | 3283 | ||
3654 | /* coalescing only for new GDT_PCIMPR controllers available */ | 3284 | /* coalescing only for new GDT_PCIMPR controllers available */ |
3655 | if (ha->type == GDT_PCIMPR && coalesced) { | 3285 | if (ha->type == GDT_PCIMPR && coalesced) { |
3656 | gdth_writeb(0xff, &dp6m_ptr->i960r.edoor_reg); | 3286 | writeb(0xff, &dp6m_ptr->i960r.edoor_reg); |
3657 | gdth_writeb(0, &dp6m_ptr->i960r.sema1_reg); | 3287 | writeb(0, &dp6m_ptr->i960r.sema1_reg); |
3658 | } | 3288 | } |
3659 | #endif | 3289 | #endif |
3660 | 3290 | ||
3661 | gdth_next(hanum); | 3291 | gdth_next(ha); |
3662 | return IRQ_HANDLED; | 3292 | return IRQ_HANDLED; |
3663 | } | 3293 | } |
3664 | 3294 | ||
3665 | static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) | 3295 | static irqreturn_t gdth_interrupt(int irq, void *dev_id) |
3296 | { | ||
3297 | gdth_ha_str *ha = (gdth_ha_str *)dev_id; | ||
3298 | |||
3299 | return __gdth_interrupt(ha, irq, false, NULL); | ||
3300 | } | ||
3301 | |||
3302 | static int gdth_sync_event(gdth_ha_str *ha, int service, unchar index, | ||
3303 | Scsi_Cmnd *scp) | ||
3666 | { | 3304 | { |
3667 | register gdth_ha_str *ha; | ||
3668 | gdth_msg_str *msg; | 3305 | gdth_msg_str *msg; |
3669 | gdth_cmd_str *cmdp; | 3306 | gdth_cmd_str *cmdp; |
3670 | unchar b, t; | 3307 | unchar b, t; |
3308 | struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); | ||
3671 | 3309 | ||
3672 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
3673 | cmdp = ha->pccb; | 3310 | cmdp = ha->pccb; |
3674 | TRACE(("gdth_sync_event() serv %d status %d\n", | 3311 | TRACE(("gdth_sync_event() serv %d status %d\n", |
3675 | service,ha->status)); | 3312 | service,ha->status)); |
@@ -3687,12 +3324,12 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) | |||
3687 | } | 3324 | } |
3688 | 3325 | ||
3689 | if (msg->msg_ext && !msg->msg_answer) { | 3326 | if (msg->msg_ext && !msg->msg_answer) { |
3690 | while (gdth_test_busy(hanum)) | 3327 | while (gdth_test_busy(ha)) |
3691 | gdth_delay(0); | 3328 | gdth_delay(0); |
3692 | cmdp->Service = SCREENSERVICE; | 3329 | cmdp->Service = SCREENSERVICE; |
3693 | cmdp->RequestBuffer = SCREEN_CMND; | 3330 | cmdp->RequestBuffer = SCREEN_CMND; |
3694 | gdth_get_cmd_index(hanum); | 3331 | gdth_get_cmd_index(ha); |
3695 | gdth_set_sema0(hanum); | 3332 | gdth_set_sema0(ha); |
3696 | cmdp->OpCode = GDT_READ; | 3333 | cmdp->OpCode = GDT_READ; |
3697 | cmdp->BoardNode = LOCALBOARD; | 3334 | cmdp->BoardNode = LOCALBOARD; |
3698 | cmdp->u.screen.reserved = 0; | 3335 | cmdp->u.screen.reserved = 0; |
@@ -3702,8 +3339,8 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) | |||
3702 | ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) | 3339 | ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) |
3703 | + sizeof(ulong64); | 3340 | + sizeof(ulong64); |
3704 | ha->cmd_cnt = 0; | 3341 | ha->cmd_cnt = 0; |
3705 | gdth_copy_command(hanum); | 3342 | gdth_copy_command(ha); |
3706 | gdth_release_event(hanum); | 3343 | gdth_release_event(ha); |
3707 | return 0; | 3344 | return 0; |
3708 | } | 3345 | } |
3709 | 3346 | ||
@@ -3721,12 +3358,12 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) | |||
3721 | } | 3358 | } |
3722 | msg->msg_ext = 0; | 3359 | msg->msg_ext = 0; |
3723 | msg->msg_answer = 0; | 3360 | msg->msg_answer = 0; |
3724 | while (gdth_test_busy(hanum)) | 3361 | while (gdth_test_busy(ha)) |
3725 | gdth_delay(0); | 3362 | gdth_delay(0); |
3726 | cmdp->Service = SCREENSERVICE; | 3363 | cmdp->Service = SCREENSERVICE; |
3727 | cmdp->RequestBuffer = SCREEN_CMND; | 3364 | cmdp->RequestBuffer = SCREEN_CMND; |
3728 | gdth_get_cmd_index(hanum); | 3365 | gdth_get_cmd_index(ha); |
3729 | gdth_set_sema0(hanum); | 3366 | gdth_set_sema0(ha); |
3730 | cmdp->OpCode = GDT_WRITE; | 3367 | cmdp->OpCode = GDT_WRITE; |
3731 | cmdp->BoardNode = LOCALBOARD; | 3368 | cmdp->BoardNode = LOCALBOARD; |
3732 | cmdp->u.screen.reserved = 0; | 3369 | cmdp->u.screen.reserved = 0; |
@@ -3736,74 +3373,67 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) | |||
3736 | ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) | 3373 | ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) |
3737 | + sizeof(ulong64); | 3374 | + sizeof(ulong64); |
3738 | ha->cmd_cnt = 0; | 3375 | ha->cmd_cnt = 0; |
3739 | gdth_copy_command(hanum); | 3376 | gdth_copy_command(ha); |
3740 | gdth_release_event(hanum); | 3377 | gdth_release_event(ha); |
3741 | return 0; | 3378 | return 0; |
3742 | } | 3379 | } |
3743 | printk("\n"); | 3380 | printk("\n"); |
3744 | 3381 | ||
3745 | } else { | 3382 | } else { |
3746 | b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; | 3383 | b = scp->device->channel; |
3747 | t = scp->device->id; | 3384 | t = scp->device->id; |
3748 | if (scp->SCp.sent_command == -1 && b != ha->virt_bus) { | 3385 | if (cmndinfo->OpCode == -1 && b != ha->virt_bus) { |
3749 | ha->raw[BUS_L2P(ha,b)].io_cnt[t]--; | 3386 | ha->raw[BUS_L2P(ha,b)].io_cnt[t]--; |
3750 | } | 3387 | } |
3751 | /* cache or raw service */ | 3388 | /* cache or raw service */ |
3752 | if (ha->status == S_BSY) { | 3389 | if (ha->status == S_BSY) { |
3753 | TRACE2(("Controller busy -> retry !\n")); | 3390 | TRACE2(("Controller busy -> retry !\n")); |
3754 | if (scp->SCp.sent_command == GDT_MOUNT) | 3391 | if (cmndinfo->OpCode == GDT_MOUNT) |
3755 | scp->SCp.sent_command = GDT_CLUST_INFO; | 3392 | cmndinfo->OpCode = GDT_CLUST_INFO; |
3756 | /* retry */ | 3393 | /* retry */ |
3757 | return 2; | 3394 | return 2; |
3758 | } | 3395 | } |
3759 | if (scp->SCp.Status == GDTH_MAP_SG) | 3396 | if (gdth_bufflen(scp)) |
3760 | pci_unmap_sg(ha->pdev,scp->request_buffer, | 3397 | pci_unmap_sg(ha->pdev, gdth_sglist(scp), gdth_sg_count(scp), |
3761 | scp->use_sg,scp->SCp.Message); | 3398 | cmndinfo->dma_dir); |
3762 | else if (scp->SCp.Status == GDTH_MAP_SINGLE) | 3399 | |
3763 | pci_unmap_page(ha->pdev,scp->SCp.dma_handle, | 3400 | if (cmndinfo->sense_paddr) |
3764 | scp->request_bufflen,scp->SCp.Message); | 3401 | pci_unmap_page(ha->pdev, cmndinfo->sense_paddr, 16, |
3765 | if (scp->SCp.buffer) { | 3402 | PCI_DMA_FROMDEVICE); |
3766 | dma_addr_t addr; | ||
3767 | addr = (dma_addr_t)*(ulong32 *)&scp->SCp.buffer; | ||
3768 | if (scp->host_scribble) | ||
3769 | addr += (dma_addr_t) | ||
3770 | ((ulong64)(*(ulong32 *)&scp->host_scribble) << 32); | ||
3771 | pci_unmap_page(ha->pdev,addr,16,PCI_DMA_FROMDEVICE); | ||
3772 | } | ||
3773 | 3403 | ||
3774 | if (ha->status == S_OK) { | 3404 | if (ha->status == S_OK) { |
3775 | scp->SCp.Status = S_OK; | 3405 | cmndinfo->status = S_OK; |
3776 | scp->SCp.Message = ha->info; | 3406 | cmndinfo->info = ha->info; |
3777 | if (scp->SCp.sent_command != -1) { | 3407 | if (cmndinfo->OpCode != -1) { |
3778 | TRACE2(("gdth_sync_event(): special cmd 0x%x OK\n", | 3408 | TRACE2(("gdth_sync_event(): special cmd 0x%x OK\n", |
3779 | scp->SCp.sent_command)); | 3409 | cmndinfo->OpCode)); |
3780 | /* special commands GDT_CLUST_INFO/GDT_MOUNT ? */ | 3410 | /* special commands GDT_CLUST_INFO/GDT_MOUNT ? */ |
3781 | if (scp->SCp.sent_command == GDT_CLUST_INFO) { | 3411 | if (cmndinfo->OpCode == GDT_CLUST_INFO) { |
3782 | ha->hdr[t].cluster_type = (unchar)ha->info; | 3412 | ha->hdr[t].cluster_type = (unchar)ha->info; |
3783 | if (!(ha->hdr[t].cluster_type & | 3413 | if (!(ha->hdr[t].cluster_type & |
3784 | CLUSTER_MOUNTED)) { | 3414 | CLUSTER_MOUNTED)) { |
3785 | /* NOT MOUNTED -> MOUNT */ | 3415 | /* NOT MOUNTED -> MOUNT */ |
3786 | scp->SCp.sent_command = GDT_MOUNT; | 3416 | cmndinfo->OpCode = GDT_MOUNT; |
3787 | if (ha->hdr[t].cluster_type & | 3417 | if (ha->hdr[t].cluster_type & |
3788 | CLUSTER_RESERVED) { | 3418 | CLUSTER_RESERVED) { |
3789 | /* cluster drive RESERVED (on the other node) */ | 3419 | /* cluster drive RESERVED (on the other node) */ |
3790 | scp->SCp.phase = -2; /* reservation conflict */ | 3420 | cmndinfo->phase = -2; /* reservation conflict */ |
3791 | } | 3421 | } |
3792 | } else { | 3422 | } else { |
3793 | scp->SCp.sent_command = -1; | 3423 | cmndinfo->OpCode = -1; |
3794 | } | 3424 | } |
3795 | } else { | 3425 | } else { |
3796 | if (scp->SCp.sent_command == GDT_MOUNT) { | 3426 | if (cmndinfo->OpCode == GDT_MOUNT) { |
3797 | ha->hdr[t].cluster_type |= CLUSTER_MOUNTED; | 3427 | ha->hdr[t].cluster_type |= CLUSTER_MOUNTED; |
3798 | ha->hdr[t].media_changed = TRUE; | 3428 | ha->hdr[t].media_changed = TRUE; |
3799 | } else if (scp->SCp.sent_command == GDT_UNMOUNT) { | 3429 | } else if (cmndinfo->OpCode == GDT_UNMOUNT) { |
3800 | ha->hdr[t].cluster_type &= ~CLUSTER_MOUNTED; | 3430 | ha->hdr[t].cluster_type &= ~CLUSTER_MOUNTED; |
3801 | ha->hdr[t].media_changed = TRUE; | 3431 | ha->hdr[t].media_changed = TRUE; |
3802 | } | 3432 | } |
3803 | scp->SCp.sent_command = -1; | 3433 | cmndinfo->OpCode = -1; |
3804 | } | 3434 | } |
3805 | /* retry */ | 3435 | /* retry */ |
3806 | scp->SCp.this_residual = HIGH_PRI; | 3436 | cmndinfo->priority = HIGH_PRI; |
3807 | return 2; | 3437 | return 2; |
3808 | } else { | 3438 | } else { |
3809 | /* RESERVE/RELEASE ? */ | 3439 | /* RESERVE/RELEASE ? */ |
@@ -3816,17 +3446,17 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) | |||
3816 | scp->sense_buffer[0] = 0; | 3446 | scp->sense_buffer[0] = 0; |
3817 | } | 3447 | } |
3818 | } else { | 3448 | } else { |
3819 | scp->SCp.Status = ha->status; | 3449 | cmndinfo->status = ha->status; |
3820 | scp->SCp.Message = ha->info; | 3450 | cmndinfo->info = ha->info; |
3821 | 3451 | ||
3822 | if (scp->SCp.sent_command != -1) { | 3452 | if (cmndinfo->OpCode != -1) { |
3823 | TRACE2(("gdth_sync_event(): special cmd 0x%x error 0x%x\n", | 3453 | TRACE2(("gdth_sync_event(): special cmd 0x%x error 0x%x\n", |
3824 | scp->SCp.sent_command, ha->status)); | 3454 | cmndinfo->OpCode, ha->status)); |
3825 | if (scp->SCp.sent_command == GDT_SCAN_START || | 3455 | if (cmndinfo->OpCode == GDT_SCAN_START || |
3826 | scp->SCp.sent_command == GDT_SCAN_END) { | 3456 | cmndinfo->OpCode == GDT_SCAN_END) { |
3827 | scp->SCp.sent_command = -1; | 3457 | cmndinfo->OpCode = -1; |
3828 | /* retry */ | 3458 | /* retry */ |
3829 | scp->SCp.this_residual = HIGH_PRI; | 3459 | cmndinfo->priority = HIGH_PRI; |
3830 | return 2; | 3460 | return 2; |
3831 | } | 3461 | } |
3832 | memset((char*)scp->sense_buffer,0,16); | 3462 | memset((char*)scp->sense_buffer,0,16); |
@@ -3848,9 +3478,9 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) | |||
3848 | scp->sense_buffer[2] = NOT_READY; | 3478 | scp->sense_buffer[2] = NOT_READY; |
3849 | scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); | 3479 | scp->result = (DID_OK << 16) | (CHECK_CONDITION << 1); |
3850 | } | 3480 | } |
3851 | if (scp->done != gdth_scsi_done) { | 3481 | if (!cmndinfo->internal_command) { |
3852 | ha->dvr.size = sizeof(ha->dvr.eu.sync); | 3482 | ha->dvr.size = sizeof(ha->dvr.eu.sync); |
3853 | ha->dvr.eu.sync.ionode = hanum; | 3483 | ha->dvr.eu.sync.ionode = ha->hanum; |
3854 | ha->dvr.eu.sync.service = service; | 3484 | ha->dvr.eu.sync.service = service; |
3855 | ha->dvr.eu.sync.status = ha->status; | 3485 | ha->dvr.eu.sync.status = ha->status; |
3856 | ha->dvr.eu.sync.info = ha->info; | 3486 | ha->dvr.eu.sync.info = ha->info; |
@@ -3869,8 +3499,8 @@ static int gdth_sync_event(int hanum,int service,unchar index,Scsi_Cmnd *scp) | |||
3869 | } | 3499 | } |
3870 | } | 3500 | } |
3871 | } | 3501 | } |
3872 | if (!scp->SCp.have_data_in) | 3502 | if (!cmndinfo->wait_for_completion) |
3873 | scp->SCp.have_data_in++; | 3503 | cmndinfo->wait_for_completion++; |
3874 | else | 3504 | else |
3875 | return 1; | 3505 | return 1; |
3876 | } | 3506 | } |
@@ -4034,25 +3664,23 @@ static char *async_cache_tab[] = { | |||
4034 | }; | 3664 | }; |
4035 | 3665 | ||
4036 | 3666 | ||
4037 | static int gdth_async_event(int hanum) | 3667 | static int gdth_async_event(gdth_ha_str *ha) |
4038 | { | 3668 | { |
4039 | gdth_ha_str *ha; | ||
4040 | gdth_cmd_str *cmdp; | 3669 | gdth_cmd_str *cmdp; |
4041 | int cmd_index; | 3670 | int cmd_index; |
4042 | 3671 | ||
4043 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
4044 | cmdp= ha->pccb; | 3672 | cmdp= ha->pccb; |
4045 | TRACE2(("gdth_async_event() ha %d serv %d\n", | 3673 | TRACE2(("gdth_async_event() ha %d serv %d\n", |
4046 | hanum,ha->service)); | 3674 | ha->hanum, ha->service)); |
4047 | 3675 | ||
4048 | if (ha->service == SCREENSERVICE) { | 3676 | if (ha->service == SCREENSERVICE) { |
4049 | if (ha->status == MSG_REQUEST) { | 3677 | if (ha->status == MSG_REQUEST) { |
4050 | while (gdth_test_busy(hanum)) | 3678 | while (gdth_test_busy(ha)) |
4051 | gdth_delay(0); | 3679 | gdth_delay(0); |
4052 | cmdp->Service = SCREENSERVICE; | 3680 | cmdp->Service = SCREENSERVICE; |
4053 | cmdp->RequestBuffer = SCREEN_CMND; | 3681 | cmdp->RequestBuffer = SCREEN_CMND; |
4054 | cmd_index = gdth_get_cmd_index(hanum); | 3682 | cmd_index = gdth_get_cmd_index(ha); |
4055 | gdth_set_sema0(hanum); | 3683 | gdth_set_sema0(ha); |
4056 | cmdp->OpCode = GDT_READ; | 3684 | cmdp->OpCode = GDT_READ; |
4057 | cmdp->BoardNode = LOCALBOARD; | 3685 | cmdp->BoardNode = LOCALBOARD; |
4058 | cmdp->u.screen.reserved = 0; | 3686 | cmdp->u.screen.reserved = 0; |
@@ -4062,7 +3690,7 @@ static int gdth_async_event(int hanum) | |||
4062 | ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) | 3690 | ha->cmd_len = GDTOFFSOF(gdth_cmd_str,u.screen.su.msg.msg_addr) |
4063 | + sizeof(ulong64); | 3691 | + sizeof(ulong64); |
4064 | ha->cmd_cnt = 0; | 3692 | ha->cmd_cnt = 0; |
4065 | gdth_copy_command(hanum); | 3693 | gdth_copy_command(ha); |
4066 | if (ha->type == GDT_EISA) | 3694 | if (ha->type == GDT_EISA) |
4067 | printk("[EISA slot %d] ",(ushort)ha->brd_phys); | 3695 | printk("[EISA slot %d] ",(ushort)ha->brd_phys); |
4068 | else if (ha->type == GDT_ISA) | 3696 | else if (ha->type == GDT_ISA) |
@@ -4070,19 +3698,19 @@ static int gdth_async_event(int hanum) | |||
4070 | else | 3698 | else |
4071 | printk("[PCI %d/%d] ",(ushort)(ha->brd_phys>>8), | 3699 | printk("[PCI %d/%d] ",(ushort)(ha->brd_phys>>8), |
4072 | (ushort)((ha->brd_phys>>3)&0x1f)); | 3700 | (ushort)((ha->brd_phys>>3)&0x1f)); |
4073 | gdth_release_event(hanum); | 3701 | gdth_release_event(ha); |
4074 | } | 3702 | } |
4075 | 3703 | ||
4076 | } else { | 3704 | } else { |
4077 | if (ha->type == GDT_PCIMPR && | 3705 | if (ha->type == GDT_PCIMPR && |
4078 | (ha->fw_vers & 0xff) >= 0x1a) { | 3706 | (ha->fw_vers & 0xff) >= 0x1a) { |
4079 | ha->dvr.size = 0; | 3707 | ha->dvr.size = 0; |
4080 | ha->dvr.eu.async.ionode = hanum; | 3708 | ha->dvr.eu.async.ionode = ha->hanum; |
4081 | ha->dvr.eu.async.status = ha->status; | 3709 | ha->dvr.eu.async.status = ha->status; |
4082 | /* severity and event_string already set! */ | 3710 | /* severity and event_string already set! */ |
4083 | } else { | 3711 | } else { |
4084 | ha->dvr.size = sizeof(ha->dvr.eu.async); | 3712 | ha->dvr.size = sizeof(ha->dvr.eu.async); |
4085 | ha->dvr.eu.async.ionode = hanum; | 3713 | ha->dvr.eu.async.ionode = ha->hanum; |
4086 | ha->dvr.eu.async.service = ha->service; | 3714 | ha->dvr.eu.async.service = ha->service; |
4087 | ha->dvr.eu.async.status = ha->status; | 3715 | ha->dvr.eu.async.status = ha->status; |
4088 | ha->dvr.eu.async.info = ha->info; | 3716 | ha->dvr.eu.async.info = ha->info; |
@@ -4164,9 +3792,8 @@ static void gdth_timeout(ulong data) | |||
4164 | Scsi_Cmnd *nscp; | 3792 | Scsi_Cmnd *nscp; |
4165 | gdth_ha_str *ha; | 3793 | gdth_ha_str *ha; |
4166 | ulong flags; | 3794 | ulong flags; |
4167 | int hanum = 0; | ||
4168 | 3795 | ||
4169 | ha = HADATA(gdth_ctr_tab[hanum]); | 3796 | ha = list_first_entry(&gdth_instances, gdth_ha_str, list); |
4170 | spin_lock_irqsave(&ha->smp_lock, flags); | 3797 | spin_lock_irqsave(&ha->smp_lock, flags); |
4171 | 3798 | ||
4172 | for (act_stats=0,i=0; i<GDTH_MAXCMDS; ++i) | 3799 | for (act_stats=0,i=0; i<GDTH_MAXCMDS; ++i) |
@@ -4229,8 +3856,6 @@ static void __init internal_setup(char *str,int *ints) | |||
4229 | max_ids = val; | 3856 | max_ids = val; |
4230 | else if (!strncmp(argv, "rescan:", 7)) | 3857 | else if (!strncmp(argv, "rescan:", 7)) |
4231 | rescan = val; | 3858 | rescan = val; |
4232 | else if (!strncmp(argv, "virt_ctr:", 9)) | ||
4233 | virt_ctr = val; | ||
4234 | else if (!strncmp(argv, "shared_access:", 14)) | 3859 | else if (!strncmp(argv, "shared_access:", 14)) |
4235 | shared_access = val; | 3860 | shared_access = val; |
4236 | else if (!strncmp(argv, "probe_eisa_isa:", 15)) | 3861 | else if (!strncmp(argv, "probe_eisa_isa:", 15)) |
@@ -4277,523 +3902,10 @@ int __init option_setup(char *str) | |||
4277 | return 1; | 3902 | return 1; |
4278 | } | 3903 | } |
4279 | 3904 | ||
4280 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 3905 | static const char *gdth_ctr_name(gdth_ha_str *ha) |
4281 | static int __init gdth_detect(struct scsi_host_template *shtp) | ||
4282 | #else | ||
4283 | static int __init gdth_detect(Scsi_Host_Template *shtp) | ||
4284 | #endif | ||
4285 | { | ||
4286 | struct Scsi_Host *shp; | ||
4287 | gdth_pci_str pcistr[MAXHA]; | ||
4288 | gdth_ha_str *ha; | ||
4289 | ulong32 isa_bios; | ||
4290 | ushort eisa_slot; | ||
4291 | int i,hanum,cnt,ctr,err; | ||
4292 | unchar b; | ||
4293 | |||
4294 | |||
4295 | #ifdef DEBUG_GDTH | ||
4296 | printk("GDT: This driver contains debugging information !! Trace level = %d\n", | ||
4297 | DebugState); | ||
4298 | printk(" Destination of debugging information: "); | ||
4299 | #ifdef __SERIAL__ | ||
4300 | #ifdef __COM2__ | ||
4301 | printk("Serial port COM2\n"); | ||
4302 | #else | ||
4303 | printk("Serial port COM1\n"); | ||
4304 | #endif | ||
4305 | #else | ||
4306 | printk("Console\n"); | ||
4307 | #endif | ||
4308 | gdth_delay(3000); | ||
4309 | #endif | ||
4310 | |||
4311 | TRACE(("gdth_detect()\n")); | ||
4312 | |||
4313 | if (disable) { | ||
4314 | printk("GDT-HA: Controller driver disabled from command line !\n"); | ||
4315 | return 0; | ||
4316 | } | ||
4317 | |||
4318 | printk("GDT-HA: Storage RAID Controller Driver. Version: %s\n",GDTH_VERSION_STR); | ||
4319 | /* initializations */ | ||
4320 | gdth_polling = TRUE; b = 0; | ||
4321 | gdth_clear_events(); | ||
4322 | |||
4323 | /* As default we do not probe for EISA or ISA controllers */ | ||
4324 | if (probe_eisa_isa) { | ||
4325 | /* scanning for controllers, at first: ISA controller */ | ||
4326 | for (isa_bios=0xc8000UL; isa_bios<=0xd8000UL; isa_bios+=0x8000UL) { | ||
4327 | dma_addr_t scratch_dma_handle; | ||
4328 | scratch_dma_handle = 0; | ||
4329 | |||
4330 | if (gdth_ctr_count >= MAXHA) | ||
4331 | break; | ||
4332 | if (gdth_search_isa(isa_bios)) { /* controller found */ | ||
4333 | shp = scsi_register(shtp,sizeof(gdth_ext_str)); | ||
4334 | if (shp == NULL) | ||
4335 | continue; | ||
4336 | |||
4337 | ha = HADATA(shp); | ||
4338 | if (!gdth_init_isa(isa_bios,ha)) { | ||
4339 | scsi_unregister(shp); | ||
4340 | continue; | ||
4341 | } | ||
4342 | #ifdef __ia64__ | ||
4343 | break; | ||
4344 | #else | ||
4345 | /* controller found and initialized */ | ||
4346 | printk("Configuring GDT-ISA HA at BIOS 0x%05X IRQ %u DRQ %u\n", | ||
4347 | isa_bios,ha->irq,ha->drq); | ||
4348 | |||
4349 | if (request_irq(ha->irq,gdth_interrupt,IRQF_DISABLED,"gdth",ha)) { | ||
4350 | printk("GDT-ISA: Unable to allocate IRQ\n"); | ||
4351 | scsi_unregister(shp); | ||
4352 | continue; | ||
4353 | } | ||
4354 | if (request_dma(ha->drq,"gdth")) { | ||
4355 | printk("GDT-ISA: Unable to allocate DMA channel\n"); | ||
4356 | free_irq(ha->irq,ha); | ||
4357 | scsi_unregister(shp); | ||
4358 | continue; | ||
4359 | } | ||
4360 | set_dma_mode(ha->drq,DMA_MODE_CASCADE); | ||
4361 | enable_dma(ha->drq); | ||
4362 | shp->unchecked_isa_dma = 1; | ||
4363 | shp->irq = ha->irq; | ||
4364 | shp->dma_channel = ha->drq; | ||
4365 | hanum = gdth_ctr_count; | ||
4366 | gdth_ctr_tab[gdth_ctr_count++] = shp; | ||
4367 | gdth_ctr_vtab[gdth_ctr_vcount++] = shp; | ||
4368 | |||
4369 | NUMDATA(shp)->hanum = (ushort)hanum; | ||
4370 | NUMDATA(shp)->busnum= 0; | ||
4371 | |||
4372 | ha->pccb = CMDDATA(shp); | ||
4373 | ha->ccb_phys = 0L; | ||
4374 | ha->pdev = NULL; | ||
4375 | ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, | ||
4376 | &scratch_dma_handle); | ||
4377 | ha->scratch_phys = scratch_dma_handle; | ||
4378 | ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4379 | &scratch_dma_handle); | ||
4380 | ha->msg_phys = scratch_dma_handle; | ||
4381 | #ifdef INT_COAL | ||
4382 | ha->coal_stat = (gdth_coal_status *) | ||
4383 | pci_alloc_consistent(ha->pdev, sizeof(gdth_coal_status) * | ||
4384 | MAXOFFSETS, &scratch_dma_handle); | ||
4385 | ha->coal_stat_phys = scratch_dma_handle; | ||
4386 | #endif | ||
4387 | |||
4388 | ha->scratch_busy = FALSE; | ||
4389 | ha->req_first = NULL; | ||
4390 | ha->tid_cnt = MAX_HDRIVES; | ||
4391 | if (max_ids > 0 && max_ids < ha->tid_cnt) | ||
4392 | ha->tid_cnt = max_ids; | ||
4393 | for (i=0; i<GDTH_MAXCMDS; ++i) | ||
4394 | ha->cmd_tab[i].cmnd = UNUSED_CMND; | ||
4395 | ha->scan_mode = rescan ? 0x10 : 0; | ||
4396 | |||
4397 | if (ha->pscratch == NULL || ha->pmsg == NULL || | ||
4398 | !gdth_search_drives(hanum)) { | ||
4399 | printk("GDT-ISA: Error during device scan\n"); | ||
4400 | --gdth_ctr_count; | ||
4401 | --gdth_ctr_vcount; | ||
4402 | |||
4403 | #ifdef INT_COAL | ||
4404 | if (ha->coal_stat) | ||
4405 | pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * | ||
4406 | MAXOFFSETS, ha->coal_stat, | ||
4407 | ha->coal_stat_phys); | ||
4408 | #endif | ||
4409 | if (ha->pscratch) | ||
4410 | pci_free_consistent(ha->pdev, GDTH_SCRATCH, | ||
4411 | ha->pscratch, ha->scratch_phys); | ||
4412 | if (ha->pmsg) | ||
4413 | pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4414 | ha->pmsg, ha->msg_phys); | ||
4415 | |||
4416 | free_irq(ha->irq,ha); | ||
4417 | scsi_unregister(shp); | ||
4418 | continue; | ||
4419 | } | ||
4420 | if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) | ||
4421 | hdr_channel = ha->bus_cnt; | ||
4422 | ha->virt_bus = hdr_channel; | ||
4423 | |||
4424 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) && \ | ||
4425 | LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) | ||
4426 | shp->highmem_io = 0; | ||
4427 | #endif | ||
4428 | if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) | ||
4429 | shp->max_cmd_len = 16; | ||
4430 | |||
4431 | shp->max_id = ha->tid_cnt; | ||
4432 | shp->max_lun = MAXLUN; | ||
4433 | shp->max_channel = virt_ctr ? 0 : ha->bus_cnt; | ||
4434 | if (virt_ctr) { | ||
4435 | virt_ctr = 1; | ||
4436 | /* register addit. SCSI channels as virtual controllers */ | ||
4437 | for (b = 1; b < ha->bus_cnt + 1; ++b) { | ||
4438 | shp = scsi_register(shtp,sizeof(gdth_num_str)); | ||
4439 | shp->unchecked_isa_dma = 1; | ||
4440 | shp->irq = ha->irq; | ||
4441 | shp->dma_channel = ha->drq; | ||
4442 | gdth_ctr_vtab[gdth_ctr_vcount++] = shp; | ||
4443 | NUMDATA(shp)->hanum = (ushort)hanum; | ||
4444 | NUMDATA(shp)->busnum = b; | ||
4445 | } | ||
4446 | } | ||
4447 | |||
4448 | spin_lock_init(&ha->smp_lock); | ||
4449 | gdth_enable_int(hanum); | ||
4450 | #endif /* !__ia64__ */ | ||
4451 | } | ||
4452 | } | ||
4453 | |||
4454 | /* scanning for EISA controllers */ | ||
4455 | for (eisa_slot=0x1000; eisa_slot<=0x8000; eisa_slot+=0x1000) { | ||
4456 | dma_addr_t scratch_dma_handle; | ||
4457 | scratch_dma_handle = 0; | ||
4458 | |||
4459 | if (gdth_ctr_count >= MAXHA) | ||
4460 | break; | ||
4461 | if (gdth_search_eisa(eisa_slot)) { /* controller found */ | ||
4462 | shp = scsi_register(shtp,sizeof(gdth_ext_str)); | ||
4463 | if (shp == NULL) | ||
4464 | continue; | ||
4465 | |||
4466 | ha = HADATA(shp); | ||
4467 | if (!gdth_init_eisa(eisa_slot,ha)) { | ||
4468 | scsi_unregister(shp); | ||
4469 | continue; | ||
4470 | } | ||
4471 | /* controller found and initialized */ | ||
4472 | printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n", | ||
4473 | eisa_slot>>12,ha->irq); | ||
4474 | |||
4475 | if (request_irq(ha->irq,gdth_interrupt,IRQF_DISABLED,"gdth",ha)) { | ||
4476 | printk("GDT-EISA: Unable to allocate IRQ\n"); | ||
4477 | scsi_unregister(shp); | ||
4478 | continue; | ||
4479 | } | ||
4480 | shp->unchecked_isa_dma = 0; | ||
4481 | shp->irq = ha->irq; | ||
4482 | shp->dma_channel = 0xff; | ||
4483 | hanum = gdth_ctr_count; | ||
4484 | gdth_ctr_tab[gdth_ctr_count++] = shp; | ||
4485 | gdth_ctr_vtab[gdth_ctr_vcount++] = shp; | ||
4486 | |||
4487 | NUMDATA(shp)->hanum = (ushort)hanum; | ||
4488 | NUMDATA(shp)->busnum= 0; | ||
4489 | TRACE2(("EISA detect Bus 0: hanum %d\n", | ||
4490 | NUMDATA(shp)->hanum)); | ||
4491 | |||
4492 | ha->pccb = CMDDATA(shp); | ||
4493 | ha->ccb_phys = 0L; | ||
4494 | |||
4495 | ha->pdev = NULL; | ||
4496 | ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, | ||
4497 | &scratch_dma_handle); | ||
4498 | ha->scratch_phys = scratch_dma_handle; | ||
4499 | ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4500 | &scratch_dma_handle); | ||
4501 | ha->msg_phys = scratch_dma_handle; | ||
4502 | #ifdef INT_COAL | ||
4503 | ha->coal_stat = (gdth_coal_status *) | ||
4504 | pci_alloc_consistent(ha->pdev, sizeof(gdth_coal_status) * | ||
4505 | MAXOFFSETS, &scratch_dma_handle); | ||
4506 | ha->coal_stat_phys = scratch_dma_handle; | ||
4507 | #endif | ||
4508 | ha->ccb_phys = | ||
4509 | pci_map_single(ha->pdev,ha->pccb, | ||
4510 | sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL); | ||
4511 | ha->scratch_busy = FALSE; | ||
4512 | ha->req_first = NULL; | ||
4513 | ha->tid_cnt = MAX_HDRIVES; | ||
4514 | if (max_ids > 0 && max_ids < ha->tid_cnt) | ||
4515 | ha->tid_cnt = max_ids; | ||
4516 | for (i=0; i<GDTH_MAXCMDS; ++i) | ||
4517 | ha->cmd_tab[i].cmnd = UNUSED_CMND; | ||
4518 | ha->scan_mode = rescan ? 0x10 : 0; | ||
4519 | |||
4520 | if (ha->pscratch == NULL || ha->pmsg == NULL || | ||
4521 | !gdth_search_drives(hanum)) { | ||
4522 | printk("GDT-EISA: Error during device scan\n"); | ||
4523 | --gdth_ctr_count; | ||
4524 | --gdth_ctr_vcount; | ||
4525 | #ifdef INT_COAL | ||
4526 | if (ha->coal_stat) | ||
4527 | pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * | ||
4528 | MAXOFFSETS, ha->coal_stat, | ||
4529 | ha->coal_stat_phys); | ||
4530 | #endif | ||
4531 | if (ha->pscratch) | ||
4532 | pci_free_consistent(ha->pdev, GDTH_SCRATCH, | ||
4533 | ha->pscratch, ha->scratch_phys); | ||
4534 | if (ha->pmsg) | ||
4535 | pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4536 | ha->pmsg, ha->msg_phys); | ||
4537 | if (ha->ccb_phys) | ||
4538 | pci_unmap_single(ha->pdev,ha->ccb_phys, | ||
4539 | sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL); | ||
4540 | free_irq(ha->irq,ha); | ||
4541 | scsi_unregister(shp); | ||
4542 | continue; | ||
4543 | } | ||
4544 | if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) | ||
4545 | hdr_channel = ha->bus_cnt; | ||
4546 | ha->virt_bus = hdr_channel; | ||
4547 | |||
4548 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) && \ | ||
4549 | LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) | ||
4550 | shp->highmem_io = 0; | ||
4551 | #endif | ||
4552 | if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) | ||
4553 | shp->max_cmd_len = 16; | ||
4554 | |||
4555 | shp->max_id = ha->tid_cnt; | ||
4556 | shp->max_lun = MAXLUN; | ||
4557 | shp->max_channel = virt_ctr ? 0 : ha->bus_cnt; | ||
4558 | if (virt_ctr) { | ||
4559 | virt_ctr = 1; | ||
4560 | /* register addit. SCSI channels as virtual controllers */ | ||
4561 | for (b = 1; b < ha->bus_cnt + 1; ++b) { | ||
4562 | shp = scsi_register(shtp,sizeof(gdth_num_str)); | ||
4563 | shp->unchecked_isa_dma = 0; | ||
4564 | shp->irq = ha->irq; | ||
4565 | shp->dma_channel = 0xff; | ||
4566 | gdth_ctr_vtab[gdth_ctr_vcount++] = shp; | ||
4567 | NUMDATA(shp)->hanum = (ushort)hanum; | ||
4568 | NUMDATA(shp)->busnum = b; | ||
4569 | } | ||
4570 | } | ||
4571 | |||
4572 | spin_lock_init(&ha->smp_lock); | ||
4573 | gdth_enable_int(hanum); | ||
4574 | } | ||
4575 | } | ||
4576 | } | ||
4577 | |||
4578 | /* scanning for PCI controllers */ | ||
4579 | cnt = gdth_search_pci(pcistr); | ||
4580 | printk("GDT-HA: Found %d PCI Storage RAID Controllers\n",cnt); | ||
4581 | gdth_sort_pci(pcistr,cnt); | ||
4582 | for (ctr = 0; ctr < cnt; ++ctr) { | ||
4583 | dma_addr_t scratch_dma_handle; | ||
4584 | scratch_dma_handle = 0; | ||
4585 | |||
4586 | if (gdth_ctr_count >= MAXHA) | ||
4587 | break; | ||
4588 | shp = scsi_register(shtp,sizeof(gdth_ext_str)); | ||
4589 | if (shp == NULL) | ||
4590 | continue; | ||
4591 | |||
4592 | ha = HADATA(shp); | ||
4593 | if (!gdth_init_pci(&pcistr[ctr],ha)) { | ||
4594 | scsi_unregister(shp); | ||
4595 | continue; | ||
4596 | } | ||
4597 | /* controller found and initialized */ | ||
4598 | printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n", | ||
4599 | pcistr[ctr].pdev->bus->number, | ||
4600 | PCI_SLOT(pcistr[ctr].pdev->devfn), ha->irq); | ||
4601 | |||
4602 | if (request_irq(ha->irq, gdth_interrupt, | ||
4603 | IRQF_DISABLED|IRQF_SHARED, "gdth", ha)) | ||
4604 | { | ||
4605 | printk("GDT-PCI: Unable to allocate IRQ\n"); | ||
4606 | scsi_unregister(shp); | ||
4607 | continue; | ||
4608 | } | ||
4609 | shp->unchecked_isa_dma = 0; | ||
4610 | shp->irq = ha->irq; | ||
4611 | shp->dma_channel = 0xff; | ||
4612 | hanum = gdth_ctr_count; | ||
4613 | gdth_ctr_tab[gdth_ctr_count++] = shp; | ||
4614 | gdth_ctr_vtab[gdth_ctr_vcount++] = shp; | ||
4615 | |||
4616 | NUMDATA(shp)->hanum = (ushort)hanum; | ||
4617 | NUMDATA(shp)->busnum= 0; | ||
4618 | |||
4619 | ha->pccb = CMDDATA(shp); | ||
4620 | ha->ccb_phys = 0L; | ||
4621 | |||
4622 | ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, | ||
4623 | &scratch_dma_handle); | ||
4624 | ha->scratch_phys = scratch_dma_handle; | ||
4625 | ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4626 | &scratch_dma_handle); | ||
4627 | ha->msg_phys = scratch_dma_handle; | ||
4628 | #ifdef INT_COAL | ||
4629 | ha->coal_stat = (gdth_coal_status *) | ||
4630 | pci_alloc_consistent(ha->pdev, sizeof(gdth_coal_status) * | ||
4631 | MAXOFFSETS, &scratch_dma_handle); | ||
4632 | ha->coal_stat_phys = scratch_dma_handle; | ||
4633 | #endif | ||
4634 | ha->scratch_busy = FALSE; | ||
4635 | ha->req_first = NULL; | ||
4636 | ha->tid_cnt = pcistr[ctr].pdev->device >= 0x200 ? MAXID : MAX_HDRIVES; | ||
4637 | if (max_ids > 0 && max_ids < ha->tid_cnt) | ||
4638 | ha->tid_cnt = max_ids; | ||
4639 | for (i=0; i<GDTH_MAXCMDS; ++i) | ||
4640 | ha->cmd_tab[i].cmnd = UNUSED_CMND; | ||
4641 | ha->scan_mode = rescan ? 0x10 : 0; | ||
4642 | |||
4643 | err = FALSE; | ||
4644 | if (ha->pscratch == NULL || ha->pmsg == NULL || | ||
4645 | !gdth_search_drives(hanum)) { | ||
4646 | err = TRUE; | ||
4647 | } else { | ||
4648 | if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) | ||
4649 | hdr_channel = ha->bus_cnt; | ||
4650 | ha->virt_bus = hdr_channel; | ||
4651 | |||
4652 | |||
4653 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) | ||
4654 | scsi_set_pci_device(shp, pcistr[ctr].pdev); | ||
4655 | #endif | ||
4656 | if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat &GDT_64BIT)|| | ||
4657 | /* 64-bit DMA only supported from FW >= x.43 */ | ||
4658 | (!ha->dma64_support)) { | ||
4659 | if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { | ||
4660 | printk(KERN_WARNING "GDT-PCI %d: Unable to set 32-bit DMA\n", hanum); | ||
4661 | err = TRUE; | ||
4662 | } | ||
4663 | } else { | ||
4664 | shp->max_cmd_len = 16; | ||
4665 | if (!pci_set_dma_mask(pcistr[ctr].pdev, DMA_64BIT_MASK)) { | ||
4666 | printk("GDT-PCI %d: 64-bit DMA enabled\n", hanum); | ||
4667 | } else if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { | ||
4668 | printk(KERN_WARNING "GDT-PCI %d: Unable to set 64/32-bit DMA\n", hanum); | ||
4669 | err = TRUE; | ||
4670 | } | ||
4671 | } | ||
4672 | } | ||
4673 | |||
4674 | if (err) { | ||
4675 | printk("GDT-PCI %d: Error during device scan\n", hanum); | ||
4676 | --gdth_ctr_count; | ||
4677 | --gdth_ctr_vcount; | ||
4678 | #ifdef INT_COAL | ||
4679 | if (ha->coal_stat) | ||
4680 | pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * | ||
4681 | MAXOFFSETS, ha->coal_stat, | ||
4682 | ha->coal_stat_phys); | ||
4683 | #endif | ||
4684 | if (ha->pscratch) | ||
4685 | pci_free_consistent(ha->pdev, GDTH_SCRATCH, | ||
4686 | ha->pscratch, ha->scratch_phys); | ||
4687 | if (ha->pmsg) | ||
4688 | pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4689 | ha->pmsg, ha->msg_phys); | ||
4690 | free_irq(ha->irq,ha); | ||
4691 | scsi_unregister(shp); | ||
4692 | continue; | ||
4693 | } | ||
4694 | |||
4695 | shp->max_id = ha->tid_cnt; | ||
4696 | shp->max_lun = MAXLUN; | ||
4697 | shp->max_channel = virt_ctr ? 0 : ha->bus_cnt; | ||
4698 | if (virt_ctr) { | ||
4699 | virt_ctr = 1; | ||
4700 | /* register addit. SCSI channels as virtual controllers */ | ||
4701 | for (b = 1; b < ha->bus_cnt + 1; ++b) { | ||
4702 | shp = scsi_register(shtp,sizeof(gdth_num_str)); | ||
4703 | shp->unchecked_isa_dma = 0; | ||
4704 | shp->irq = ha->irq; | ||
4705 | shp->dma_channel = 0xff; | ||
4706 | gdth_ctr_vtab[gdth_ctr_vcount++] = shp; | ||
4707 | NUMDATA(shp)->hanum = (ushort)hanum; | ||
4708 | NUMDATA(shp)->busnum = b; | ||
4709 | } | ||
4710 | } | ||
4711 | |||
4712 | spin_lock_init(&ha->smp_lock); | ||
4713 | gdth_enable_int(hanum); | ||
4714 | } | ||
4715 | |||
4716 | TRACE2(("gdth_detect() %d controller detected\n",gdth_ctr_count)); | ||
4717 | if (gdth_ctr_count > 0) { | ||
4718 | #ifdef GDTH_STATISTICS | ||
4719 | TRACE2(("gdth_detect(): Initializing timer !\n")); | ||
4720 | init_timer(&gdth_timer); | ||
4721 | gdth_timer.expires = jiffies + HZ; | ||
4722 | gdth_timer.data = 0L; | ||
4723 | gdth_timer.function = gdth_timeout; | ||
4724 | add_timer(&gdth_timer); | ||
4725 | #endif | ||
4726 | major = register_chrdev(0,"gdth",&gdth_fops); | ||
4727 | notifier_disabled = 0; | ||
4728 | register_reboot_notifier(&gdth_notifier); | ||
4729 | } | ||
4730 | gdth_polling = FALSE; | ||
4731 | return gdth_ctr_vcount; | ||
4732 | } | ||
4733 | |||
4734 | static int gdth_release(struct Scsi_Host *shp) | ||
4735 | { | 3906 | { |
4736 | int hanum; | ||
4737 | gdth_ha_str *ha; | ||
4738 | |||
4739 | TRACE2(("gdth_release()\n")); | ||
4740 | if (NUMDATA(shp)->busnum == 0) { | ||
4741 | hanum = NUMDATA(shp)->hanum; | ||
4742 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
4743 | if (ha->sdev) { | ||
4744 | scsi_free_host_dev(ha->sdev); | ||
4745 | ha->sdev = NULL; | ||
4746 | } | ||
4747 | gdth_flush(hanum); | ||
4748 | |||
4749 | if (shp->irq) { | ||
4750 | free_irq(shp->irq,ha); | ||
4751 | } | ||
4752 | #ifndef __ia64__ | ||
4753 | if (shp->dma_channel != 0xff) { | ||
4754 | free_dma(shp->dma_channel); | ||
4755 | } | ||
4756 | #endif | ||
4757 | #ifdef INT_COAL | ||
4758 | if (ha->coal_stat) | ||
4759 | pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * | ||
4760 | MAXOFFSETS, ha->coal_stat, ha->coal_stat_phys); | ||
4761 | #endif | ||
4762 | if (ha->pscratch) | ||
4763 | pci_free_consistent(ha->pdev, GDTH_SCRATCH, | ||
4764 | ha->pscratch, ha->scratch_phys); | ||
4765 | if (ha->pmsg) | ||
4766 | pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4767 | ha->pmsg, ha->msg_phys); | ||
4768 | if (ha->ccb_phys) | ||
4769 | pci_unmap_single(ha->pdev,ha->ccb_phys, | ||
4770 | sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL); | ||
4771 | gdth_ctr_released++; | ||
4772 | TRACE2(("gdth_release(): HA %d of %d\n", | ||
4773 | gdth_ctr_released, gdth_ctr_count)); | ||
4774 | |||
4775 | if (gdth_ctr_released == gdth_ctr_count) { | ||
4776 | #ifdef GDTH_STATISTICS | ||
4777 | del_timer(&gdth_timer); | ||
4778 | #endif | ||
4779 | unregister_chrdev(major,"gdth"); | ||
4780 | unregister_reboot_notifier(&gdth_notifier); | ||
4781 | } | ||
4782 | } | ||
4783 | |||
4784 | scsi_unregister(shp); | ||
4785 | return 0; | ||
4786 | } | ||
4787 | |||
4788 | |||
4789 | static const char *gdth_ctr_name(int hanum) | ||
4790 | { | ||
4791 | gdth_ha_str *ha; | ||
4792 | |||
4793 | TRACE2(("gdth_ctr_name()\n")); | 3907 | TRACE2(("gdth_ctr_name()\n")); |
4794 | 3908 | ||
4795 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
4796 | |||
4797 | if (ha->type == GDT_EISA) { | 3909 | if (ha->type == GDT_EISA) { |
4798 | switch (ha->stype) { | 3910 | switch (ha->stype) { |
4799 | case GDT3_ID: | 3911 | case GDT3_ID: |
@@ -4820,29 +3932,23 @@ static const char *gdth_ctr_name(int hanum) | |||
4820 | 3932 | ||
4821 | static const char *gdth_info(struct Scsi_Host *shp) | 3933 | static const char *gdth_info(struct Scsi_Host *shp) |
4822 | { | 3934 | { |
4823 | int hanum; | 3935 | gdth_ha_str *ha = shost_priv(shp); |
4824 | gdth_ha_str *ha; | ||
4825 | 3936 | ||
4826 | TRACE2(("gdth_info()\n")); | 3937 | TRACE2(("gdth_info()\n")); |
4827 | hanum = NUMDATA(shp)->hanum; | ||
4828 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
4829 | |||
4830 | return ((const char *)ha->binfo.type_string); | 3938 | return ((const char *)ha->binfo.type_string); |
4831 | } | 3939 | } |
4832 | 3940 | ||
4833 | static int gdth_eh_bus_reset(Scsi_Cmnd *scp) | 3941 | static int gdth_eh_bus_reset(Scsi_Cmnd *scp) |
4834 | { | 3942 | { |
4835 | int i, hanum; | 3943 | gdth_ha_str *ha = shost_priv(scp->device->host); |
4836 | gdth_ha_str *ha; | 3944 | int i; |
4837 | ulong flags; | 3945 | ulong flags; |
4838 | Scsi_Cmnd *cmnd; | 3946 | Scsi_Cmnd *cmnd; |
4839 | unchar b; | 3947 | unchar b; |
4840 | 3948 | ||
4841 | TRACE2(("gdth_eh_bus_reset()\n")); | 3949 | TRACE2(("gdth_eh_bus_reset()\n")); |
4842 | 3950 | ||
4843 | hanum = NUMDATA(scp->device->host)->hanum; | 3951 | b = scp->device->channel; |
4844 | b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; | ||
4845 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
4846 | 3952 | ||
4847 | /* clear command tab */ | 3953 | /* clear command tab */ |
4848 | spin_lock_irqsave(&ha->smp_lock, flags); | 3954 | spin_lock_irqsave(&ha->smp_lock, flags); |
@@ -4859,9 +3965,9 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *scp) | |||
4859 | if (ha->hdr[i].present) { | 3965 | if (ha->hdr[i].present) { |
4860 | spin_lock_irqsave(&ha->smp_lock, flags); | 3966 | spin_lock_irqsave(&ha->smp_lock, flags); |
4861 | gdth_polling = TRUE; | 3967 | gdth_polling = TRUE; |
4862 | while (gdth_test_busy(hanum)) | 3968 | while (gdth_test_busy(ha)) |
4863 | gdth_delay(0); | 3969 | gdth_delay(0); |
4864 | if (gdth_internal_cmd(hanum, CACHESERVICE, | 3970 | if (gdth_internal_cmd(ha, CACHESERVICE, |
4865 | GDT_CLUST_RESET, i, 0, 0)) | 3971 | GDT_CLUST_RESET, i, 0, 0)) |
4866 | ha->hdr[i].cluster_type &= ~CLUSTER_RESERVED; | 3972 | ha->hdr[i].cluster_type &= ~CLUSTER_RESERVED; |
4867 | gdth_polling = FALSE; | 3973 | gdth_polling = FALSE; |
@@ -4874,9 +3980,9 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *scp) | |||
4874 | for (i = 0; i < MAXID; ++i) | 3980 | for (i = 0; i < MAXID; ++i) |
4875 | ha->raw[BUS_L2P(ha,b)].io_cnt[i] = 0; | 3981 | ha->raw[BUS_L2P(ha,b)].io_cnt[i] = 0; |
4876 | gdth_polling = TRUE; | 3982 | gdth_polling = TRUE; |
4877 | while (gdth_test_busy(hanum)) | 3983 | while (gdth_test_busy(ha)) |
4878 | gdth_delay(0); | 3984 | gdth_delay(0); |
4879 | gdth_internal_cmd(hanum, SCSIRAWSERVICE, GDT_RESET_BUS, | 3985 | gdth_internal_cmd(ha, SCSIRAWSERVICE, GDT_RESET_BUS, |
4880 | BUS_L2P(ha,b), 0, 0); | 3986 | BUS_L2P(ha,b), 0, 0); |
4881 | gdth_polling = FALSE; | 3987 | gdth_polling = FALSE; |
4882 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 3988 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
@@ -4884,30 +3990,18 @@ static int gdth_eh_bus_reset(Scsi_Cmnd *scp) | |||
4884 | return SUCCESS; | 3990 | return SUCCESS; |
4885 | } | 3991 | } |
4886 | 3992 | ||
4887 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
4888 | static int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,sector_t cap,int *ip) | 3993 | static int gdth_bios_param(struct scsi_device *sdev,struct block_device *bdev,sector_t cap,int *ip) |
4889 | #else | ||
4890 | static int gdth_bios_param(Disk *disk,kdev_t dev,int *ip) | ||
4891 | #endif | ||
4892 | { | 3994 | { |
4893 | unchar b, t; | 3995 | unchar b, t; |
4894 | int hanum; | 3996 | gdth_ha_str *ha = shost_priv(sdev->host); |
4895 | gdth_ha_str *ha; | ||
4896 | struct scsi_device *sd; | 3997 | struct scsi_device *sd; |
4897 | unsigned capacity; | 3998 | unsigned capacity; |
4898 | 3999 | ||
4899 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
4900 | sd = sdev; | 4000 | sd = sdev; |
4901 | capacity = cap; | 4001 | capacity = cap; |
4902 | #else | 4002 | b = sd->channel; |
4903 | sd = disk->device; | ||
4904 | capacity = disk->capacity; | ||
4905 | #endif | ||
4906 | hanum = NUMDATA(sd->host)->hanum; | ||
4907 | b = virt_ctr ? NUMDATA(sd->host)->busnum : sd->channel; | ||
4908 | t = sd->id; | 4003 | t = sd->id; |
4909 | TRACE2(("gdth_bios_param() ha %d bus %d target %d\n", hanum, b, t)); | 4004 | TRACE2(("gdth_bios_param() ha %d bus %d target %d\n", ha->hanum, b, t)); |
4910 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
4911 | 4005 | ||
4912 | if (b != ha->virt_bus || ha->hdr[t].heads == 0) { | 4006 | if (b != ha->virt_bus || ha->hdr[t].heads == 0) { |
4913 | /* raw device or host drive without mapping information */ | 4007 | /* raw device or host drive without mapping information */ |
@@ -4925,33 +4019,42 @@ static int gdth_bios_param(Disk *disk,kdev_t dev,int *ip) | |||
4925 | } | 4019 | } |
4926 | 4020 | ||
4927 | 4021 | ||
4928 | static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)) | 4022 | static int gdth_queuecommand(struct scsi_cmnd *scp, |
4023 | void (*done)(struct scsi_cmnd *)) | ||
4929 | { | 4024 | { |
4930 | int hanum; | 4025 | gdth_ha_str *ha = shost_priv(scp->device->host); |
4931 | int priority; | 4026 | struct gdth_cmndinfo *cmndinfo; |
4932 | 4027 | ||
4933 | TRACE(("gdth_queuecommand() cmd 0x%x\n", scp->cmnd[0])); | 4028 | TRACE(("gdth_queuecommand() cmd 0x%x\n", scp->cmnd[0])); |
4934 | 4029 | ||
4935 | scp->scsi_done = (void *)done; | 4030 | cmndinfo = gdth_get_cmndinfo(ha); |
4936 | scp->SCp.have_data_in = 1; | 4031 | BUG_ON(!cmndinfo); |
4937 | scp->SCp.phase = -1; | 4032 | |
4938 | scp->SCp.sent_command = -1; | 4033 | scp->scsi_done = done; |
4939 | scp->SCp.Status = GDTH_MAP_NONE; | 4034 | gdth_update_timeout(scp, scp->timeout_per_command * 6); |
4940 | scp->SCp.buffer = (struct scatterlist *)NULL; | 4035 | cmndinfo->priority = DEFAULT_PRI; |
4941 | 4036 | ||
4942 | hanum = NUMDATA(scp->device->host)->hanum; | 4037 | gdth_set_bufflen(scp, scsi_bufflen(scp)); |
4038 | gdth_set_sg_count(scp, scsi_sg_count(scp)); | ||
4039 | gdth_set_sglist(scp, scsi_sglist(scp)); | ||
4040 | |||
4041 | return __gdth_queuecommand(ha, scp, cmndinfo); | ||
4042 | } | ||
4043 | |||
4044 | static int __gdth_queuecommand(gdth_ha_str *ha, struct scsi_cmnd *scp, | ||
4045 | struct gdth_cmndinfo *cmndinfo) | ||
4046 | { | ||
4047 | scp->host_scribble = (unsigned char *)cmndinfo; | ||
4048 | cmndinfo->wait_for_completion = 1; | ||
4049 | cmndinfo->phase = -1; | ||
4050 | cmndinfo->OpCode = -1; | ||
4051 | |||
4943 | #ifdef GDTH_STATISTICS | 4052 | #ifdef GDTH_STATISTICS |
4944 | ++act_ios; | 4053 | ++act_ios; |
4945 | #endif | 4054 | #endif |
4946 | 4055 | ||
4947 | priority = DEFAULT_PRI; | 4056 | gdth_putq(ha, scp, cmndinfo->priority); |
4948 | if (scp->done == gdth_scsi_done) | 4057 | gdth_next(ha); |
4949 | priority = scp->SCp.this_residual; | ||
4950 | else | ||
4951 | gdth_update_timeout(hanum, scp, scp->timeout_per_command * 6); | ||
4952 | |||
4953 | gdth_putq( hanum, scp, priority ); | ||
4954 | gdth_next( hanum ); | ||
4955 | return 0; | 4058 | return 0; |
4956 | } | 4059 | } |
4957 | 4060 | ||
@@ -4959,12 +4062,10 @@ static int gdth_queuecommand(Scsi_Cmnd *scp,void (*done)(Scsi_Cmnd *)) | |||
4959 | static int gdth_open(struct inode *inode, struct file *filep) | 4062 | static int gdth_open(struct inode *inode, struct file *filep) |
4960 | { | 4063 | { |
4961 | gdth_ha_str *ha; | 4064 | gdth_ha_str *ha; |
4962 | int i; | ||
4963 | 4065 | ||
4964 | for (i = 0; i < gdth_ctr_count; i++) { | 4066 | list_for_each_entry(ha, &gdth_instances, list) { |
4965 | ha = HADATA(gdth_ctr_tab[i]); | ||
4966 | if (!ha->sdev) | 4067 | if (!ha->sdev) |
4967 | ha->sdev = scsi_get_host_dev(gdth_ctr_tab[i]); | 4068 | ha->sdev = scsi_get_host_dev(ha->shost); |
4968 | } | 4069 | } |
4969 | 4070 | ||
4970 | TRACE(("gdth_open()\n")); | 4071 | TRACE(("gdth_open()\n")); |
@@ -4983,10 +4084,11 @@ static int ioc_event(void __user *arg) | |||
4983 | gdth_ha_str *ha; | 4084 | gdth_ha_str *ha; |
4984 | ulong flags; | 4085 | ulong flags; |
4985 | 4086 | ||
4986 | if (copy_from_user(&evt, arg, sizeof(gdth_ioctl_event)) || | 4087 | if (copy_from_user(&evt, arg, sizeof(gdth_ioctl_event))) |
4987 | evt.ionode >= gdth_ctr_count) | 4088 | return -EFAULT; |
4089 | ha = gdth_find_ha(evt.ionode); | ||
4090 | if (!ha) | ||
4988 | return -EFAULT; | 4091 | return -EFAULT; |
4989 | ha = HADATA(gdth_ctr_tab[evt.ionode]); | ||
4990 | 4092 | ||
4991 | if (evt.erase == 0xff) { | 4093 | if (evt.erase == 0xff) { |
4992 | if (evt.event.event_source == ES_TEST) | 4094 | if (evt.event.event_source == ES_TEST) |
@@ -5020,11 +4122,12 @@ static int ioc_lockdrv(void __user *arg) | |||
5020 | ulong flags; | 4122 | ulong flags; |
5021 | gdth_ha_str *ha; | 4123 | gdth_ha_str *ha; |
5022 | 4124 | ||
5023 | if (copy_from_user(&ldrv, arg, sizeof(gdth_ioctl_lockdrv)) || | 4125 | if (copy_from_user(&ldrv, arg, sizeof(gdth_ioctl_lockdrv))) |
5024 | ldrv.ionode >= gdth_ctr_count) | ||
5025 | return -EFAULT; | 4126 | return -EFAULT; |
5026 | ha = HADATA(gdth_ctr_tab[ldrv.ionode]); | 4127 | ha = gdth_find_ha(ldrv.ionode); |
5027 | 4128 | if (!ha) | |
4129 | return -EFAULT; | ||
4130 | |||
5028 | for (i = 0; i < ldrv.drive_cnt && i < MAX_HDRIVES; ++i) { | 4131 | for (i = 0; i < ldrv.drive_cnt && i < MAX_HDRIVES; ++i) { |
5029 | j = ldrv.drives[i]; | 4132 | j = ldrv.drives[i]; |
5030 | if (j >= MAX_HDRIVES || !ha->hdr[j].present) | 4133 | if (j >= MAX_HDRIVES || !ha->hdr[j].present) |
@@ -5033,14 +4136,14 @@ static int ioc_lockdrv(void __user *arg) | |||
5033 | spin_lock_irqsave(&ha->smp_lock, flags); | 4136 | spin_lock_irqsave(&ha->smp_lock, flags); |
5034 | ha->hdr[j].lock = 1; | 4137 | ha->hdr[j].lock = 1; |
5035 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 4138 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
5036 | gdth_wait_completion(ldrv.ionode, ha->bus_cnt, j); | 4139 | gdth_wait_completion(ha, ha->bus_cnt, j); |
5037 | gdth_stop_timeout(ldrv.ionode, ha->bus_cnt, j); | 4140 | gdth_stop_timeout(ha, ha->bus_cnt, j); |
5038 | } else { | 4141 | } else { |
5039 | spin_lock_irqsave(&ha->smp_lock, flags); | 4142 | spin_lock_irqsave(&ha->smp_lock, flags); |
5040 | ha->hdr[j].lock = 0; | 4143 | ha->hdr[j].lock = 0; |
5041 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 4144 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
5042 | gdth_start_timeout(ldrv.ionode, ha->bus_cnt, j); | 4145 | gdth_start_timeout(ha, ha->bus_cnt, j); |
5043 | gdth_next(ldrv.ionode); | 4146 | gdth_next(ha); |
5044 | } | 4147 | } |
5045 | } | 4148 | } |
5046 | return 0; | 4149 | return 0; |
@@ -5050,16 +4153,16 @@ static int ioc_resetdrv(void __user *arg, char *cmnd) | |||
5050 | { | 4153 | { |
5051 | gdth_ioctl_reset res; | 4154 | gdth_ioctl_reset res; |
5052 | gdth_cmd_str cmd; | 4155 | gdth_cmd_str cmd; |
5053 | int hanum; | ||
5054 | gdth_ha_str *ha; | 4156 | gdth_ha_str *ha; |
5055 | int rval; | 4157 | int rval; |
5056 | 4158 | ||
5057 | if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) || | 4159 | if (copy_from_user(&res, arg, sizeof(gdth_ioctl_reset)) || |
5058 | res.ionode >= gdth_ctr_count || res.number >= MAX_HDRIVES) | 4160 | res.number >= MAX_HDRIVES) |
5059 | return -EFAULT; | 4161 | return -EFAULT; |
5060 | hanum = res.ionode; | 4162 | ha = gdth_find_ha(res.ionode); |
5061 | ha = HADATA(gdth_ctr_tab[hanum]); | 4163 | if (!ha) |
5062 | 4164 | return -EFAULT; | |
4165 | |||
5063 | if (!ha->hdr[res.number].present) | 4166 | if (!ha->hdr[res.number].present) |
5064 | return 0; | 4167 | return 0; |
5065 | memset(&cmd, 0, sizeof(gdth_cmd_str)); | 4168 | memset(&cmd, 0, sizeof(gdth_cmd_str)); |
@@ -5085,22 +4188,21 @@ static int ioc_general(void __user *arg, char *cmnd) | |||
5085 | gdth_ioctl_general gen; | 4188 | gdth_ioctl_general gen; |
5086 | char *buf = NULL; | 4189 | char *buf = NULL; |
5087 | ulong64 paddr; | 4190 | ulong64 paddr; |
5088 | int hanum; | ||
5089 | gdth_ha_str *ha; | 4191 | gdth_ha_str *ha; |
5090 | int rval; | 4192 | int rval; |
5091 | 4193 | ||
5092 | if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general)) || | 4194 | if (copy_from_user(&gen, arg, sizeof(gdth_ioctl_general))) |
5093 | gen.ionode >= gdth_ctr_count) | 4195 | return -EFAULT; |
4196 | ha = gdth_find_ha(gen.ionode); | ||
4197 | if (!ha) | ||
5094 | return -EFAULT; | 4198 | return -EFAULT; |
5095 | hanum = gen.ionode; | ||
5096 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
5097 | if (gen.data_len + gen.sense_len != 0) { | 4199 | if (gen.data_len + gen.sense_len != 0) { |
5098 | if (!(buf = gdth_ioctl_alloc(hanum, gen.data_len + gen.sense_len, | 4200 | if (!(buf = gdth_ioctl_alloc(ha, gen.data_len + gen.sense_len, |
5099 | FALSE, &paddr))) | 4201 | FALSE, &paddr))) |
5100 | return -EFAULT; | 4202 | return -EFAULT; |
5101 | if (copy_from_user(buf, arg + sizeof(gdth_ioctl_general), | 4203 | if (copy_from_user(buf, arg + sizeof(gdth_ioctl_general), |
5102 | gen.data_len + gen.sense_len)) { | 4204 | gen.data_len + gen.sense_len)) { |
5103 | gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr); | 4205 | gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); |
5104 | return -EFAULT; | 4206 | return -EFAULT; |
5105 | } | 4207 | } |
5106 | 4208 | ||
@@ -5174,7 +4276,7 @@ static int ioc_general(void __user *arg, char *cmnd) | |||
5174 | gen.command.u.raw.sense_data = (ulong32)paddr + gen.data_len; | 4276 | gen.command.u.raw.sense_data = (ulong32)paddr + gen.data_len; |
5175 | } | 4277 | } |
5176 | } else { | 4278 | } else { |
5177 | gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr); | 4279 | gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); |
5178 | return -EFAULT; | 4280 | return -EFAULT; |
5179 | } | 4281 | } |
5180 | } | 4282 | } |
@@ -5186,15 +4288,15 @@ static int ioc_general(void __user *arg, char *cmnd) | |||
5186 | 4288 | ||
5187 | if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf, | 4289 | if (copy_to_user(arg + sizeof(gdth_ioctl_general), buf, |
5188 | gen.data_len + gen.sense_len)) { | 4290 | gen.data_len + gen.sense_len)) { |
5189 | gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr); | 4291 | gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); |
5190 | return -EFAULT; | 4292 | return -EFAULT; |
5191 | } | 4293 | } |
5192 | if (copy_to_user(arg, &gen, | 4294 | if (copy_to_user(arg, &gen, |
5193 | sizeof(gdth_ioctl_general) - sizeof(gdth_cmd_str))) { | 4295 | sizeof(gdth_ioctl_general) - sizeof(gdth_cmd_str))) { |
5194 | gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr); | 4296 | gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); |
5195 | return -EFAULT; | 4297 | return -EFAULT; |
5196 | } | 4298 | } |
5197 | gdth_ioctl_free(hanum, gen.data_len+gen.sense_len, buf, paddr); | 4299 | gdth_ioctl_free(ha, gen.data_len+gen.sense_len, buf, paddr); |
5198 | return 0; | 4300 | return 0; |
5199 | } | 4301 | } |
5200 | 4302 | ||
@@ -5204,7 +4306,7 @@ static int ioc_hdrlist(void __user *arg, char *cmnd) | |||
5204 | gdth_cmd_str *cmd; | 4306 | gdth_cmd_str *cmd; |
5205 | gdth_ha_str *ha; | 4307 | gdth_ha_str *ha; |
5206 | unchar i; | 4308 | unchar i; |
5207 | int hanum, rc = -ENOMEM; | 4309 | int rc = -ENOMEM; |
5208 | u32 cluster_type = 0; | 4310 | u32 cluster_type = 0; |
5209 | 4311 | ||
5210 | rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); | 4312 | rsc = kmalloc(sizeof(*rsc), GFP_KERNEL); |
@@ -5213,12 +4315,10 @@ static int ioc_hdrlist(void __user *arg, char *cmnd) | |||
5213 | goto free_fail; | 4315 | goto free_fail; |
5214 | 4316 | ||
5215 | if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || | 4317 | if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || |
5216 | rsc->ionode >= gdth_ctr_count) { | 4318 | (NULL == (ha = gdth_find_ha(rsc->ionode)))) { |
5217 | rc = -EFAULT; | 4319 | rc = -EFAULT; |
5218 | goto free_fail; | 4320 | goto free_fail; |
5219 | } | 4321 | } |
5220 | hanum = rsc->ionode; | ||
5221 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
5222 | memset(cmd, 0, sizeof(gdth_cmd_str)); | 4322 | memset(cmd, 0, sizeof(gdth_cmd_str)); |
5223 | 4323 | ||
5224 | for (i = 0; i < MAX_HDRIVES; ++i) { | 4324 | for (i = 0; i < MAX_HDRIVES; ++i) { |
@@ -5259,7 +4359,7 @@ static int ioc_rescan(void __user *arg, char *cmnd) | |||
5259 | gdth_cmd_str *cmd; | 4359 | gdth_cmd_str *cmd; |
5260 | ushort i, status, hdr_cnt; | 4360 | ushort i, status, hdr_cnt; |
5261 | ulong32 info; | 4361 | ulong32 info; |
5262 | int hanum, cyls, hds, secs; | 4362 | int cyls, hds, secs; |
5263 | int rc = -ENOMEM; | 4363 | int rc = -ENOMEM; |
5264 | ulong flags; | 4364 | ulong flags; |
5265 | gdth_ha_str *ha; | 4365 | gdth_ha_str *ha; |
@@ -5270,12 +4370,10 @@ static int ioc_rescan(void __user *arg, char *cmnd) | |||
5270 | goto free_fail; | 4370 | goto free_fail; |
5271 | 4371 | ||
5272 | if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || | 4372 | if (copy_from_user(rsc, arg, sizeof(gdth_ioctl_rescan)) || |
5273 | rsc->ionode >= gdth_ctr_count) { | 4373 | (NULL == (ha = gdth_find_ha(rsc->ionode)))) { |
5274 | rc = -EFAULT; | 4374 | rc = -EFAULT; |
5275 | goto free_fail; | 4375 | goto free_fail; |
5276 | } | 4376 | } |
5277 | hanum = rsc->ionode; | ||
5278 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
5279 | memset(cmd, 0, sizeof(gdth_cmd_str)); | 4377 | memset(cmd, 0, sizeof(gdth_cmd_str)); |
5280 | 4378 | ||
5281 | if (rsc->flag == 0) { | 4379 | if (rsc->flag == 0) { |
@@ -5432,9 +4530,9 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, | |||
5432 | gdth_ioctl_ctrtype ctrt; | 4530 | gdth_ioctl_ctrtype ctrt; |
5433 | 4531 | ||
5434 | if (copy_from_user(&ctrt, argp, sizeof(gdth_ioctl_ctrtype)) || | 4532 | if (copy_from_user(&ctrt, argp, sizeof(gdth_ioctl_ctrtype)) || |
5435 | ctrt.ionode >= gdth_ctr_count) | 4533 | (NULL == (ha = gdth_find_ha(ctrt.ionode)))) |
5436 | return -EFAULT; | 4534 | return -EFAULT; |
5437 | ha = HADATA(gdth_ctr_tab[ctrt.ionode]); | 4535 | |
5438 | if (ha->type == GDT_ISA || ha->type == GDT_EISA) { | 4536 | if (ha->type == GDT_ISA || ha->type == GDT_EISA) { |
5439 | ctrt.type = (unchar)((ha->stype>>20) - 0x10); | 4537 | ctrt.type = (unchar)((ha->stype>>20) - 0x10); |
5440 | } else { | 4538 | } else { |
@@ -5473,10 +4571,9 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, | |||
5473 | unchar i, j; | 4571 | unchar i, j; |
5474 | 4572 | ||
5475 | if (copy_from_user(&lchn, argp, sizeof(gdth_ioctl_lockchn)) || | 4573 | if (copy_from_user(&lchn, argp, sizeof(gdth_ioctl_lockchn)) || |
5476 | lchn.ionode >= gdth_ctr_count) | 4574 | (NULL == (ha = gdth_find_ha(lchn.ionode)))) |
5477 | return -EFAULT; | 4575 | return -EFAULT; |
5478 | ha = HADATA(gdth_ctr_tab[lchn.ionode]); | 4576 | |
5479 | |||
5480 | i = lchn.channel; | 4577 | i = lchn.channel; |
5481 | if (i < ha->bus_cnt) { | 4578 | if (i < ha->bus_cnt) { |
5482 | if (lchn.lock) { | 4579 | if (lchn.lock) { |
@@ -5484,16 +4581,16 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, | |||
5484 | ha->raw[i].lock = 1; | 4581 | ha->raw[i].lock = 1; |
5485 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 4582 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
5486 | for (j = 0; j < ha->tid_cnt; ++j) { | 4583 | for (j = 0; j < ha->tid_cnt; ++j) { |
5487 | gdth_wait_completion(lchn.ionode, i, j); | 4584 | gdth_wait_completion(ha, i, j); |
5488 | gdth_stop_timeout(lchn.ionode, i, j); | 4585 | gdth_stop_timeout(ha, i, j); |
5489 | } | 4586 | } |
5490 | } else { | 4587 | } else { |
5491 | spin_lock_irqsave(&ha->smp_lock, flags); | 4588 | spin_lock_irqsave(&ha->smp_lock, flags); |
5492 | ha->raw[i].lock = 0; | 4589 | ha->raw[i].lock = 0; |
5493 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 4590 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
5494 | for (j = 0; j < ha->tid_cnt; ++j) { | 4591 | for (j = 0; j < ha->tid_cnt; ++j) { |
5495 | gdth_start_timeout(lchn.ionode, i, j); | 4592 | gdth_start_timeout(ha, i, j); |
5496 | gdth_next(lchn.ionode); | 4593 | gdth_next(ha); |
5497 | } | 4594 | } |
5498 | } | 4595 | } |
5499 | } | 4596 | } |
@@ -5509,37 +4606,22 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, | |||
5509 | case GDTIOCTL_RESET_BUS: | 4606 | case GDTIOCTL_RESET_BUS: |
5510 | { | 4607 | { |
5511 | gdth_ioctl_reset res; | 4608 | gdth_ioctl_reset res; |
5512 | int hanum, rval; | 4609 | int rval; |
5513 | 4610 | ||
5514 | if (copy_from_user(&res, argp, sizeof(gdth_ioctl_reset)) || | 4611 | if (copy_from_user(&res, argp, sizeof(gdth_ioctl_reset)) || |
5515 | res.ionode >= gdth_ctr_count) | 4612 | (NULL == (ha = gdth_find_ha(res.ionode)))) |
5516 | return -EFAULT; | 4613 | return -EFAULT; |
5517 | hanum = res.ionode; | ||
5518 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
5519 | 4614 | ||
5520 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 4615 | scp = kzalloc(sizeof(*scp), GFP_KERNEL); |
5521 | scp = kmalloc(sizeof(*scp), GFP_KERNEL); | ||
5522 | if (!scp) | 4616 | if (!scp) |
5523 | return -ENOMEM; | 4617 | return -ENOMEM; |
5524 | memset(scp, 0, sizeof(*scp)); | ||
5525 | scp->device = ha->sdev; | 4618 | scp->device = ha->sdev; |
5526 | scp->cmd_len = 12; | 4619 | scp->cmd_len = 12; |
5527 | scp->use_sg = 0; | 4620 | scp->device->channel = res.number; |
5528 | scp->device->channel = virt_ctr ? 0 : res.number; | ||
5529 | rval = gdth_eh_bus_reset(scp); | 4621 | rval = gdth_eh_bus_reset(scp); |
5530 | res.status = (rval == SUCCESS ? S_OK : S_GENERR); | 4622 | res.status = (rval == SUCCESS ? S_OK : S_GENERR); |
5531 | kfree(scp); | 4623 | kfree(scp); |
5532 | #else | 4624 | |
5533 | scp = scsi_allocate_device(ha->sdev, 1, FALSE); | ||
5534 | if (!scp) | ||
5535 | return -ENOMEM; | ||
5536 | scp->cmd_len = 12; | ||
5537 | scp->use_sg = 0; | ||
5538 | scp->channel = virt_ctr ? 0 : res.number; | ||
5539 | rval = gdth_eh_bus_reset(scp); | ||
5540 | res.status = (rval == SUCCESS ? S_OK : S_GENERR); | ||
5541 | scsi_release_command(scp); | ||
5542 | #endif | ||
5543 | if (copy_to_user(argp, &res, sizeof(gdth_ioctl_reset))) | 4625 | if (copy_to_user(argp, &res, sizeof(gdth_ioctl_reset))) |
5544 | return -EFAULT; | 4626 | return -EFAULT; |
5545 | break; | 4627 | break; |
@@ -5556,16 +4638,14 @@ static int gdth_ioctl(struct inode *inode, struct file *filep, | |||
5556 | 4638 | ||
5557 | 4639 | ||
5558 | /* flush routine */ | 4640 | /* flush routine */ |
5559 | static void gdth_flush(int hanum) | 4641 | static void gdth_flush(gdth_ha_str *ha) |
5560 | { | 4642 | { |
5561 | int i; | 4643 | int i; |
5562 | gdth_ha_str *ha; | ||
5563 | gdth_cmd_str gdtcmd; | 4644 | gdth_cmd_str gdtcmd; |
5564 | char cmnd[MAX_COMMAND_SIZE]; | 4645 | char cmnd[MAX_COMMAND_SIZE]; |
5565 | memset(cmnd, 0xff, MAX_COMMAND_SIZE); | 4646 | memset(cmnd, 0xff, MAX_COMMAND_SIZE); |
5566 | 4647 | ||
5567 | TRACE2(("gdth_flush() hanum %d\n",hanum)); | 4648 | TRACE2(("gdth_flush() hanum %d\n", ha->hanum)); |
5568 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
5569 | 4649 | ||
5570 | for (i = 0; i < MAX_HDRIVES; ++i) { | 4650 | for (i = 0; i < MAX_HDRIVES; ++i) { |
5571 | if (ha->hdr[i].present) { | 4651 | if (ha->hdr[i].present) { |
@@ -5581,9 +4661,9 @@ static void gdth_flush(int hanum) | |||
5581 | gdtcmd.u.cache.BlockNo = 1; | 4661 | gdtcmd.u.cache.BlockNo = 1; |
5582 | gdtcmd.u.cache.sg_canz = 0; | 4662 | gdtcmd.u.cache.sg_canz = 0; |
5583 | } | 4663 | } |
5584 | TRACE2(("gdth_flush(): flush ha %d drive %d\n", hanum, i)); | 4664 | TRACE2(("gdth_flush(): flush ha %d drive %d\n", ha->hanum, i)); |
5585 | 4665 | ||
5586 | gdth_execute(gdth_ctr_tab[hanum], &gdtcmd, cmnd, 30, NULL); | 4666 | gdth_execute(ha->shost, &gdtcmd, cmnd, 30, NULL); |
5587 | } | 4667 | } |
5588 | } | 4668 | } |
5589 | } | 4669 | } |
@@ -5591,7 +4671,7 @@ static void gdth_flush(int hanum) | |||
5591 | /* shutdown routine */ | 4671 | /* shutdown routine */ |
5592 | static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) | 4672 | static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) |
5593 | { | 4673 | { |
5594 | int hanum; | 4674 | gdth_ha_str *ha; |
5595 | #ifndef __alpha__ | 4675 | #ifndef __alpha__ |
5596 | gdth_cmd_str gdtcmd; | 4676 | gdth_cmd_str gdtcmd; |
5597 | char cmnd[MAX_COMMAND_SIZE]; | 4677 | char cmnd[MAX_COMMAND_SIZE]; |
@@ -5606,8 +4686,8 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) | |||
5606 | 4686 | ||
5607 | notifier_disabled = 1; | 4687 | notifier_disabled = 1; |
5608 | printk("GDT-HA: Flushing all host drives .. "); | 4688 | printk("GDT-HA: Flushing all host drives .. "); |
5609 | for (hanum = 0; hanum < gdth_ctr_count; ++hanum) { | 4689 | list_for_each_entry(ha, &gdth_instances, list) { |
5610 | gdth_flush(hanum); | 4690 | gdth_flush(ha); |
5611 | 4691 | ||
5612 | #ifndef __alpha__ | 4692 | #ifndef __alpha__ |
5613 | /* controller reset */ | 4693 | /* controller reset */ |
@@ -5615,8 +4695,8 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) | |||
5615 | gdtcmd.BoardNode = LOCALBOARD; | 4695 | gdtcmd.BoardNode = LOCALBOARD; |
5616 | gdtcmd.Service = CACHESERVICE; | 4696 | gdtcmd.Service = CACHESERVICE; |
5617 | gdtcmd.OpCode = GDT_RESET; | 4697 | gdtcmd.OpCode = GDT_RESET; |
5618 | TRACE2(("gdth_halt(): reset controller %d\n", hanum)); | 4698 | TRACE2(("gdth_halt(): reset controller %d\n", ha->hanum)); |
5619 | gdth_execute(gdth_ctr_tab[hanum], &gdtcmd, cmnd, 10, NULL); | 4699 | gdth_execute(ha->shost, &gdtcmd, cmnd, 10, NULL); |
5620 | #endif | 4700 | #endif |
5621 | } | 4701 | } |
5622 | printk("Done.\n"); | 4702 | printk("Done.\n"); |
@@ -5627,7 +4707,6 @@ static int gdth_halt(struct notifier_block *nb, ulong event, void *buf) | |||
5627 | return NOTIFY_OK; | 4707 | return NOTIFY_OK; |
5628 | } | 4708 | } |
5629 | 4709 | ||
5630 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
5631 | /* configure lun */ | 4710 | /* configure lun */ |
5632 | static int gdth_slave_configure(struct scsi_device *sdev) | 4711 | static int gdth_slave_configure(struct scsi_device *sdev) |
5633 | { | 4712 | { |
@@ -5636,40 +4715,536 @@ static int gdth_slave_configure(struct scsi_device *sdev) | |||
5636 | sdev->skip_ms_page_8 = 1; | 4715 | sdev->skip_ms_page_8 = 1; |
5637 | return 0; | 4716 | return 0; |
5638 | } | 4717 | } |
5639 | #endif | ||
5640 | 4718 | ||
5641 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | 4719 | static struct scsi_host_template gdth_template = { |
5642 | static struct scsi_host_template driver_template = { | ||
5643 | #else | ||
5644 | static Scsi_Host_Template driver_template = { | ||
5645 | #endif | ||
5646 | .proc_name = "gdth", | ||
5647 | .proc_info = gdth_proc_info, | ||
5648 | .name = "GDT SCSI Disk Array Controller", | 4720 | .name = "GDT SCSI Disk Array Controller", |
5649 | .detect = gdth_detect, | ||
5650 | .release = gdth_release, | ||
5651 | .info = gdth_info, | 4721 | .info = gdth_info, |
5652 | .queuecommand = gdth_queuecommand, | 4722 | .queuecommand = gdth_queuecommand, |
5653 | .eh_bus_reset_handler = gdth_eh_bus_reset, | 4723 | .eh_bus_reset_handler = gdth_eh_bus_reset, |
4724 | .slave_configure = gdth_slave_configure, | ||
5654 | .bios_param = gdth_bios_param, | 4725 | .bios_param = gdth_bios_param, |
4726 | .proc_info = gdth_proc_info, | ||
4727 | .proc_name = "gdth", | ||
5655 | .can_queue = GDTH_MAXCMDS, | 4728 | .can_queue = GDTH_MAXCMDS, |
5656 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
5657 | .slave_configure = gdth_slave_configure, | ||
5658 | #endif | ||
5659 | .this_id = -1, | 4729 | .this_id = -1, |
5660 | .sg_tablesize = GDTH_MAXSG, | 4730 | .sg_tablesize = GDTH_MAXSG, |
5661 | .cmd_per_lun = GDTH_MAXC_P_L, | 4731 | .cmd_per_lun = GDTH_MAXC_P_L, |
5662 | .unchecked_isa_dma = 1, | 4732 | .unchecked_isa_dma = 1, |
5663 | .use_clustering = ENABLE_CLUSTERING, | 4733 | .use_clustering = ENABLE_CLUSTERING, |
5664 | #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,0) | 4734 | }; |
5665 | .use_new_eh_code = 1, | 4735 | |
5666 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20) | 4736 | #ifdef CONFIG_ISA |
5667 | .highmem_io = 1, | 4737 | static int gdth_isa_probe_one(ulong32 isa_bios) |
4738 | { | ||
4739 | struct Scsi_Host *shp; | ||
4740 | gdth_ha_str *ha; | ||
4741 | dma_addr_t scratch_dma_handle = 0; | ||
4742 | int error, i; | ||
4743 | |||
4744 | if (!gdth_search_isa(isa_bios)) | ||
4745 | return -ENXIO; | ||
4746 | |||
4747 | shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); | ||
4748 | if (!shp) | ||
4749 | return -ENOMEM; | ||
4750 | ha = shost_priv(shp); | ||
4751 | |||
4752 | error = -ENODEV; | ||
4753 | if (!gdth_init_isa(isa_bios,ha)) | ||
4754 | goto out_host_put; | ||
4755 | |||
4756 | /* controller found and initialized */ | ||
4757 | printk("Configuring GDT-ISA HA at BIOS 0x%05X IRQ %u DRQ %u\n", | ||
4758 | isa_bios, ha->irq, ha->drq); | ||
4759 | |||
4760 | error = request_irq(ha->irq, gdth_interrupt, IRQF_DISABLED, "gdth", ha); | ||
4761 | if (error) { | ||
4762 | printk("GDT-ISA: Unable to allocate IRQ\n"); | ||
4763 | goto out_host_put; | ||
4764 | } | ||
4765 | |||
4766 | error = request_dma(ha->drq, "gdth"); | ||
4767 | if (error) { | ||
4768 | printk("GDT-ISA: Unable to allocate DMA channel\n"); | ||
4769 | goto out_free_irq; | ||
4770 | } | ||
4771 | |||
4772 | set_dma_mode(ha->drq,DMA_MODE_CASCADE); | ||
4773 | enable_dma(ha->drq); | ||
4774 | shp->unchecked_isa_dma = 1; | ||
4775 | shp->irq = ha->irq; | ||
4776 | shp->dma_channel = ha->drq; | ||
4777 | |||
4778 | ha->hanum = gdth_ctr_count++; | ||
4779 | ha->shost = shp; | ||
4780 | |||
4781 | ha->pccb = &ha->cmdext; | ||
4782 | ha->ccb_phys = 0L; | ||
4783 | ha->pdev = NULL; | ||
4784 | |||
4785 | error = -ENOMEM; | ||
4786 | |||
4787 | ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, | ||
4788 | &scratch_dma_handle); | ||
4789 | if (!ha->pscratch) | ||
4790 | goto out_dec_counters; | ||
4791 | ha->scratch_phys = scratch_dma_handle; | ||
4792 | |||
4793 | ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4794 | &scratch_dma_handle); | ||
4795 | if (!ha->pmsg) | ||
4796 | goto out_free_pscratch; | ||
4797 | ha->msg_phys = scratch_dma_handle; | ||
4798 | |||
4799 | #ifdef INT_COAL | ||
4800 | ha->coal_stat = pci_alloc_consistent(ha->pdev, | ||
4801 | sizeof(gdth_coal_status) * MAXOFFSETS, | ||
4802 | &scratch_dma_handle); | ||
4803 | if (!ha->coal_stat) | ||
4804 | goto out_free_pmsg; | ||
4805 | ha->coal_stat_phys = scratch_dma_handle; | ||
4806 | #endif | ||
4807 | |||
4808 | ha->scratch_busy = FALSE; | ||
4809 | ha->req_first = NULL; | ||
4810 | ha->tid_cnt = MAX_HDRIVES; | ||
4811 | if (max_ids > 0 && max_ids < ha->tid_cnt) | ||
4812 | ha->tid_cnt = max_ids; | ||
4813 | for (i = 0; i < GDTH_MAXCMDS; ++i) | ||
4814 | ha->cmd_tab[i].cmnd = UNUSED_CMND; | ||
4815 | ha->scan_mode = rescan ? 0x10 : 0; | ||
4816 | |||
4817 | error = -ENODEV; | ||
4818 | if (!gdth_search_drives(ha)) { | ||
4819 | printk("GDT-ISA: Error during device scan\n"); | ||
4820 | goto out_free_coal_stat; | ||
4821 | } | ||
4822 | |||
4823 | if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) | ||
4824 | hdr_channel = ha->bus_cnt; | ||
4825 | ha->virt_bus = hdr_channel; | ||
4826 | |||
4827 | if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) | ||
4828 | shp->max_cmd_len = 16; | ||
4829 | |||
4830 | shp->max_id = ha->tid_cnt; | ||
4831 | shp->max_lun = MAXLUN; | ||
4832 | shp->max_channel = ha->bus_cnt; | ||
4833 | |||
4834 | spin_lock_init(&ha->smp_lock); | ||
4835 | gdth_enable_int(ha); | ||
4836 | |||
4837 | error = scsi_add_host(shp, NULL); | ||
4838 | if (error) | ||
4839 | goto out_free_coal_stat; | ||
4840 | list_add_tail(&ha->list, &gdth_instances); | ||
4841 | return 0; | ||
4842 | |||
4843 | out_free_coal_stat: | ||
4844 | #ifdef INT_COAL | ||
4845 | pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * MAXOFFSETS, | ||
4846 | ha->coal_stat, ha->coal_stat_phys); | ||
4847 | out_free_pmsg: | ||
4848 | #endif | ||
4849 | pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4850 | ha->pmsg, ha->msg_phys); | ||
4851 | out_free_pscratch: | ||
4852 | pci_free_consistent(ha->pdev, GDTH_SCRATCH, | ||
4853 | ha->pscratch, ha->scratch_phys); | ||
4854 | out_dec_counters: | ||
4855 | gdth_ctr_count--; | ||
4856 | out_free_irq: | ||
4857 | free_irq(ha->irq, ha); | ||
4858 | out_host_put: | ||
4859 | scsi_host_put(shp); | ||
4860 | return error; | ||
4861 | } | ||
4862 | #endif /* CONFIG_ISA */ | ||
4863 | |||
4864 | #ifdef CONFIG_EISA | ||
4865 | static int gdth_eisa_probe_one(ushort eisa_slot) | ||
4866 | { | ||
4867 | struct Scsi_Host *shp; | ||
4868 | gdth_ha_str *ha; | ||
4869 | dma_addr_t scratch_dma_handle = 0; | ||
4870 | int error, i; | ||
4871 | |||
4872 | if (!gdth_search_eisa(eisa_slot)) | ||
4873 | return -ENXIO; | ||
4874 | |||
4875 | shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); | ||
4876 | if (!shp) | ||
4877 | return -ENOMEM; | ||
4878 | ha = shost_priv(shp); | ||
4879 | |||
4880 | error = -ENODEV; | ||
4881 | if (!gdth_init_eisa(eisa_slot,ha)) | ||
4882 | goto out_host_put; | ||
4883 | |||
4884 | /* controller found and initialized */ | ||
4885 | printk("Configuring GDT-EISA HA at Slot %d IRQ %u\n", | ||
4886 | eisa_slot >> 12, ha->irq); | ||
4887 | |||
4888 | error = request_irq(ha->irq, gdth_interrupt, IRQF_DISABLED, "gdth", ha); | ||
4889 | if (error) { | ||
4890 | printk("GDT-EISA: Unable to allocate IRQ\n"); | ||
4891 | goto out_host_put; | ||
4892 | } | ||
4893 | |||
4894 | shp->unchecked_isa_dma = 0; | ||
4895 | shp->irq = ha->irq; | ||
4896 | shp->dma_channel = 0xff; | ||
4897 | |||
4898 | ha->hanum = gdth_ctr_count++; | ||
4899 | ha->shost = shp; | ||
4900 | |||
4901 | TRACE2(("EISA detect Bus 0: hanum %d\n", ha->hanum)); | ||
4902 | |||
4903 | ha->pccb = &ha->cmdext; | ||
4904 | ha->ccb_phys = 0L; | ||
4905 | |||
4906 | error = -ENOMEM; | ||
4907 | |||
4908 | ha->pdev = NULL; | ||
4909 | ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, | ||
4910 | &scratch_dma_handle); | ||
4911 | if (!ha->pscratch) | ||
4912 | goto out_free_irq; | ||
4913 | ha->scratch_phys = scratch_dma_handle; | ||
4914 | |||
4915 | ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
4916 | &scratch_dma_handle); | ||
4917 | if (!ha->pmsg) | ||
4918 | goto out_free_pscratch; | ||
4919 | ha->msg_phys = scratch_dma_handle; | ||
4920 | |||
4921 | #ifdef INT_COAL | ||
4922 | ha->coal_stat = pci_alloc_consistent(ha->pdev, | ||
4923 | sizeof(gdth_coal_status) * MAXOFFSETS, | ||
4924 | &scratch_dma_handle); | ||
4925 | if (!ha->coal_stat) | ||
4926 | goto out_free_pmsg; | ||
4927 | ha->coal_stat_phys = scratch_dma_handle; | ||
5668 | #endif | 4928 | #endif |
4929 | |||
4930 | ha->ccb_phys = pci_map_single(ha->pdev,ha->pccb, | ||
4931 | sizeof(gdth_cmd_str), PCI_DMA_BIDIRECTIONAL); | ||
4932 | if (!ha->ccb_phys) | ||
4933 | goto out_free_coal_stat; | ||
4934 | |||
4935 | ha->scratch_busy = FALSE; | ||
4936 | ha->req_first = NULL; | ||
4937 | ha->tid_cnt = MAX_HDRIVES; | ||
4938 | if (max_ids > 0 && max_ids < ha->tid_cnt) | ||
4939 | ha->tid_cnt = max_ids; | ||
4940 | for (i = 0; i < GDTH_MAXCMDS; ++i) | ||
4941 | ha->cmd_tab[i].cmnd = UNUSED_CMND; | ||
4942 | ha->scan_mode = rescan ? 0x10 : 0; | ||
4943 | |||
4944 | if (!gdth_search_drives(ha)) { | ||
4945 | printk("GDT-EISA: Error during device scan\n"); | ||
4946 | error = -ENODEV; | ||
4947 | goto out_free_ccb_phys; | ||
4948 | } | ||
4949 | |||
4950 | if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) | ||
4951 | hdr_channel = ha->bus_cnt; | ||
4952 | ha->virt_bus = hdr_channel; | ||
4953 | |||
4954 | if (ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) | ||
4955 | shp->max_cmd_len = 16; | ||
4956 | |||
4957 | shp->max_id = ha->tid_cnt; | ||
4958 | shp->max_lun = MAXLUN; | ||
4959 | shp->max_channel = ha->bus_cnt; | ||
4960 | |||
4961 | spin_lock_init(&ha->smp_lock); | ||
4962 | gdth_enable_int(ha); | ||
4963 | |||
4964 | error = scsi_add_host(shp, NULL); | ||
4965 | if (error) | ||
4966 | goto out_free_coal_stat; | ||
4967 | list_add_tail(&ha->list, &gdth_instances); | ||
4968 | return 0; | ||
4969 | |||
4970 | out_free_ccb_phys: | ||
4971 | pci_unmap_single(ha->pdev,ha->ccb_phys, sizeof(gdth_cmd_str), | ||
4972 | PCI_DMA_BIDIRECTIONAL); | ||
4973 | out_free_coal_stat: | ||
4974 | #ifdef INT_COAL | ||
4975 | pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * MAXOFFSETS, | ||
4976 | ha->coal_stat, ha->coal_stat_phys); | ||
4977 | out_free_pmsg: | ||
5669 | #endif | 4978 | #endif |
5670 | }; | 4979 | pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), |
4980 | ha->pmsg, ha->msg_phys); | ||
4981 | out_free_pscratch: | ||
4982 | pci_free_consistent(ha->pdev, GDTH_SCRATCH, | ||
4983 | ha->pscratch, ha->scratch_phys); | ||
4984 | out_free_irq: | ||
4985 | free_irq(ha->irq, ha); | ||
4986 | gdth_ctr_count--; | ||
4987 | out_host_put: | ||
4988 | scsi_host_put(shp); | ||
4989 | return error; | ||
4990 | } | ||
4991 | #endif /* CONFIG_EISA */ | ||
4992 | |||
4993 | #ifdef CONFIG_PCI | ||
4994 | static int gdth_pci_probe_one(gdth_pci_str *pcistr, int ctr) | ||
4995 | { | ||
4996 | struct Scsi_Host *shp; | ||
4997 | gdth_ha_str *ha; | ||
4998 | dma_addr_t scratch_dma_handle = 0; | ||
4999 | int error, i; | ||
5000 | |||
5001 | shp = scsi_host_alloc(&gdth_template, sizeof(gdth_ha_str)); | ||
5002 | if (!shp) | ||
5003 | return -ENOMEM; | ||
5004 | ha = shost_priv(shp); | ||
5005 | |||
5006 | error = -ENODEV; | ||
5007 | if (!gdth_init_pci(&pcistr[ctr],ha)) | ||
5008 | goto out_host_put; | ||
5009 | |||
5010 | /* controller found and initialized */ | ||
5011 | printk("Configuring GDT-PCI HA at %d/%d IRQ %u\n", | ||
5012 | pcistr[ctr].pdev->bus->number, | ||
5013 | PCI_SLOT(pcistr[ctr].pdev->devfn), | ||
5014 | ha->irq); | ||
5015 | |||
5016 | error = request_irq(ha->irq, gdth_interrupt, | ||
5017 | IRQF_DISABLED|IRQF_SHARED, "gdth", ha); | ||
5018 | if (error) { | ||
5019 | printk("GDT-PCI: Unable to allocate IRQ\n"); | ||
5020 | goto out_host_put; | ||
5021 | } | ||
5022 | |||
5023 | shp->unchecked_isa_dma = 0; | ||
5024 | shp->irq = ha->irq; | ||
5025 | shp->dma_channel = 0xff; | ||
5026 | |||
5027 | ha->hanum = gdth_ctr_count++; | ||
5028 | ha->shost = shp; | ||
5029 | |||
5030 | ha->pccb = &ha->cmdext; | ||
5031 | ha->ccb_phys = 0L; | ||
5032 | |||
5033 | error = -ENOMEM; | ||
5034 | |||
5035 | ha->pscratch = pci_alloc_consistent(ha->pdev, GDTH_SCRATCH, | ||
5036 | &scratch_dma_handle); | ||
5037 | if (!ha->pscratch) | ||
5038 | goto out_free_irq; | ||
5039 | ha->scratch_phys = scratch_dma_handle; | ||
5040 | |||
5041 | ha->pmsg = pci_alloc_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
5042 | &scratch_dma_handle); | ||
5043 | if (!ha->pmsg) | ||
5044 | goto out_free_pscratch; | ||
5045 | ha->msg_phys = scratch_dma_handle; | ||
5046 | |||
5047 | #ifdef INT_COAL | ||
5048 | ha->coal_stat = pci_alloc_consistent(ha->pdev, | ||
5049 | sizeof(gdth_coal_status) * MAXOFFSETS, | ||
5050 | &scratch_dma_handle); | ||
5051 | if (!ha->coal_stat) | ||
5052 | goto out_free_pmsg; | ||
5053 | ha->coal_stat_phys = scratch_dma_handle; | ||
5054 | #endif | ||
5055 | |||
5056 | ha->scratch_busy = FALSE; | ||
5057 | ha->req_first = NULL; | ||
5058 | ha->tid_cnt = pcistr[ctr].pdev->device >= 0x200 ? MAXID : MAX_HDRIVES; | ||
5059 | if (max_ids > 0 && max_ids < ha->tid_cnt) | ||
5060 | ha->tid_cnt = max_ids; | ||
5061 | for (i = 0; i < GDTH_MAXCMDS; ++i) | ||
5062 | ha->cmd_tab[i].cmnd = UNUSED_CMND; | ||
5063 | ha->scan_mode = rescan ? 0x10 : 0; | ||
5064 | |||
5065 | error = -ENODEV; | ||
5066 | if (!gdth_search_drives(ha)) { | ||
5067 | printk("GDT-PCI %d: Error during device scan\n", ha->hanum); | ||
5068 | goto out_free_coal_stat; | ||
5069 | } | ||
5070 | |||
5071 | if (hdr_channel < 0 || hdr_channel > ha->bus_cnt) | ||
5072 | hdr_channel = ha->bus_cnt; | ||
5073 | ha->virt_bus = hdr_channel; | ||
5074 | |||
5075 | /* 64-bit DMA only supported from FW >= x.43 */ | ||
5076 | if (!(ha->cache_feat & ha->raw_feat & ha->screen_feat & GDT_64BIT) || | ||
5077 | !ha->dma64_support) { | ||
5078 | if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { | ||
5079 | printk(KERN_WARNING "GDT-PCI %d: " | ||
5080 | "Unable to set 32-bit DMA\n", ha->hanum); | ||
5081 | goto out_free_coal_stat; | ||
5082 | } | ||
5083 | } else { | ||
5084 | shp->max_cmd_len = 16; | ||
5085 | if (!pci_set_dma_mask(pcistr[ctr].pdev, DMA_64BIT_MASK)) { | ||
5086 | printk("GDT-PCI %d: 64-bit DMA enabled\n", ha->hanum); | ||
5087 | } else if (pci_set_dma_mask(pcistr[ctr].pdev, DMA_32BIT_MASK)) { | ||
5088 | printk(KERN_WARNING "GDT-PCI %d: " | ||
5089 | "Unable to set 64/32-bit DMA\n", ha->hanum); | ||
5090 | goto out_free_coal_stat; | ||
5091 | } | ||
5092 | } | ||
5093 | |||
5094 | shp->max_id = ha->tid_cnt; | ||
5095 | shp->max_lun = MAXLUN; | ||
5096 | shp->max_channel = ha->bus_cnt; | ||
5097 | |||
5098 | spin_lock_init(&ha->smp_lock); | ||
5099 | gdth_enable_int(ha); | ||
5100 | |||
5101 | error = scsi_add_host(shp, &pcistr[ctr].pdev->dev); | ||
5102 | if (error) | ||
5103 | goto out_free_coal_stat; | ||
5104 | list_add_tail(&ha->list, &gdth_instances); | ||
5105 | return 0; | ||
5106 | |||
5107 | out_free_coal_stat: | ||
5108 | #ifdef INT_COAL | ||
5109 | pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * MAXOFFSETS, | ||
5110 | ha->coal_stat, ha->coal_stat_phys); | ||
5111 | out_free_pmsg: | ||
5112 | #endif | ||
5113 | pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
5114 | ha->pmsg, ha->msg_phys); | ||
5115 | out_free_pscratch: | ||
5116 | pci_free_consistent(ha->pdev, GDTH_SCRATCH, | ||
5117 | ha->pscratch, ha->scratch_phys); | ||
5118 | out_free_irq: | ||
5119 | free_irq(ha->irq, ha); | ||
5120 | gdth_ctr_count--; | ||
5121 | out_host_put: | ||
5122 | scsi_host_put(shp); | ||
5123 | return error; | ||
5124 | } | ||
5125 | #endif /* CONFIG_PCI */ | ||
5126 | |||
5127 | static void gdth_remove_one(gdth_ha_str *ha) | ||
5128 | { | ||
5129 | struct Scsi_Host *shp = ha->shost; | ||
5130 | |||
5131 | TRACE2(("gdth_remove_one()\n")); | ||
5132 | |||
5133 | scsi_remove_host(shp); | ||
5134 | |||
5135 | if (ha->sdev) { | ||
5136 | scsi_free_host_dev(ha->sdev); | ||
5137 | ha->sdev = NULL; | ||
5138 | } | ||
5139 | |||
5140 | gdth_flush(ha); | ||
5141 | |||
5142 | if (shp->irq) | ||
5143 | free_irq(shp->irq,ha); | ||
5144 | |||
5145 | #ifdef CONFIG_ISA | ||
5146 | if (shp->dma_channel != 0xff) | ||
5147 | free_dma(shp->dma_channel); | ||
5148 | #endif | ||
5149 | #ifdef INT_COAL | ||
5150 | if (ha->coal_stat) | ||
5151 | pci_free_consistent(ha->pdev, sizeof(gdth_coal_status) * | ||
5152 | MAXOFFSETS, ha->coal_stat, ha->coal_stat_phys); | ||
5153 | #endif | ||
5154 | if (ha->pscratch) | ||
5155 | pci_free_consistent(ha->pdev, GDTH_SCRATCH, | ||
5156 | ha->pscratch, ha->scratch_phys); | ||
5157 | if (ha->pmsg) | ||
5158 | pci_free_consistent(ha->pdev, sizeof(gdth_msg_str), | ||
5159 | ha->pmsg, ha->msg_phys); | ||
5160 | if (ha->ccb_phys) | ||
5161 | pci_unmap_single(ha->pdev,ha->ccb_phys, | ||
5162 | sizeof(gdth_cmd_str),PCI_DMA_BIDIRECTIONAL); | ||
5163 | |||
5164 | scsi_host_put(shp); | ||
5165 | } | ||
5166 | |||
5167 | static int __init gdth_init(void) | ||
5168 | { | ||
5169 | if (disable) { | ||
5170 | printk("GDT-HA: Controller driver disabled from" | ||
5171 | " command line !\n"); | ||
5172 | return 0; | ||
5173 | } | ||
5174 | |||
5175 | printk("GDT-HA: Storage RAID Controller Driver. Version: %s\n", | ||
5176 | GDTH_VERSION_STR); | ||
5177 | |||
5178 | /* initializations */ | ||
5179 | gdth_polling = TRUE; | ||
5180 | gdth_clear_events(); | ||
5181 | |||
5182 | /* As default we do not probe for EISA or ISA controllers */ | ||
5183 | if (probe_eisa_isa) { | ||
5184 | /* scanning for controllers, at first: ISA controller */ | ||
5185 | #ifdef CONFIG_ISA | ||
5186 | ulong32 isa_bios; | ||
5187 | for (isa_bios = 0xc8000UL; isa_bios <= 0xd8000UL; | ||
5188 | isa_bios += 0x8000UL) | ||
5189 | gdth_isa_probe_one(isa_bios); | ||
5190 | #endif | ||
5191 | #ifdef CONFIG_EISA | ||
5192 | { | ||
5193 | ushort eisa_slot; | ||
5194 | for (eisa_slot = 0x1000; eisa_slot <= 0x8000; | ||
5195 | eisa_slot += 0x1000) | ||
5196 | gdth_eisa_probe_one(eisa_slot); | ||
5197 | } | ||
5198 | #endif | ||
5199 | } | ||
5200 | |||
5201 | #ifdef CONFIG_PCI | ||
5202 | /* scanning for PCI controllers */ | ||
5203 | { | ||
5204 | gdth_pci_str pcistr[MAXHA]; | ||
5205 | int cnt,ctr; | ||
5206 | |||
5207 | cnt = gdth_search_pci(pcistr); | ||
5208 | printk("GDT-HA: Found %d PCI Storage RAID Controllers\n", cnt); | ||
5209 | gdth_sort_pci(pcistr,cnt); | ||
5210 | for (ctr = 0; ctr < cnt; ++ctr) | ||
5211 | gdth_pci_probe_one(pcistr, ctr); | ||
5212 | } | ||
5213 | #endif /* CONFIG_PCI */ | ||
5214 | |||
5215 | TRACE2(("gdth_detect() %d controller detected\n", gdth_ctr_count)); | ||
5216 | #ifdef GDTH_STATISTICS | ||
5217 | TRACE2(("gdth_detect(): Initializing timer !\n")); | ||
5218 | init_timer(&gdth_timer); | ||
5219 | gdth_timer.expires = jiffies + HZ; | ||
5220 | gdth_timer.data = 0L; | ||
5221 | gdth_timer.function = gdth_timeout; | ||
5222 | add_timer(&gdth_timer); | ||
5223 | #endif | ||
5224 | major = register_chrdev(0,"gdth", &gdth_fops); | ||
5225 | notifier_disabled = 0; | ||
5226 | register_reboot_notifier(&gdth_notifier); | ||
5227 | gdth_polling = FALSE; | ||
5228 | return 0; | ||
5229 | } | ||
5230 | |||
5231 | static void __exit gdth_exit(void) | ||
5232 | { | ||
5233 | gdth_ha_str *ha; | ||
5234 | |||
5235 | list_for_each_entry(ha, &gdth_instances, list) | ||
5236 | gdth_remove_one(ha); | ||
5237 | |||
5238 | #ifdef GDTH_STATISTICS | ||
5239 | del_timer(&gdth_timer); | ||
5240 | #endif | ||
5241 | unregister_chrdev(major,"gdth"); | ||
5242 | unregister_reboot_notifier(&gdth_notifier); | ||
5243 | } | ||
5244 | |||
5245 | module_init(gdth_init); | ||
5246 | module_exit(gdth_exit); | ||
5671 | 5247 | ||
5672 | #include "scsi_module.c" | ||
5673 | #ifndef MODULE | 5248 | #ifndef MODULE |
5674 | __setup("gdth=", option_setup); | 5249 | __setup("gdth=", option_setup); |
5675 | #endif | 5250 | #endif |
diff --git a/drivers/scsi/gdth.h b/drivers/scsi/gdth.h index 37423300592e..1434c6b0297c 100644 --- a/drivers/scsi/gdth.h +++ b/drivers/scsi/gdth.h | |||
@@ -13,7 +13,6 @@ | |||
13 | * $Id: gdth.h,v 1.58 2006/01/11 16:14:09 achim Exp $ | 13 | * $Id: gdth.h,v 1.58 2006/01/11 16:14:09 achim Exp $ |
14 | */ | 14 | */ |
15 | 15 | ||
16 | #include <linux/version.h> | ||
17 | #include <linux/types.h> | 16 | #include <linux/types.h> |
18 | 17 | ||
19 | #ifndef TRUE | 18 | #ifndef TRUE |
@@ -304,15 +303,8 @@ | |||
304 | #define MAILBOXREG 0x0c90 /* mailbox reg. (16 bytes) */ | 303 | #define MAILBOXREG 0x0c90 /* mailbox reg. (16 bytes) */ |
305 | #define EISAREG 0x0cc0 /* EISA configuration */ | 304 | #define EISAREG 0x0cc0 /* EISA configuration */ |
306 | 305 | ||
307 | /* DMA memory mappings */ | ||
308 | #define GDTH_MAP_NONE 0 | ||
309 | #define GDTH_MAP_SINGLE 1 | ||
310 | #define GDTH_MAP_SG 2 | ||
311 | #define GDTH_MAP_IOCTL 3 | ||
312 | |||
313 | /* other defines */ | 306 | /* other defines */ |
314 | #define LINUX_OS 8 /* used for cache optim. */ | 307 | #define LINUX_OS 8 /* used for cache optim. */ |
315 | #define SCATTER_GATHER 1 /* s/g feature */ | ||
316 | #define SECS32 0x1f /* round capacity */ | 308 | #define SECS32 0x1f /* round capacity */ |
317 | #define BIOS_ID_OFFS 0x10 /* offset contr-ID in ISABIOS */ | 309 | #define BIOS_ID_OFFS 0x10 /* offset contr-ID in ISABIOS */ |
318 | #define LOCALBOARD 0 /* board node always 0 */ | 310 | #define LOCALBOARD 0 /* board node always 0 */ |
@@ -854,6 +846,9 @@ typedef struct { | |||
854 | 846 | ||
855 | /* controller information structure */ | 847 | /* controller information structure */ |
856 | typedef struct { | 848 | typedef struct { |
849 | struct Scsi_Host *shost; | ||
850 | struct list_head list; | ||
851 | ushort hanum; | ||
857 | ushort oem_id; /* OEM */ | 852 | ushort oem_id; /* OEM */ |
858 | ushort type; /* controller class */ | 853 | ushort type; /* controller class */ |
859 | ulong32 stype; /* subtype (PCI: device ID) */ | 854 | ulong32 stype; /* subtype (PCI: device ID) */ |
@@ -865,6 +860,7 @@ typedef struct { | |||
865 | void __iomem *brd; /* DPRAM address */ | 860 | void __iomem *brd; /* DPRAM address */ |
866 | ulong32 brd_phys; /* slot number/BIOS address */ | 861 | ulong32 brd_phys; /* slot number/BIOS address */ |
867 | gdt6c_plx_regs *plx; /* PLX regs (new PCI contr.) */ | 862 | gdt6c_plx_regs *plx; /* PLX regs (new PCI contr.) */ |
863 | gdth_cmd_str cmdext; | ||
868 | gdth_cmd_str *pccb; /* address command structure */ | 864 | gdth_cmd_str *pccb; /* address command structure */ |
869 | ulong32 ccb_phys; /* phys. address */ | 865 | ulong32 ccb_phys; /* phys. address */ |
870 | #ifdef INT_COAL | 866 | #ifdef INT_COAL |
@@ -916,6 +912,19 @@ typedef struct { | |||
916 | Scsi_Cmnd *cmnd; /* pending request */ | 912 | Scsi_Cmnd *cmnd; /* pending request */ |
917 | ushort service; /* service */ | 913 | ushort service; /* service */ |
918 | } cmd_tab[GDTH_MAXCMDS]; /* table of pend. requests */ | 914 | } cmd_tab[GDTH_MAXCMDS]; /* table of pend. requests */ |
915 | struct gdth_cmndinfo { /* per-command private info */ | ||
916 | int index; | ||
917 | int internal_command; /* don't call scsi_done */ | ||
918 | dma_addr_t sense_paddr; /* sense dma-addr */ | ||
919 | unchar priority; | ||
920 | int timeout; | ||
921 | volatile int wait_for_completion; | ||
922 | ushort status; | ||
923 | ulong32 info; | ||
924 | enum dma_data_direction dma_dir; | ||
925 | int phase; /* ???? */ | ||
926 | int OpCode; | ||
927 | } cmndinfo[GDTH_MAXCMDS]; /* index==0 is free */ | ||
919 | unchar bus_cnt; /* SCSI bus count */ | 928 | unchar bus_cnt; /* SCSI bus count */ |
920 | unchar tid_cnt; /* Target ID count */ | 929 | unchar tid_cnt; /* Target ID count */ |
921 | unchar bus_id[MAXBUS]; /* IOP IDs */ | 930 | unchar bus_id[MAXBUS]; /* IOP IDs */ |
@@ -938,19 +947,10 @@ typedef struct { | |||
938 | struct scsi_device *sdev; | 947 | struct scsi_device *sdev; |
939 | } gdth_ha_str; | 948 | } gdth_ha_str; |
940 | 949 | ||
941 | /* structure for scsi_register(), SCSI bus != 0 */ | 950 | static inline struct gdth_cmndinfo *gdth_cmnd_priv(struct scsi_cmnd* cmd) |
942 | typedef struct { | 951 | { |
943 | ushort hanum; | 952 | return (struct gdth_cmndinfo *)cmd->host_scribble; |
944 | ushort busnum; | 953 | } |
945 | } gdth_num_str; | ||
946 | |||
947 | /* structure for scsi_register() */ | ||
948 | typedef struct { | ||
949 | gdth_num_str numext; /* must be the first element */ | ||
950 | gdth_ha_str haext; | ||
951 | gdth_cmd_str cmdext; | ||
952 | } gdth_ext_str; | ||
953 | |||
954 | 954 | ||
955 | /* INQUIRY data format */ | 955 | /* INQUIRY data format */ |
956 | typedef struct { | 956 | typedef struct { |
diff --git a/drivers/scsi/gdth_kcompat.h b/drivers/scsi/gdth_kcompat.h deleted file mode 100644 index 2a302eee669a..000000000000 --- a/drivers/scsi/gdth_kcompat.h +++ /dev/null | |||
@@ -1,31 +0,0 @@ | |||
1 | #ifndef IRQ_HANDLED | ||
2 | typedef void irqreturn_t; | ||
3 | #define IRQ_NONE | ||
4 | #define IRQ_HANDLED | ||
5 | #endif | ||
6 | |||
7 | #ifndef MODULE_LICENSE | ||
8 | #define MODULE_LICENSE(x) | ||
9 | #endif | ||
10 | |||
11 | #ifndef __iomem | ||
12 | #define __iomem | ||
13 | #endif | ||
14 | |||
15 | #ifndef __attribute_used__ | ||
16 | #define __attribute_used__ __devinitdata | ||
17 | #endif | ||
18 | |||
19 | #ifndef __user | ||
20 | #define __user | ||
21 | #endif | ||
22 | |||
23 | #ifndef SERVICE_ACTION_IN | ||
24 | #define SERVICE_ACTION_IN 0x9e | ||
25 | #endif | ||
26 | #ifndef READ_16 | ||
27 | #define READ_16 0x88 | ||
28 | #endif | ||
29 | #ifndef WRITE_16 | ||
30 | #define WRITE_16 0x8a | ||
31 | #endif | ||
diff --git a/drivers/scsi/gdth_proc.c b/drivers/scsi/gdth_proc.c index 32982eb75c84..de5773443c62 100644 --- a/drivers/scsi/gdth_proc.c +++ b/drivers/scsi/gdth_proc.c | |||
@@ -4,62 +4,32 @@ | |||
4 | 4 | ||
5 | #include <linux/completion.h> | 5 | #include <linux/completion.h> |
6 | 6 | ||
7 | #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,0) | ||
8 | int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length, | 7 | int gdth_proc_info(struct Scsi_Host *host, char *buffer,char **start,off_t offset,int length, |
9 | int inout) | 8 | int inout) |
10 | { | 9 | { |
11 | int hanum,busnum; | 10 | gdth_ha_str *ha = shost_priv(host); |
12 | 11 | ||
13 | TRACE2(("gdth_proc_info() length %d offs %d inout %d\n", | 12 | TRACE2(("gdth_proc_info() length %d offs %d inout %d\n", |
14 | length,(int)offset,inout)); | 13 | length,(int)offset,inout)); |
15 | 14 | ||
16 | hanum = NUMDATA(host)->hanum; | ||
17 | busnum= NUMDATA(host)->busnum; | ||
18 | |||
19 | if (inout) | ||
20 | return(gdth_set_info(buffer,length,host,hanum,busnum)); | ||
21 | else | ||
22 | return(gdth_get_info(buffer,start,offset,length,host,hanum,busnum)); | ||
23 | } | ||
24 | #else | ||
25 | int gdth_proc_info(char *buffer,char **start,off_t offset,int length,int hostno, | ||
26 | int inout) | ||
27 | { | ||
28 | int hanum,busnum,i; | ||
29 | |||
30 | TRACE2(("gdth_proc_info() length %d offs %d inout %d\n", | ||
31 | length,(int)offset,inout)); | ||
32 | |||
33 | for (i = 0; i < gdth_ctr_vcount; ++i) { | ||
34 | if (gdth_ctr_vtab[i]->host_no == hostno) | ||
35 | break; | ||
36 | } | ||
37 | if (i == gdth_ctr_vcount) | ||
38 | return(-EINVAL); | ||
39 | |||
40 | hanum = NUMDATA(gdth_ctr_vtab[i])->hanum; | ||
41 | busnum= NUMDATA(gdth_ctr_vtab[i])->busnum; | ||
42 | |||
43 | if (inout) | 15 | if (inout) |
44 | return(gdth_set_info(buffer,length,gdth_ctr_vtab[i],hanum,busnum)); | 16 | return(gdth_set_info(buffer,length,host,ha)); |
45 | else | 17 | else |
46 | return(gdth_get_info(buffer,start,offset,length, | 18 | return(gdth_get_info(buffer,start,offset,length,host,ha)); |
47 | gdth_ctr_vtab[i],hanum,busnum)); | ||
48 | } | 19 | } |
49 | #endif | ||
50 | 20 | ||
51 | static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, | 21 | static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, |
52 | int hanum,int busnum) | 22 | gdth_ha_str *ha) |
53 | { | 23 | { |
54 | int ret_val = -EINVAL; | 24 | int ret_val = -EINVAL; |
55 | 25 | ||
56 | TRACE2(("gdth_set_info() ha %d bus %d\n",hanum,busnum)); | 26 | TRACE2(("gdth_set_info() ha %d\n",ha->hanum,)); |
57 | 27 | ||
58 | if (length >= 4) { | 28 | if (length >= 4) { |
59 | if (strncmp(buffer,"gdth",4) == 0) { | 29 | if (strncmp(buffer,"gdth",4) == 0) { |
60 | buffer += 5; | 30 | buffer += 5; |
61 | length -= 5; | 31 | length -= 5; |
62 | ret_val = gdth_set_asc_info(host, buffer, length, hanum); | 32 | ret_val = gdth_set_asc_info(host, buffer, length, ha); |
63 | } | 33 | } |
64 | } | 34 | } |
65 | 35 | ||
@@ -67,11 +37,10 @@ static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, | |||
67 | } | 37 | } |
68 | 38 | ||
69 | static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, | 39 | static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, |
70 | int length,int hanum) | 40 | int length, gdth_ha_str *ha) |
71 | { | 41 | { |
72 | int orig_length, drive, wb_mode; | 42 | int orig_length, drive, wb_mode; |
73 | int i, found; | 43 | int i, found; |
74 | gdth_ha_str *ha; | ||
75 | gdth_cmd_str gdtcmd; | 44 | gdth_cmd_str gdtcmd; |
76 | gdth_cpar_str *pcpar; | 45 | gdth_cpar_str *pcpar; |
77 | ulong64 paddr; | 46 | ulong64 paddr; |
@@ -80,8 +49,7 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, | |||
80 | memset(cmnd, 0xff, 12); | 49 | memset(cmnd, 0xff, 12); |
81 | memset(&gdtcmd, 0, sizeof(gdth_cmd_str)); | 50 | memset(&gdtcmd, 0, sizeof(gdth_cmd_str)); |
82 | 51 | ||
83 | TRACE2(("gdth_set_asc_info() ha %d\n",hanum)); | 52 | TRACE2(("gdth_set_asc_info() ha %d\n",ha->hanum)); |
84 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
85 | orig_length = length + 5; | 53 | orig_length = length + 5; |
86 | drive = -1; | 54 | drive = -1; |
87 | wb_mode = 0; | 55 | wb_mode = 0; |
@@ -157,7 +125,7 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, | |||
157 | } | 125 | } |
158 | 126 | ||
159 | if (wb_mode) { | 127 | if (wb_mode) { |
160 | if (!gdth_ioctl_alloc(hanum, sizeof(gdth_cpar_str), TRUE, &paddr)) | 128 | if (!gdth_ioctl_alloc(ha, sizeof(gdth_cpar_str), TRUE, &paddr)) |
161 | return(-EBUSY); | 129 | return(-EBUSY); |
162 | pcpar = (gdth_cpar_str *)ha->pscratch; | 130 | pcpar = (gdth_cpar_str *)ha->pscratch; |
163 | memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) ); | 131 | memcpy( pcpar, &ha->cpar, sizeof(gdth_cpar_str) ); |
@@ -171,7 +139,7 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, | |||
171 | 139 | ||
172 | gdth_execute(host, &gdtcmd, cmnd, 30, NULL); | 140 | gdth_execute(host, &gdtcmd, cmnd, 30, NULL); |
173 | 141 | ||
174 | gdth_ioctl_free(hanum, GDTH_SCRATCH, ha->pscratch, paddr); | 142 | gdth_ioctl_free(ha, GDTH_SCRATCH, ha->pscratch, paddr); |
175 | printk("Done.\n"); | 143 | printk("Done.\n"); |
176 | return(orig_length); | 144 | return(orig_length); |
177 | } | 145 | } |
@@ -181,11 +149,10 @@ static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, | |||
181 | } | 149 | } |
182 | 150 | ||
183 | static int gdth_get_info(char *buffer,char **start,off_t offset,int length, | 151 | static int gdth_get_info(char *buffer,char **start,off_t offset,int length, |
184 | struct Scsi_Host *host,int hanum,int busnum) | 152 | struct Scsi_Host *host, gdth_ha_str *ha) |
185 | { | 153 | { |
186 | int size = 0,len = 0; | 154 | int size = 0,len = 0; |
187 | off_t begin = 0,pos = 0; | 155 | off_t begin = 0,pos = 0; |
188 | gdth_ha_str *ha; | ||
189 | int id, i, j, k, sec, flag; | 156 | int id, i, j, k, sec, flag; |
190 | int no_mdrv = 0, drv_no, is_mirr; | 157 | int no_mdrv = 0, drv_no, is_mirr; |
191 | ulong32 cnt; | 158 | ulong32 cnt; |
@@ -214,8 +181,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, | |||
214 | memset(cmnd, 0xff, 12); | 181 | memset(cmnd, 0xff, 12); |
215 | memset(gdtcmd, 0, sizeof(gdth_cmd_str)); | 182 | memset(gdtcmd, 0, sizeof(gdth_cmd_str)); |
216 | 183 | ||
217 | TRACE2(("gdth_get_info() ha %d bus %d\n",hanum,busnum)); | 184 | TRACE2(("gdth_get_info() ha %d\n",ha->hanum)); |
218 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
219 | 185 | ||
220 | 186 | ||
221 | /* request is i.e. "cat /proc/scsi/gdth/0" */ | 187 | /* request is i.e. "cat /proc/scsi/gdth/0" */ |
@@ -245,13 +211,10 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, | |||
245 | /* controller information */ | 211 | /* controller information */ |
246 | size = sprintf(buffer+len,"\nDisk Array Controller Information:\n"); | 212 | size = sprintf(buffer+len,"\nDisk Array Controller Information:\n"); |
247 | len += size; pos = begin + len; | 213 | len += size; pos = begin + len; |
248 | if (virt_ctr) | 214 | strcpy(hrec, ha->binfo.type_string); |
249 | sprintf(hrec, "%s (Bus %d)", ha->binfo.type_string, busnum); | ||
250 | else | ||
251 | strcpy(hrec, ha->binfo.type_string); | ||
252 | size = sprintf(buffer+len, | 215 | size = sprintf(buffer+len, |
253 | " Number: \t%d \tName: \t%s\n", | 216 | " Number: \t%d \tName: \t%s\n", |
254 | hanum, hrec); | 217 | ha->hanum, hrec); |
255 | len += size; pos = begin + len; | 218 | len += size; pos = begin + len; |
256 | 219 | ||
257 | if (ha->more_proc) | 220 | if (ha->more_proc) |
@@ -301,7 +264,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, | |||
301 | len += size; pos = begin + len; | 264 | len += size; pos = begin + len; |
302 | flag = FALSE; | 265 | flag = FALSE; |
303 | 266 | ||
304 | buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE, &paddr); | 267 | buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr); |
305 | if (!buf) | 268 | if (!buf) |
306 | goto stop_output; | 269 | goto stop_output; |
307 | for (i = 0; i < ha->bus_cnt; ++i) { | 270 | for (i = 0; i < ha->bus_cnt; ++i) { |
@@ -404,7 +367,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, | |||
404 | goto stop_output; | 367 | goto stop_output; |
405 | } | 368 | } |
406 | } | 369 | } |
407 | gdth_ioctl_free(hanum, GDTH_SCRATCH, buf, paddr); | 370 | gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); |
408 | 371 | ||
409 | if (!flag) { | 372 | if (!flag) { |
410 | size = sprintf(buffer+len, "\n --\n"); | 373 | size = sprintf(buffer+len, "\n --\n"); |
@@ -416,7 +379,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, | |||
416 | len += size; pos = begin + len; | 379 | len += size; pos = begin + len; |
417 | flag = FALSE; | 380 | flag = FALSE; |
418 | 381 | ||
419 | buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE, &paddr); | 382 | buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr); |
420 | if (!buf) | 383 | if (!buf) |
421 | goto stop_output; | 384 | goto stop_output; |
422 | for (i = 0; i < MAX_LDRIVES; ++i) { | 385 | for (i = 0; i < MAX_LDRIVES; ++i) { |
@@ -510,7 +473,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, | |||
510 | if (pos > offset + length) | 473 | if (pos > offset + length) |
511 | goto stop_output; | 474 | goto stop_output; |
512 | } | 475 | } |
513 | gdth_ioctl_free(hanum, GDTH_SCRATCH, buf, paddr); | 476 | gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); |
514 | 477 | ||
515 | if (!flag) { | 478 | if (!flag) { |
516 | size = sprintf(buffer+len, "\n --\n"); | 479 | size = sprintf(buffer+len, "\n --\n"); |
@@ -522,7 +485,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, | |||
522 | len += size; pos = begin + len; | 485 | len += size; pos = begin + len; |
523 | flag = FALSE; | 486 | flag = FALSE; |
524 | 487 | ||
525 | buf = gdth_ioctl_alloc(hanum, GDTH_SCRATCH, FALSE, &paddr); | 488 | buf = gdth_ioctl_alloc(ha, GDTH_SCRATCH, FALSE, &paddr); |
526 | if (!buf) | 489 | if (!buf) |
527 | goto stop_output; | 490 | goto stop_output; |
528 | for (i = 0; i < MAX_LDRIVES; ++i) { | 491 | for (i = 0; i < MAX_LDRIVES; ++i) { |
@@ -581,7 +544,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, | |||
581 | goto stop_output; | 544 | goto stop_output; |
582 | } | 545 | } |
583 | } | 546 | } |
584 | gdth_ioctl_free(hanum, GDTH_SCRATCH, buf, paddr); | 547 | gdth_ioctl_free(ha, GDTH_SCRATCH, buf, paddr); |
585 | 548 | ||
586 | if (!flag) { | 549 | if (!flag) { |
587 | size = sprintf(buffer+len, "\n --\n"); | 550 | size = sprintf(buffer+len, "\n --\n"); |
@@ -593,7 +556,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, | |||
593 | len += size; pos = begin + len; | 556 | len += size; pos = begin + len; |
594 | flag = FALSE; | 557 | flag = FALSE; |
595 | 558 | ||
596 | buf = gdth_ioctl_alloc(hanum, sizeof(gdth_hget_str), FALSE, &paddr); | 559 | buf = gdth_ioctl_alloc(ha, sizeof(gdth_hget_str), FALSE, &paddr); |
597 | if (!buf) | 560 | if (!buf) |
598 | goto stop_output; | 561 | goto stop_output; |
599 | for (i = 0; i < MAX_LDRIVES; ++i) { | 562 | for (i = 0; i < MAX_LDRIVES; ++i) { |
@@ -626,7 +589,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, | |||
626 | } | 589 | } |
627 | } | 590 | } |
628 | } | 591 | } |
629 | gdth_ioctl_free(hanum, sizeof(gdth_hget_str), buf, paddr); | 592 | gdth_ioctl_free(ha, sizeof(gdth_hget_str), buf, paddr); |
630 | 593 | ||
631 | for (i = 0; i < MAX_HDRIVES; ++i) { | 594 | for (i = 0; i < MAX_HDRIVES; ++i) { |
632 | if (!(ha->hdr[i].present)) | 595 | if (!(ha->hdr[i].present)) |
@@ -664,7 +627,7 @@ static int gdth_get_info(char *buffer,char **start,off_t offset,int length, | |||
664 | id = gdth_read_event(ha, id, estr); | 627 | id = gdth_read_event(ha, id, estr); |
665 | if (estr->event_source == 0) | 628 | if (estr->event_source == 0) |
666 | break; | 629 | break; |
667 | if (estr->event_data.eu.driver.ionode == hanum && | 630 | if (estr->event_data.eu.driver.ionode == ha->hanum && |
668 | estr->event_source == ES_ASYNC) { | 631 | estr->event_source == ES_ASYNC) { |
669 | gdth_log_event(&estr->event_data, hrec); | 632 | gdth_log_event(&estr->event_data, hrec); |
670 | do_gettimeofday(&tv); | 633 | do_gettimeofday(&tv); |
@@ -699,17 +662,15 @@ free_fail: | |||
699 | return rc; | 662 | return rc; |
700 | } | 663 | } |
701 | 664 | ||
702 | static char *gdth_ioctl_alloc(int hanum, int size, int scratch, | 665 | static char *gdth_ioctl_alloc(gdth_ha_str *ha, int size, int scratch, |
703 | ulong64 *paddr) | 666 | ulong64 *paddr) |
704 | { | 667 | { |
705 | gdth_ha_str *ha; | ||
706 | ulong flags; | 668 | ulong flags; |
707 | char *ret_val; | 669 | char *ret_val; |
708 | 670 | ||
709 | if (size == 0) | 671 | if (size == 0) |
710 | return NULL; | 672 | return NULL; |
711 | 673 | ||
712 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
713 | spin_lock_irqsave(&ha->smp_lock, flags); | 674 | spin_lock_irqsave(&ha->smp_lock, flags); |
714 | 675 | ||
715 | if (!ha->scratch_busy && size <= GDTH_SCRATCH) { | 676 | if (!ha->scratch_busy && size <= GDTH_SCRATCH) { |
@@ -729,12 +690,10 @@ static char *gdth_ioctl_alloc(int hanum, int size, int scratch, | |||
729 | return ret_val; | 690 | return ret_val; |
730 | } | 691 | } |
731 | 692 | ||
732 | static void gdth_ioctl_free(int hanum, int size, char *buf, ulong64 paddr) | 693 | static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, ulong64 paddr) |
733 | { | 694 | { |
734 | gdth_ha_str *ha; | ||
735 | ulong flags; | 695 | ulong flags; |
736 | 696 | ||
737 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
738 | spin_lock_irqsave(&ha->smp_lock, flags); | 697 | spin_lock_irqsave(&ha->smp_lock, flags); |
739 | 698 | ||
740 | if (buf == ha->pscratch) { | 699 | if (buf == ha->pscratch) { |
@@ -747,13 +706,11 @@ static void gdth_ioctl_free(int hanum, int size, char *buf, ulong64 paddr) | |||
747 | } | 706 | } |
748 | 707 | ||
749 | #ifdef GDTH_IOCTL_PROC | 708 | #ifdef GDTH_IOCTL_PROC |
750 | static int gdth_ioctl_check_bin(int hanum, ushort size) | 709 | static int gdth_ioctl_check_bin(gdth_ha_str *ha, ushort size) |
751 | { | 710 | { |
752 | gdth_ha_str *ha; | ||
753 | ulong flags; | 711 | ulong flags; |
754 | int ret_val; | 712 | int ret_val; |
755 | 713 | ||
756 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
757 | spin_lock_irqsave(&ha->smp_lock, flags); | 714 | spin_lock_irqsave(&ha->smp_lock, flags); |
758 | 715 | ||
759 | ret_val = FALSE; | 716 | ret_val = FALSE; |
@@ -766,27 +723,27 @@ static int gdth_ioctl_check_bin(int hanum, ushort size) | |||
766 | } | 723 | } |
767 | #endif | 724 | #endif |
768 | 725 | ||
769 | static void gdth_wait_completion(int hanum, int busnum, int id) | 726 | static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id) |
770 | { | 727 | { |
771 | gdth_ha_str *ha; | ||
772 | ulong flags; | 728 | ulong flags; |
773 | int i; | 729 | int i; |
774 | Scsi_Cmnd *scp; | 730 | Scsi_Cmnd *scp; |
731 | struct gdth_cmndinfo *cmndinfo; | ||
775 | unchar b, t; | 732 | unchar b, t; |
776 | 733 | ||
777 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
778 | spin_lock_irqsave(&ha->smp_lock, flags); | 734 | spin_lock_irqsave(&ha->smp_lock, flags); |
779 | 735 | ||
780 | for (i = 0; i < GDTH_MAXCMDS; ++i) { | 736 | for (i = 0; i < GDTH_MAXCMDS; ++i) { |
781 | scp = ha->cmd_tab[i].cmnd; | 737 | scp = ha->cmd_tab[i].cmnd; |
738 | cmndinfo = gdth_cmnd_priv(scp); | ||
782 | 739 | ||
783 | b = virt_ctr ? NUMDATA(scp->device->host)->busnum : scp->device->channel; | 740 | b = scp->device->channel; |
784 | t = scp->device->id; | 741 | t = scp->device->id; |
785 | if (!SPECIAL_SCP(scp) && t == (unchar)id && | 742 | if (!SPECIAL_SCP(scp) && t == (unchar)id && |
786 | b == (unchar)busnum) { | 743 | b == (unchar)busnum) { |
787 | scp->SCp.have_data_in = 0; | 744 | cmndinfo->wait_for_completion = 0; |
788 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 745 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
789 | while (!scp->SCp.have_data_in) | 746 | while (!cmndinfo->wait_for_completion) |
790 | barrier(); | 747 | barrier(); |
791 | spin_lock_irqsave(&ha->smp_lock, flags); | 748 | spin_lock_irqsave(&ha->smp_lock, flags); |
792 | } | 749 | } |
@@ -794,55 +751,51 @@ static void gdth_wait_completion(int hanum, int busnum, int id) | |||
794 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 751 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
795 | } | 752 | } |
796 | 753 | ||
797 | static void gdth_stop_timeout(int hanum, int busnum, int id) | 754 | static void gdth_stop_timeout(gdth_ha_str *ha, int busnum, int id) |
798 | { | 755 | { |
799 | gdth_ha_str *ha; | ||
800 | ulong flags; | 756 | ulong flags; |
801 | Scsi_Cmnd *scp; | 757 | Scsi_Cmnd *scp; |
802 | unchar b, t; | 758 | unchar b, t; |
803 | 759 | ||
804 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
805 | spin_lock_irqsave(&ha->smp_lock, flags); | 760 | spin_lock_irqsave(&ha->smp_lock, flags); |
806 | 761 | ||
807 | for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { | 762 | for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { |
808 | if (scp->done != gdth_scsi_done) { | 763 | struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); |
809 | b = virt_ctr ? | 764 | if (!cmndinfo->internal_command) { |
810 | NUMDATA(scp->device->host)->busnum : scp->device->channel; | 765 | b = scp->device->channel; |
811 | t = scp->device->id; | 766 | t = scp->device->id; |
812 | if (t == (unchar)id && b == (unchar)busnum) { | 767 | if (t == (unchar)id && b == (unchar)busnum) { |
813 | TRACE2(("gdth_stop_timeout(): update_timeout()\n")); | 768 | TRACE2(("gdth_stop_timeout(): update_timeout()\n")); |
814 | scp->SCp.buffers_residual = gdth_update_timeout(hanum, scp, 0); | 769 | cmndinfo->timeout = gdth_update_timeout(scp, 0); |
815 | } | 770 | } |
816 | } | 771 | } |
817 | } | 772 | } |
818 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 773 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
819 | } | 774 | } |
820 | 775 | ||
821 | static void gdth_start_timeout(int hanum, int busnum, int id) | 776 | static void gdth_start_timeout(gdth_ha_str *ha, int busnum, int id) |
822 | { | 777 | { |
823 | gdth_ha_str *ha; | ||
824 | ulong flags; | 778 | ulong flags; |
825 | Scsi_Cmnd *scp; | 779 | Scsi_Cmnd *scp; |
826 | unchar b, t; | 780 | unchar b, t; |
827 | 781 | ||
828 | ha = HADATA(gdth_ctr_tab[hanum]); | ||
829 | spin_lock_irqsave(&ha->smp_lock, flags); | 782 | spin_lock_irqsave(&ha->smp_lock, flags); |
830 | 783 | ||
831 | for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { | 784 | for (scp = ha->req_first; scp; scp = (Scsi_Cmnd *)scp->SCp.ptr) { |
832 | if (scp->done != gdth_scsi_done) { | 785 | struct gdth_cmndinfo *cmndinfo = gdth_cmnd_priv(scp); |
833 | b = virt_ctr ? | 786 | if (!cmndinfo->internal_command) { |
834 | NUMDATA(scp->device->host)->busnum : scp->device->channel; | 787 | b = scp->device->channel; |
835 | t = scp->device->id; | 788 | t = scp->device->id; |
836 | if (t == (unchar)id && b == (unchar)busnum) { | 789 | if (t == (unchar)id && b == (unchar)busnum) { |
837 | TRACE2(("gdth_start_timeout(): update_timeout()\n")); | 790 | TRACE2(("gdth_start_timeout(): update_timeout()\n")); |
838 | gdth_update_timeout(hanum, scp, scp->SCp.buffers_residual); | 791 | gdth_update_timeout(scp, cmndinfo->timeout); |
839 | } | 792 | } |
840 | } | 793 | } |
841 | } | 794 | } |
842 | spin_unlock_irqrestore(&ha->smp_lock, flags); | 795 | spin_unlock_irqrestore(&ha->smp_lock, flags); |
843 | } | 796 | } |
844 | 797 | ||
845 | static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout) | 798 | static int gdth_update_timeout(Scsi_Cmnd *scp, int timeout) |
846 | { | 799 | { |
847 | int oldto; | 800 | int oldto; |
848 | 801 | ||
diff --git a/drivers/scsi/gdth_proc.h b/drivers/scsi/gdth_proc.h index a679eeb6820b..45e6fdacf36e 100644 --- a/drivers/scsi/gdth_proc.h +++ b/drivers/scsi/gdth_proc.h | |||
@@ -9,20 +9,20 @@ int gdth_execute(struct Scsi_Host *shost, gdth_cmd_str *gdtcmd, char *cmnd, | |||
9 | int timeout, u32 *info); | 9 | int timeout, u32 *info); |
10 | 10 | ||
11 | static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, | 11 | static int gdth_set_info(char *buffer,int length,struct Scsi_Host *host, |
12 | int hanum,int busnum); | 12 | gdth_ha_str *ha); |
13 | static int gdth_get_info(char *buffer,char **start,off_t offset,int length, | 13 | static int gdth_get_info(char *buffer,char **start,off_t offset,int length, |
14 | struct Scsi_Host *host,int hanum,int busnum); | 14 | struct Scsi_Host *host, gdth_ha_str *ha); |
15 | 15 | ||
16 | static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, | 16 | static int gdth_set_asc_info(struct Scsi_Host *host, char *buffer, |
17 | int length, int hanum); | 17 | int length, gdth_ha_str *ha); |
18 | 18 | ||
19 | static char *gdth_ioctl_alloc(int hanum, int size, int scratch, | 19 | static char *gdth_ioctl_alloc(gdth_ha_str *ha, int size, int scratch, |
20 | ulong64 *paddr); | 20 | ulong64 *paddr); |
21 | static void gdth_ioctl_free(int hanum, int size, char *buf, ulong64 paddr); | 21 | static void gdth_ioctl_free(gdth_ha_str *ha, int size, char *buf, ulong64 paddr); |
22 | static void gdth_wait_completion(int hanum, int busnum, int id); | 22 | static void gdth_wait_completion(gdth_ha_str *ha, int busnum, int id); |
23 | static void gdth_stop_timeout(int hanum, int busnum, int id); | 23 | static void gdth_stop_timeout(gdth_ha_str *ha, int busnum, int id); |
24 | static void gdth_start_timeout(int hanum, int busnum, int id); | 24 | static void gdth_start_timeout(gdth_ha_str *ha, int busnum, int id); |
25 | static int gdth_update_timeout(int hanum, Scsi_Cmnd *scp, int timeout); | 25 | static int gdth_update_timeout(Scsi_Cmnd *scp, int timeout); |
26 | 26 | ||
27 | #endif | 27 | #endif |
28 | 28 | ||
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c index 96bc31266c98..adc9559cb6f4 100644 --- a/drivers/scsi/hosts.c +++ b/drivers/scsi/hosts.c | |||
@@ -342,6 +342,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize) | |||
342 | shost->unchecked_isa_dma = sht->unchecked_isa_dma; | 342 | shost->unchecked_isa_dma = sht->unchecked_isa_dma; |
343 | shost->use_clustering = sht->use_clustering; | 343 | shost->use_clustering = sht->use_clustering; |
344 | shost->ordered_tag = sht->ordered_tag; | 344 | shost->ordered_tag = sht->ordered_tag; |
345 | shost->active_mode = sht->supported_mode; | ||
345 | 346 | ||
346 | if (sht->max_host_blocked) | 347 | if (sht->max_host_blocked) |
347 | shost->max_host_blocked = sht->max_host_blocked; | 348 | shost->max_host_blocked = sht->max_host_blocked; |
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c index 0e579ca45814..8b384fa7f048 100644 --- a/drivers/scsi/hptiop.c +++ b/drivers/scsi/hptiop.c | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * HighPoint RR3xxx controller driver for Linux | 2 | * HighPoint RR3xxx controller driver for Linux |
3 | * Copyright (C) 2006 HighPoint Technologies, Inc. All Rights Reserved. | 3 | * Copyright (C) 2006-2007 HighPoint Technologies, Inc. All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
@@ -42,7 +42,7 @@ MODULE_DESCRIPTION("HighPoint RocketRAID 3xxx SATA Controller Driver"); | |||
42 | 42 | ||
43 | static char driver_name[] = "hptiop"; | 43 | static char driver_name[] = "hptiop"; |
44 | static const char driver_name_long[] = "RocketRAID 3xxx SATA Controller driver"; | 44 | static const char driver_name_long[] = "RocketRAID 3xxx SATA Controller driver"; |
45 | static const char driver_ver[] = "v1.0 (060426)"; | 45 | static const char driver_ver[] = "v1.2 (070830)"; |
46 | 46 | ||
47 | static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag); | 47 | static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag); |
48 | static void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag); | 48 | static void hptiop_iop_request_callback(struct hptiop_hba *hba, u32 tag); |
@@ -76,7 +76,7 @@ static int iop_wait_ready(struct hpt_iopmu __iomem *iop, u32 millisec) | |||
76 | 76 | ||
77 | static void hptiop_request_callback(struct hptiop_hba *hba, u32 tag) | 77 | static void hptiop_request_callback(struct hptiop_hba *hba, u32 tag) |
78 | { | 78 | { |
79 | if ((tag & IOPMU_QUEUE_MASK_HOST_BITS) == IOPMU_QUEUE_ADDR_HOST_BIT) | 79 | if (tag & IOPMU_QUEUE_ADDR_HOST_BIT) |
80 | return hptiop_host_request_callback(hba, | 80 | return hptiop_host_request_callback(hba, |
81 | tag & ~IOPMU_QUEUE_ADDR_HOST_BIT); | 81 | tag & ~IOPMU_QUEUE_ADDR_HOST_BIT); |
82 | else | 82 | else |
@@ -323,12 +323,22 @@ static inline void free_req(struct hptiop_hba *hba, struct hptiop_request *req) | |||
323 | hba->req_list = req; | 323 | hba->req_list = req; |
324 | } | 324 | } |
325 | 325 | ||
326 | static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 tag) | 326 | static void hptiop_host_request_callback(struct hptiop_hba *hba, u32 _tag) |
327 | { | 327 | { |
328 | struct hpt_iop_request_scsi_command *req; | 328 | struct hpt_iop_request_scsi_command *req; |
329 | struct scsi_cmnd *scp; | 329 | struct scsi_cmnd *scp; |
330 | u32 tag; | ||
331 | |||
332 | if (hba->iopintf_v2) { | ||
333 | tag = _tag & ~ IOPMU_QUEUE_REQUEST_RESULT_BIT; | ||
334 | req = hba->reqs[tag].req_virt; | ||
335 | if (likely(_tag & IOPMU_QUEUE_REQUEST_RESULT_BIT)) | ||
336 | req->header.result = IOP_RESULT_SUCCESS; | ||
337 | } else { | ||
338 | tag = _tag; | ||
339 | req = hba->reqs[tag].req_virt; | ||
340 | } | ||
330 | 341 | ||
331 | req = (struct hpt_iop_request_scsi_command *)hba->reqs[tag].req_virt; | ||
332 | dprintk("hptiop_host_request_callback: req=%p, type=%d, " | 342 | dprintk("hptiop_host_request_callback: req=%p, type=%d, " |
333 | "result=%d, context=0x%x tag=%d\n", | 343 | "result=%d, context=0x%x tag=%d\n", |
334 | req, req->header.type, req->header.result, | 344 | req, req->header.type, req->header.result, |
@@ -497,7 +507,7 @@ static int hptiop_queuecommand(struct scsi_cmnd *scp, | |||
497 | goto cmd_done; | 507 | goto cmd_done; |
498 | } | 508 | } |
499 | 509 | ||
500 | req = (struct hpt_iop_request_scsi_command *)_req->req_virt; | 510 | req = _req->req_virt; |
501 | 511 | ||
502 | /* build S/G table */ | 512 | /* build S/G table */ |
503 | sg_count = hptiop_buildsgl(scp, req->sg_list); | 513 | sg_count = hptiop_buildsgl(scp, req->sg_list); |
@@ -521,8 +531,19 @@ static int hptiop_queuecommand(struct scsi_cmnd *scp, | |||
521 | 531 | ||
522 | memcpy(req->cdb, scp->cmnd, sizeof(req->cdb)); | 532 | memcpy(req->cdb, scp->cmnd, sizeof(req->cdb)); |
523 | 533 | ||
524 | writel(IOPMU_QUEUE_ADDR_HOST_BIT | _req->req_shifted_phy, | 534 | if (hba->iopintf_v2) { |
525 | &hba->iop->inbound_queue); | 535 | u32 size_bits; |
536 | if (req->header.size < 256) | ||
537 | size_bits = IOPMU_QUEUE_REQUEST_SIZE_BIT; | ||
538 | else if (req->header.size < 512) | ||
539 | size_bits = IOPMU_QUEUE_ADDR_HOST_BIT; | ||
540 | else | ||
541 | size_bits = IOPMU_QUEUE_REQUEST_SIZE_BIT | | ||
542 | IOPMU_QUEUE_ADDR_HOST_BIT; | ||
543 | writel(_req->req_shifted_phy | size_bits, &hba->iop->inbound_queue); | ||
544 | } else | ||
545 | writel(_req->req_shifted_phy | IOPMU_QUEUE_ADDR_HOST_BIT, | ||
546 | &hba->iop->inbound_queue); | ||
526 | 547 | ||
527 | return 0; | 548 | return 0; |
528 | 549 | ||
@@ -688,6 +709,7 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev, | |||
688 | hba->pcidev = pcidev; | 709 | hba->pcidev = pcidev; |
689 | hba->host = host; | 710 | hba->host = host; |
690 | hba->initialized = 0; | 711 | hba->initialized = 0; |
712 | hba->iopintf_v2 = 0; | ||
691 | 713 | ||
692 | atomic_set(&hba->resetting, 0); | 714 | atomic_set(&hba->resetting, 0); |
693 | atomic_set(&hba->reset_count, 0); | 715 | atomic_set(&hba->reset_count, 0); |
@@ -722,8 +744,13 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev, | |||
722 | hba->max_request_size = le32_to_cpu(iop_config.request_size); | 744 | hba->max_request_size = le32_to_cpu(iop_config.request_size); |
723 | hba->max_sg_descriptors = le32_to_cpu(iop_config.max_sg_count); | 745 | hba->max_sg_descriptors = le32_to_cpu(iop_config.max_sg_count); |
724 | hba->firmware_version = le32_to_cpu(iop_config.firmware_version); | 746 | hba->firmware_version = le32_to_cpu(iop_config.firmware_version); |
747 | hba->interface_version = le32_to_cpu(iop_config.interface_version); | ||
725 | hba->sdram_size = le32_to_cpu(iop_config.sdram_size); | 748 | hba->sdram_size = le32_to_cpu(iop_config.sdram_size); |
726 | 749 | ||
750 | if (hba->firmware_version > 0x01020000 || | ||
751 | hba->interface_version > 0x01020000) | ||
752 | hba->iopintf_v2 = 1; | ||
753 | |||
727 | host->max_sectors = le32_to_cpu(iop_config.data_transfer_length) >> 9; | 754 | host->max_sectors = le32_to_cpu(iop_config.data_transfer_length) >> 9; |
728 | host->max_id = le32_to_cpu(iop_config.max_devices); | 755 | host->max_id = le32_to_cpu(iop_config.max_devices); |
729 | host->sg_tablesize = le32_to_cpu(iop_config.max_sg_count); | 756 | host->sg_tablesize = le32_to_cpu(iop_config.max_sg_count); |
@@ -731,8 +758,15 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev, | |||
731 | host->cmd_per_lun = le32_to_cpu(iop_config.max_requests); | 758 | host->cmd_per_lun = le32_to_cpu(iop_config.max_requests); |
732 | host->max_cmd_len = 16; | 759 | host->max_cmd_len = 16; |
733 | 760 | ||
734 | set_config.vbus_id = cpu_to_le32(host->host_no); | 761 | req_size = sizeof(struct hpt_iop_request_scsi_command) |
762 | + sizeof(struct hpt_iopsg) * (hba->max_sg_descriptors - 1); | ||
763 | if ((req_size & 0x1f) != 0) | ||
764 | req_size = (req_size + 0x1f) & ~0x1f; | ||
765 | |||
766 | memset(&set_config, 0, sizeof(struct hpt_iop_request_set_config)); | ||
735 | set_config.iop_id = cpu_to_le32(host->host_no); | 767 | set_config.iop_id = cpu_to_le32(host->host_no); |
768 | set_config.vbus_id = cpu_to_le16(host->host_no); | ||
769 | set_config.max_host_request_size = cpu_to_le16(req_size); | ||
736 | 770 | ||
737 | if (iop_set_config(hba, &set_config)) { | 771 | if (iop_set_config(hba, &set_config)) { |
738 | printk(KERN_ERR "scsi%d: set config failed\n", | 772 | printk(KERN_ERR "scsi%d: set config failed\n", |
@@ -750,10 +784,6 @@ static int __devinit hptiop_probe(struct pci_dev *pcidev, | |||
750 | } | 784 | } |
751 | 785 | ||
752 | /* Allocate request mem */ | 786 | /* Allocate request mem */ |
753 | req_size = sizeof(struct hpt_iop_request_scsi_command) | ||
754 | + sizeof(struct hpt_iopsg) * (hba->max_sg_descriptors - 1); | ||
755 | if ((req_size& 0x1f) != 0) | ||
756 | req_size = (req_size + 0x1f) & ~0x1f; | ||
757 | 787 | ||
758 | dprintk("req_size=%d, max_requests=%d\n", req_size, hba->max_requests); | 788 | dprintk("req_size=%d, max_requests=%d\n", req_size, hba->max_requests); |
759 | 789 | ||
@@ -879,8 +909,10 @@ static void hptiop_remove(struct pci_dev *pcidev) | |||
879 | } | 909 | } |
880 | 910 | ||
881 | static struct pci_device_id hptiop_id_table[] = { | 911 | static struct pci_device_id hptiop_id_table[] = { |
882 | { PCI_DEVICE(0x1103, 0x3220) }, | 912 | { PCI_VDEVICE(TTI, 0x3220) }, |
883 | { PCI_DEVICE(0x1103, 0x3320) }, | 913 | { PCI_VDEVICE(TTI, 0x3320) }, |
914 | { PCI_VDEVICE(TTI, 0x3520) }, | ||
915 | { PCI_VDEVICE(TTI, 0x4320) }, | ||
884 | {}, | 916 | {}, |
885 | }; | 917 | }; |
886 | 918 | ||
@@ -910,3 +942,4 @@ module_init(hptiop_module_init); | |||
910 | module_exit(hptiop_module_exit); | 942 | module_exit(hptiop_module_exit); |
911 | 943 | ||
912 | MODULE_LICENSE("GPL"); | 944 | MODULE_LICENSE("GPL"); |
945 | |||
diff --git a/drivers/scsi/hptiop.h b/drivers/scsi/hptiop.h index f04f7e81d1ae..2a5e46e001cb 100644 --- a/drivers/scsi/hptiop.h +++ b/drivers/scsi/hptiop.h | |||
@@ -1,6 +1,6 @@ | |||
1 | /* | 1 | /* |
2 | * HighPoint RR3xxx controller driver for Linux | 2 | * HighPoint RR3xxx controller driver for Linux |
3 | * Copyright (C) 2006 HighPoint Technologies, Inc. All Rights Reserved. | 3 | * Copyright (C) 2006-2007 HighPoint Technologies, Inc. All Rights Reserved. |
4 | * | 4 | * |
5 | * This program is free software; you can redistribute it and/or modify | 5 | * This program is free software; you can redistribute it and/or modify |
6 | * it under the terms of the GNU General Public License as published by | 6 | * it under the terms of the GNU General Public License as published by |
@@ -18,219 +18,6 @@ | |||
18 | #ifndef _HPTIOP_H_ | 18 | #ifndef _HPTIOP_H_ |
19 | #define _HPTIOP_H_ | 19 | #define _HPTIOP_H_ |
20 | 20 | ||
21 | /* | ||
22 | * logical device type. | ||
23 | * Identify array (logical device) and physical device. | ||
24 | */ | ||
25 | #define LDT_ARRAY 1 | ||
26 | #define LDT_DEVICE 2 | ||
27 | |||
28 | /* | ||
29 | * Array types | ||
30 | */ | ||
31 | #define AT_UNKNOWN 0 | ||
32 | #define AT_RAID0 1 | ||
33 | #define AT_RAID1 2 | ||
34 | #define AT_RAID5 3 | ||
35 | #define AT_RAID6 4 | ||
36 | #define AT_JBOD 7 | ||
37 | |||
38 | #define MAX_NAME_LENGTH 36 | ||
39 | #define MAX_ARRAYNAME_LEN 16 | ||
40 | |||
41 | #define MAX_ARRAY_MEMBERS_V1 8 | ||
42 | #define MAX_ARRAY_MEMBERS_V2 16 | ||
43 | |||
44 | /* keep definition for source code compatiblity */ | ||
45 | #define MAX_ARRAY_MEMBERS MAX_ARRAY_MEMBERS_V1 | ||
46 | |||
47 | /* | ||
48 | * array flags | ||
49 | */ | ||
50 | #define ARRAY_FLAG_DISABLED 0x00000001 /* The array is disabled */ | ||
51 | #define ARRAY_FLAG_NEEDBUILDING 0x00000002 /* need to be rebuilt */ | ||
52 | #define ARRAY_FLAG_REBUILDING 0x00000004 /* in rebuilding process */ | ||
53 | #define ARRAY_FLAG_BROKEN 0x00000008 /* broken but still working */ | ||
54 | #define ARRAY_FLAG_BOOTDISK 0x00000010 /* has a active partition */ | ||
55 | #define ARRAY_FLAG_BOOTMARK 0x00000040 /* array has boot mark set */ | ||
56 | #define ARRAY_FLAG_NEED_AUTOREBUILD 0x00000080 /* auto-rebuild should start */ | ||
57 | #define ARRAY_FLAG_VERIFYING 0x00000100 /* is being verified */ | ||
58 | #define ARRAY_FLAG_INITIALIZING 0x00000200 /* is being initialized */ | ||
59 | #define ARRAY_FLAG_TRANSFORMING 0x00000400 /* tranform in progress */ | ||
60 | #define ARRAY_FLAG_NEEDTRANSFORM 0x00000800 /* array need tranform */ | ||
61 | #define ARRAY_FLAG_NEEDINITIALIZING 0x00001000 /* initialization not done */ | ||
62 | #define ARRAY_FLAG_BROKEN_REDUNDANT 0x00002000 /* broken but redundant */ | ||
63 | |||
64 | /* | ||
65 | * device flags | ||
66 | */ | ||
67 | #define DEVICE_FLAG_DISABLED 0x00000001 /* device is disabled */ | ||
68 | #define DEVICE_FLAG_UNINITIALIZED 0x00010000 /* device is not initialized */ | ||
69 | #define DEVICE_FLAG_LEGACY 0x00020000 /* lagacy drive */ | ||
70 | #define DEVICE_FLAG_IS_SPARE 0x80000000 /* is a spare disk */ | ||
71 | |||
72 | /* | ||
73 | * ioctl codes | ||
74 | */ | ||
75 | #define HPT_CTL_CODE(x) (x+0xFF00) | ||
76 | #define HPT_CTL_CODE_LINUX_TO_IOP(x) ((x)-0xff00) | ||
77 | |||
78 | #define HPT_IOCTL_GET_CONTROLLER_INFO HPT_CTL_CODE(2) | ||
79 | #define HPT_IOCTL_GET_CHANNEL_INFO HPT_CTL_CODE(3) | ||
80 | #define HPT_IOCTL_GET_LOGICAL_DEVICES HPT_CTL_CODE(4) | ||
81 | #define HPT_IOCTL_GET_DRIVER_CAPABILITIES HPT_CTL_CODE(19) | ||
82 | #define HPT_IOCTL_GET_DEVICE_INFO_V3 HPT_CTL_CODE(46) | ||
83 | #define HPT_IOCTL_GET_CONTROLLER_INFO_V2 HPT_CTL_CODE(47) | ||
84 | |||
85 | /* | ||
86 | * Controller information. | ||
87 | */ | ||
88 | struct hpt_controller_info { | ||
89 | u8 chip_type; /* chip type */ | ||
90 | u8 interrupt_level; /* IRQ level */ | ||
91 | u8 num_buses; /* bus count */ | ||
92 | u8 chip_flags; | ||
93 | |||
94 | u8 product_id[MAX_NAME_LENGTH];/* product name */ | ||
95 | u8 vendor_id[MAX_NAME_LENGTH]; /* vendor name */ | ||
96 | } | ||
97 | __attribute__((packed)); | ||
98 | |||
99 | /* | ||
100 | * Channel information. | ||
101 | */ | ||
102 | struct hpt_channel_info { | ||
103 | __le32 io_port; /* IDE Base Port Address */ | ||
104 | __le32 control_port; /* IDE Control Port Address */ | ||
105 | __le32 devices[2]; /* device connected to this channel */ | ||
106 | } | ||
107 | __attribute__((packed)); | ||
108 | |||
109 | /* | ||
110 | * Array information. | ||
111 | */ | ||
112 | struct hpt_array_info_v3 { | ||
113 | u8 name[MAX_ARRAYNAME_LEN]; /* array name */ | ||
114 | u8 description[64]; /* array description */ | ||
115 | u8 create_manager[16]; /* who created it */ | ||
116 | __le32 create_time; /* when created it */ | ||
117 | |||
118 | u8 array_type; /* array type */ | ||
119 | u8 block_size_shift; /* stripe size */ | ||
120 | u8 ndisk; /* Number of ID in Members[] */ | ||
121 | u8 reserved; | ||
122 | |||
123 | __le32 flags; /* working flags, see ARRAY_FLAG_XXX */ | ||
124 | __le32 members[MAX_ARRAY_MEMBERS_V2]; /* member array/disks */ | ||
125 | |||
126 | __le32 rebuilding_progress; | ||
127 | __le64 rebuilt_sectors; /* rebuilding point (LBA) for single member */ | ||
128 | |||
129 | __le32 transform_source; | ||
130 | __le32 transform_target; /* destination device ID */ | ||
131 | __le32 transforming_progress; | ||
132 | __le32 signature; /* persistent identification*/ | ||
133 | __le16 critical_members; /* bit mask of critical members */ | ||
134 | __le16 reserve2; | ||
135 | __le32 reserve; | ||
136 | } | ||
137 | __attribute__((packed)); | ||
138 | |||
139 | /* | ||
140 | * physical device information. | ||
141 | */ | ||
142 | #define MAX_PARENTS_PER_DISK 8 | ||
143 | |||
144 | struct hpt_device_info_v2 { | ||
145 | u8 ctlr_id; /* controller id */ | ||
146 | u8 path_id; /* bus */ | ||
147 | u8 target_id; /* id */ | ||
148 | u8 device_mode_setting; /* Current Data Transfer mode: 0-4 PIO0-4 */ | ||
149 | /* 5-7 MW DMA0-2, 8-13 UDMA0-5 */ | ||
150 | u8 device_type; /* device type */ | ||
151 | u8 usable_mode; /* highest usable mode */ | ||
152 | |||
153 | #ifdef __BIG_ENDIAN_BITFIELD | ||
154 | u8 NCQ_enabled: 1; | ||
155 | u8 NCQ_supported: 1; | ||
156 | u8 TCQ_enabled: 1; | ||
157 | u8 TCQ_supported: 1; | ||
158 | u8 write_cache_enabled: 1; | ||
159 | u8 write_cache_supported: 1; | ||
160 | u8 read_ahead_enabled: 1; | ||
161 | u8 read_ahead_supported: 1; | ||
162 | u8 reserved6: 6; | ||
163 | u8 spin_up_mode: 2; | ||
164 | #else | ||
165 | u8 read_ahead_supported: 1; | ||
166 | u8 read_ahead_enabled: 1; | ||
167 | u8 write_cache_supported: 1; | ||
168 | u8 write_cache_enabled: 1; | ||
169 | u8 TCQ_supported: 1; | ||
170 | u8 TCQ_enabled: 1; | ||
171 | u8 NCQ_supported: 1; | ||
172 | u8 NCQ_enabled: 1; | ||
173 | u8 spin_up_mode: 2; | ||
174 | u8 reserved6: 6; | ||
175 | #endif | ||
176 | |||
177 | __le32 flags; /* working flags, see DEVICE_FLAG_XXX */ | ||
178 | u8 ident[150]; /* (partitial) Identify Data of this device */ | ||
179 | |||
180 | __le64 total_free; | ||
181 | __le64 max_free; | ||
182 | __le64 bad_sectors; | ||
183 | __le32 parent_arrays[MAX_PARENTS_PER_DISK]; | ||
184 | } | ||
185 | __attribute__((packed)); | ||
186 | |||
187 | /* | ||
188 | * Logical device information. | ||
189 | */ | ||
190 | #define INVALID_TARGET_ID 0xFF | ||
191 | #define INVALID_BUS_ID 0xFF | ||
192 | |||
193 | struct hpt_logical_device_info_v3 { | ||
194 | u8 type; /* LDT_ARRAY or LDT_DEVICE */ | ||
195 | u8 cache_policy; /* refer to CACHE_POLICY_xxx */ | ||
196 | u8 vbus_id; /* vbus sequence in vbus_list */ | ||
197 | u8 target_id; /* OS target id. 0xFF is invalid */ | ||
198 | /* OS name: DISK $VBusId_$TargetId */ | ||
199 | __le64 capacity; /* array capacity */ | ||
200 | __le32 parent_array; /* don't use this field for physical | ||
201 | device. use ParentArrays field in | ||
202 | hpt_device_info_v2 */ | ||
203 | /* reserved statistic fields */ | ||
204 | __le32 stat1; | ||
205 | __le32 stat2; | ||
206 | __le32 stat3; | ||
207 | __le32 stat4; | ||
208 | |||
209 | union { | ||
210 | struct hpt_array_info_v3 array; | ||
211 | struct hpt_device_info_v2 device; | ||
212 | } __attribute__((packed)) u; | ||
213 | |||
214 | } | ||
215 | __attribute__((packed)); | ||
216 | |||
217 | /* | ||
218 | * ioctl structure | ||
219 | */ | ||
220 | #define HPT_IOCTL_MAGIC 0xA1B2C3D4 | ||
221 | |||
222 | struct hpt_ioctl_u { | ||
223 | u32 magic; /* used to check if it's a valid ioctl packet */ | ||
224 | u32 ioctl_code; /* operation control code */ | ||
225 | void __user *inbuf; /* input data buffer */ | ||
226 | u32 inbuf_size; /* size of input data buffer */ | ||
227 | void __user *outbuf; /* output data buffer */ | ||
228 | u32 outbuf_size; /* size of output data buffer */ | ||
229 | void __user *bytes_returned; /* count of bytes returned */ | ||
230 | } | ||
231 | __attribute__((packed)); | ||
232 | |||
233 | |||
234 | struct hpt_iopmu | 21 | struct hpt_iopmu |
235 | { | 22 | { |
236 | __le32 resrved0[4]; | 23 | __le32 resrved0[4]; |
@@ -252,6 +39,8 @@ struct hpt_iopmu | |||
252 | #define IOPMU_QUEUE_EMPTY 0xffffffff | 39 | #define IOPMU_QUEUE_EMPTY 0xffffffff |
253 | #define IOPMU_QUEUE_MASK_HOST_BITS 0xf0000000 | 40 | #define IOPMU_QUEUE_MASK_HOST_BITS 0xf0000000 |
254 | #define IOPMU_QUEUE_ADDR_HOST_BIT 0x80000000 | 41 | #define IOPMU_QUEUE_ADDR_HOST_BIT 0x80000000 |
42 | #define IOPMU_QUEUE_REQUEST_SIZE_BIT 0x40000000 | ||
43 | #define IOPMU_QUEUE_REQUEST_RESULT_BIT 0x40000000 | ||
255 | 44 | ||
256 | #define IOPMU_OUTBOUND_INT_MSG0 1 | 45 | #define IOPMU_OUTBOUND_INT_MSG0 1 |
257 | #define IOPMU_OUTBOUND_INT_MSG1 2 | 46 | #define IOPMU_OUTBOUND_INT_MSG1 2 |
@@ -336,7 +125,8 @@ struct hpt_iop_request_set_config | |||
336 | { | 125 | { |
337 | struct hpt_iop_request_header header; | 126 | struct hpt_iop_request_header header; |
338 | __le32 iop_id; | 127 | __le32 iop_id; |
339 | __le32 vbus_id; | 128 | __le16 vbus_id; |
129 | __le16 max_host_request_size; | ||
340 | __le32 reserve[6]; | 130 | __le32 reserve[6]; |
341 | }; | 131 | }; |
342 | 132 | ||
@@ -412,9 +202,8 @@ struct hptiop_hba { | |||
412 | struct Scsi_Host * host; | 202 | struct Scsi_Host * host; |
413 | struct pci_dev * pcidev; | 203 | struct pci_dev * pcidev; |
414 | 204 | ||
415 | struct list_head link; | ||
416 | |||
417 | /* IOP config info */ | 205 | /* IOP config info */ |
206 | u32 interface_version; | ||
418 | u32 firmware_version; | 207 | u32 firmware_version; |
419 | u32 sdram_size; | 208 | u32 sdram_size; |
420 | u32 max_devices; | 209 | u32 max_devices; |
@@ -423,8 +212,10 @@ struct hptiop_hba { | |||
423 | u32 max_sg_descriptors; | 212 | u32 max_sg_descriptors; |
424 | 213 | ||
425 | u32 req_size; /* host-allocated request buffer size */ | 214 | u32 req_size; /* host-allocated request buffer size */ |
426 | int initialized; | 215 | |
427 | int msg_done; | 216 | int iopintf_v2: 1; |
217 | int initialized: 1; | ||
218 | int msg_done: 1; | ||
428 | 219 | ||
429 | struct hptiop_request * req_list; | 220 | struct hptiop_request * req_list; |
430 | struct hptiop_request reqs[HPTIOP_MAX_REQUESTS]; | 221 | struct hptiop_request reqs[HPTIOP_MAX_REQUESTS]; |
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c index 4275d1b04ced..1a924e9b0271 100644 --- a/drivers/scsi/ibmmca.c +++ b/drivers/scsi/ibmmca.c | |||
@@ -460,13 +460,6 @@ module_param(boot_options, charp, 0); | |||
460 | module_param_array(io_port, int, NULL, 0); | 460 | module_param_array(io_port, int, NULL, 0); |
461 | module_param_array(scsi_id, int, NULL, 0); | 461 | module_param_array(scsi_id, int, NULL, 0); |
462 | 462 | ||
463 | #if 0 /* FIXME: No longer exist? --RR */ | ||
464 | MODULE_PARM(display, "1i"); | ||
465 | MODULE_PARM(adisplay, "1i"); | ||
466 | MODULE_PARM(normal, "1i"); | ||
467 | MODULE_PARM(ansi, "1i"); | ||
468 | #endif | ||
469 | |||
470 | MODULE_LICENSE("GPL"); | 463 | MODULE_LICENSE("GPL"); |
471 | #endif | 464 | #endif |
472 | /*counter of concurrent disk read/writes, to turn on/off disk led */ | 465 | /*counter of concurrent disk read/writes, to turn on/off disk led */ |
@@ -1693,6 +1686,7 @@ static int __devexit ibmmca_remove(struct device *dev) | |||
1693 | scsi_remove_host(shpnt); | 1686 | scsi_remove_host(shpnt); |
1694 | release_region(shpnt->io_port, shpnt->n_io_port); | 1687 | release_region(shpnt->io_port, shpnt->n_io_port); |
1695 | free_irq(shpnt->irq, dev); | 1688 | free_irq(shpnt->irq, dev); |
1689 | scsi_host_put(shpnt); | ||
1696 | return 0; | 1690 | return 0; |
1697 | } | 1691 | } |
1698 | 1692 | ||
diff --git a/drivers/scsi/ibmvscsi/Makefile b/drivers/scsi/ibmvscsi/Makefile index f67d9efc7a99..6ac0633d5452 100644 --- a/drivers/scsi/ibmvscsi/Makefile +++ b/drivers/scsi/ibmvscsi/Makefile | |||
@@ -1,9 +1,7 @@ | |||
1 | obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o | 1 | obj-$(CONFIG_SCSI_IBMVSCSI) += ibmvscsic.o |
2 | 2 | ||
3 | ibmvscsic-y += ibmvscsi.o | 3 | ibmvscsic-y += ibmvscsi.o |
4 | ifndef CONFIG_PPC_PSERIES | ||
5 | ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o | 4 | ibmvscsic-$(CONFIG_PPC_ISERIES) += iseries_vscsi.o |
6 | endif | ||
7 | ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o | 5 | ibmvscsic-$(CONFIG_PPC_PSERIES) += rpa_vscsi.o |
8 | 6 | ||
9 | obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o | 7 | obj-$(CONFIG_SCSI_IBMVSCSIS) += ibmvstgt.o |
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c index 5ecc63d1b436..cda0cc3d182f 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.c +++ b/drivers/scsi/ibmvscsi/ibmvscsi.c | |||
@@ -70,11 +70,13 @@ | |||
70 | #include <linux/moduleparam.h> | 70 | #include <linux/moduleparam.h> |
71 | #include <linux/dma-mapping.h> | 71 | #include <linux/dma-mapping.h> |
72 | #include <linux/delay.h> | 72 | #include <linux/delay.h> |
73 | #include <asm/firmware.h> | ||
73 | #include <asm/vio.h> | 74 | #include <asm/vio.h> |
74 | #include <scsi/scsi.h> | 75 | #include <scsi/scsi.h> |
75 | #include <scsi/scsi_cmnd.h> | 76 | #include <scsi/scsi_cmnd.h> |
76 | #include <scsi/scsi_host.h> | 77 | #include <scsi/scsi_host.h> |
77 | #include <scsi/scsi_device.h> | 78 | #include <scsi/scsi_device.h> |
79 | #include <scsi/scsi_transport_srp.h> | ||
78 | #include "ibmvscsi.h" | 80 | #include "ibmvscsi.h" |
79 | 81 | ||
80 | /* The values below are somewhat arbitrary default values, but | 82 | /* The values below are somewhat arbitrary default values, but |
@@ -87,8 +89,12 @@ static int max_channel = 3; | |||
87 | static int init_timeout = 5; | 89 | static int init_timeout = 5; |
88 | static int max_requests = IBMVSCSI_MAX_REQUESTS_DEFAULT; | 90 | static int max_requests = IBMVSCSI_MAX_REQUESTS_DEFAULT; |
89 | 91 | ||
92 | static struct scsi_transport_template *ibmvscsi_transport_template; | ||
93 | |||
90 | #define IBMVSCSI_VERSION "1.5.8" | 94 | #define IBMVSCSI_VERSION "1.5.8" |
91 | 95 | ||
96 | static struct ibmvscsi_ops *ibmvscsi_ops; | ||
97 | |||
92 | MODULE_DESCRIPTION("IBM Virtual SCSI"); | 98 | MODULE_DESCRIPTION("IBM Virtual SCSI"); |
93 | MODULE_AUTHOR("Dave Boutcher"); | 99 | MODULE_AUTHOR("Dave Boutcher"); |
94 | MODULE_LICENSE("GPL"); | 100 | MODULE_LICENSE("GPL"); |
@@ -506,8 +512,8 @@ static void ibmvscsi_reset_host(struct ibmvscsi_host_data *hostdata) | |||
506 | atomic_set(&hostdata->request_limit, 0); | 512 | atomic_set(&hostdata->request_limit, 0); |
507 | 513 | ||
508 | purge_requests(hostdata, DID_ERROR); | 514 | purge_requests(hostdata, DID_ERROR); |
509 | if ((ibmvscsi_reset_crq_queue(&hostdata->queue, hostdata)) || | 515 | if ((ibmvscsi_ops->reset_crq_queue(&hostdata->queue, hostdata)) || |
510 | (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0)) || | 516 | (ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0)) || |
511 | (vio_enable_interrupts(to_vio_dev(hostdata->dev)))) { | 517 | (vio_enable_interrupts(to_vio_dev(hostdata->dev)))) { |
512 | atomic_set(&hostdata->request_limit, -1); | 518 | atomic_set(&hostdata->request_limit, -1); |
513 | dev_err(hostdata->dev, "error after reset\n"); | 519 | dev_err(hostdata->dev, "error after reset\n"); |
@@ -612,7 +618,7 @@ static int ibmvscsi_send_srp_event(struct srp_event_struct *evt_struct, | |||
612 | } | 618 | } |
613 | 619 | ||
614 | if ((rc = | 620 | if ((rc = |
615 | ibmvscsi_send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) { | 621 | ibmvscsi_ops->send_crq(hostdata, crq_as_u64[0], crq_as_u64[1])) != 0) { |
616 | list_del(&evt_struct->list); | 622 | list_del(&evt_struct->list); |
617 | del_timer(&evt_struct->timer); | 623 | del_timer(&evt_struct->timer); |
618 | 624 | ||
@@ -1211,8 +1217,8 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, | |||
1211 | case 0x01: /* Initialization message */ | 1217 | case 0x01: /* Initialization message */ |
1212 | dev_info(hostdata->dev, "partner initialized\n"); | 1218 | dev_info(hostdata->dev, "partner initialized\n"); |
1213 | /* Send back a response */ | 1219 | /* Send back a response */ |
1214 | if ((rc = ibmvscsi_send_crq(hostdata, | 1220 | if ((rc = ibmvscsi_ops->send_crq(hostdata, |
1215 | 0xC002000000000000LL, 0)) == 0) { | 1221 | 0xC002000000000000LL, 0)) == 0) { |
1216 | /* Now login */ | 1222 | /* Now login */ |
1217 | send_srp_login(hostdata); | 1223 | send_srp_login(hostdata); |
1218 | } else { | 1224 | } else { |
@@ -1237,10 +1243,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, | |||
1237 | /* We need to re-setup the interpartition connection */ | 1243 | /* We need to re-setup the interpartition connection */ |
1238 | dev_info(hostdata->dev, "Re-enabling adapter!\n"); | 1244 | dev_info(hostdata->dev, "Re-enabling adapter!\n"); |
1239 | purge_requests(hostdata, DID_REQUEUE); | 1245 | purge_requests(hostdata, DID_REQUEUE); |
1240 | if ((ibmvscsi_reenable_crq_queue(&hostdata->queue, | 1246 | if ((ibmvscsi_ops->reenable_crq_queue(&hostdata->queue, |
1241 | hostdata)) || | 1247 | hostdata)) || |
1242 | (ibmvscsi_send_crq(hostdata, | 1248 | (ibmvscsi_ops->send_crq(hostdata, |
1243 | 0xC001000000000000LL, 0))) { | 1249 | 0xC001000000000000LL, 0))) { |
1244 | atomic_set(&hostdata->request_limit, | 1250 | atomic_set(&hostdata->request_limit, |
1245 | -1); | 1251 | -1); |
1246 | dev_err(hostdata->dev, "error after enable\n"); | 1252 | dev_err(hostdata->dev, "error after enable\n"); |
@@ -1250,10 +1256,10 @@ void ibmvscsi_handle_crq(struct viosrp_crq *crq, | |||
1250 | crq->format); | 1256 | crq->format); |
1251 | 1257 | ||
1252 | purge_requests(hostdata, DID_ERROR); | 1258 | purge_requests(hostdata, DID_ERROR); |
1253 | if ((ibmvscsi_reset_crq_queue(&hostdata->queue, | 1259 | if ((ibmvscsi_ops->reset_crq_queue(&hostdata->queue, |
1254 | hostdata)) || | 1260 | hostdata)) || |
1255 | (ibmvscsi_send_crq(hostdata, | 1261 | (ibmvscsi_ops->send_crq(hostdata, |
1256 | 0xC001000000000000LL, 0))) { | 1262 | 0xC001000000000000LL, 0))) { |
1257 | atomic_set(&hostdata->request_limit, | 1263 | atomic_set(&hostdata->request_limit, |
1258 | -1); | 1264 | -1); |
1259 | dev_err(hostdata->dev, "error after reset\n"); | 1265 | dev_err(hostdata->dev, "error after reset\n"); |
@@ -1553,6 +1559,8 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1553 | struct ibmvscsi_host_data *hostdata; | 1559 | struct ibmvscsi_host_data *hostdata; |
1554 | struct Scsi_Host *host; | 1560 | struct Scsi_Host *host; |
1555 | struct device *dev = &vdev->dev; | 1561 | struct device *dev = &vdev->dev; |
1562 | struct srp_rport_identifiers ids; | ||
1563 | struct srp_rport *rport; | ||
1556 | unsigned long wait_switch = 0; | 1564 | unsigned long wait_switch = 0; |
1557 | int rc; | 1565 | int rc; |
1558 | 1566 | ||
@@ -1565,6 +1573,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1565 | goto scsi_host_alloc_failed; | 1573 | goto scsi_host_alloc_failed; |
1566 | } | 1574 | } |
1567 | 1575 | ||
1576 | host->transportt = ibmvscsi_transport_template; | ||
1568 | hostdata = shost_priv(host); | 1577 | hostdata = shost_priv(host); |
1569 | memset(hostdata, 0x00, sizeof(*hostdata)); | 1578 | memset(hostdata, 0x00, sizeof(*hostdata)); |
1570 | INIT_LIST_HEAD(&hostdata->sent); | 1579 | INIT_LIST_HEAD(&hostdata->sent); |
@@ -1573,7 +1582,7 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1573 | atomic_set(&hostdata->request_limit, -1); | 1582 | atomic_set(&hostdata->request_limit, -1); |
1574 | hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */ | 1583 | hostdata->host->max_sectors = 32 * 8; /* default max I/O 32 pages */ |
1575 | 1584 | ||
1576 | rc = ibmvscsi_init_crq_queue(&hostdata->queue, hostdata, max_requests); | 1585 | rc = ibmvscsi_ops->init_crq_queue(&hostdata->queue, hostdata, max_requests); |
1577 | if (rc != 0 && rc != H_RESOURCE) { | 1586 | if (rc != 0 && rc != H_RESOURCE) { |
1578 | dev_err(&vdev->dev, "couldn't initialize crq. rc=%d\n", rc); | 1587 | dev_err(&vdev->dev, "couldn't initialize crq. rc=%d\n", rc); |
1579 | goto init_crq_failed; | 1588 | goto init_crq_failed; |
@@ -1590,11 +1599,19 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1590 | if (scsi_add_host(hostdata->host, hostdata->dev)) | 1599 | if (scsi_add_host(hostdata->host, hostdata->dev)) |
1591 | goto add_host_failed; | 1600 | goto add_host_failed; |
1592 | 1601 | ||
1602 | /* we don't have a proper target_port_id so let's use the fake one */ | ||
1603 | memcpy(ids.port_id, hostdata->madapter_info.partition_name, | ||
1604 | sizeof(ids.port_id)); | ||
1605 | ids.roles = SRP_RPORT_ROLE_TARGET; | ||
1606 | rport = srp_rport_add(host, &ids); | ||
1607 | if (IS_ERR(rport)) | ||
1608 | goto add_srp_port_failed; | ||
1609 | |||
1593 | /* Try to send an initialization message. Note that this is allowed | 1610 | /* Try to send an initialization message. Note that this is allowed |
1594 | * to fail if the other end is not acive. In that case we don't | 1611 | * to fail if the other end is not acive. In that case we don't |
1595 | * want to scan | 1612 | * want to scan |
1596 | */ | 1613 | */ |
1597 | if (ibmvscsi_send_crq(hostdata, 0xC001000000000000LL, 0) == 0 | 1614 | if (ibmvscsi_ops->send_crq(hostdata, 0xC001000000000000LL, 0) == 0 |
1598 | || rc == H_RESOURCE) { | 1615 | || rc == H_RESOURCE) { |
1599 | /* | 1616 | /* |
1600 | * Wait around max init_timeout secs for the adapter to finish | 1617 | * Wait around max init_timeout secs for the adapter to finish |
@@ -1617,10 +1634,12 @@ static int ibmvscsi_probe(struct vio_dev *vdev, const struct vio_device_id *id) | |||
1617 | vdev->dev.driver_data = hostdata; | 1634 | vdev->dev.driver_data = hostdata; |
1618 | return 0; | 1635 | return 0; |
1619 | 1636 | ||
1637 | add_srp_port_failed: | ||
1638 | scsi_remove_host(hostdata->host); | ||
1620 | add_host_failed: | 1639 | add_host_failed: |
1621 | release_event_pool(&hostdata->pool, hostdata); | 1640 | release_event_pool(&hostdata->pool, hostdata); |
1622 | init_pool_failed: | 1641 | init_pool_failed: |
1623 | ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, max_requests); | 1642 | ibmvscsi_ops->release_crq_queue(&hostdata->queue, hostdata, max_requests); |
1624 | init_crq_failed: | 1643 | init_crq_failed: |
1625 | scsi_host_put(host); | 1644 | scsi_host_put(host); |
1626 | scsi_host_alloc_failed: | 1645 | scsi_host_alloc_failed: |
@@ -1631,9 +1650,10 @@ static int ibmvscsi_remove(struct vio_dev *vdev) | |||
1631 | { | 1650 | { |
1632 | struct ibmvscsi_host_data *hostdata = vdev->dev.driver_data; | 1651 | struct ibmvscsi_host_data *hostdata = vdev->dev.driver_data; |
1633 | release_event_pool(&hostdata->pool, hostdata); | 1652 | release_event_pool(&hostdata->pool, hostdata); |
1634 | ibmvscsi_release_crq_queue(&hostdata->queue, hostdata, | 1653 | ibmvscsi_ops->release_crq_queue(&hostdata->queue, hostdata, |
1635 | max_requests); | 1654 | max_requests); |
1636 | 1655 | ||
1656 | srp_remove_host(hostdata->host); | ||
1637 | scsi_remove_host(hostdata->host); | 1657 | scsi_remove_host(hostdata->host); |
1638 | scsi_host_put(hostdata->host); | 1658 | scsi_host_put(hostdata->host); |
1639 | 1659 | ||
@@ -1660,14 +1680,35 @@ static struct vio_driver ibmvscsi_driver = { | |||
1660 | } | 1680 | } |
1661 | }; | 1681 | }; |
1662 | 1682 | ||
1683 | static struct srp_function_template ibmvscsi_transport_functions = { | ||
1684 | }; | ||
1685 | |||
1663 | int __init ibmvscsi_module_init(void) | 1686 | int __init ibmvscsi_module_init(void) |
1664 | { | 1687 | { |
1665 | return vio_register_driver(&ibmvscsi_driver); | 1688 | int ret; |
1689 | |||
1690 | if (firmware_has_feature(FW_FEATURE_ISERIES)) | ||
1691 | ibmvscsi_ops = &iseriesvscsi_ops; | ||
1692 | else if (firmware_has_feature(FW_FEATURE_VIO)) | ||
1693 | ibmvscsi_ops = &rpavscsi_ops; | ||
1694 | else | ||
1695 | return -ENODEV; | ||
1696 | |||
1697 | ibmvscsi_transport_template = | ||
1698 | srp_attach_transport(&ibmvscsi_transport_functions); | ||
1699 | if (!ibmvscsi_transport_template) | ||
1700 | return -ENOMEM; | ||
1701 | |||
1702 | ret = vio_register_driver(&ibmvscsi_driver); | ||
1703 | if (ret) | ||
1704 | srp_release_transport(ibmvscsi_transport_template); | ||
1705 | return ret; | ||
1666 | } | 1706 | } |
1667 | 1707 | ||
1668 | void __exit ibmvscsi_module_exit(void) | 1708 | void __exit ibmvscsi_module_exit(void) |
1669 | { | 1709 | { |
1670 | vio_unregister_driver(&ibmvscsi_driver); | 1710 | vio_unregister_driver(&ibmvscsi_driver); |
1711 | srp_release_transport(ibmvscsi_transport_template); | ||
1671 | } | 1712 | } |
1672 | 1713 | ||
1673 | module_init(ibmvscsi_module_init); | 1714 | module_init(ibmvscsi_module_init); |
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.h b/drivers/scsi/ibmvscsi/ibmvscsi.h index b19c2e26c2a5..46e850e302c7 100644 --- a/drivers/scsi/ibmvscsi/ibmvscsi.h +++ b/drivers/scsi/ibmvscsi/ibmvscsi.h | |||
@@ -98,21 +98,25 @@ struct ibmvscsi_host_data { | |||
98 | }; | 98 | }; |
99 | 99 | ||
100 | /* routines for managing a command/response queue */ | 100 | /* routines for managing a command/response queue */ |
101 | int ibmvscsi_init_crq_queue(struct crq_queue *queue, | ||
102 | struct ibmvscsi_host_data *hostdata, | ||
103 | int max_requests); | ||
104 | void ibmvscsi_release_crq_queue(struct crq_queue *queue, | ||
105 | struct ibmvscsi_host_data *hostdata, | ||
106 | int max_requests); | ||
107 | int ibmvscsi_reset_crq_queue(struct crq_queue *queue, | ||
108 | struct ibmvscsi_host_data *hostdata); | ||
109 | |||
110 | int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, | ||
111 | struct ibmvscsi_host_data *hostdata); | ||
112 | |||
113 | void ibmvscsi_handle_crq(struct viosrp_crq *crq, | 101 | void ibmvscsi_handle_crq(struct viosrp_crq *crq, |
114 | struct ibmvscsi_host_data *hostdata); | 102 | struct ibmvscsi_host_data *hostdata); |
115 | int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, | 103 | |
116 | u64 word1, u64 word2); | 104 | struct ibmvscsi_ops { |
105 | int (*init_crq_queue)(struct crq_queue *queue, | ||
106 | struct ibmvscsi_host_data *hostdata, | ||
107 | int max_requests); | ||
108 | void (*release_crq_queue)(struct crq_queue *queue, | ||
109 | struct ibmvscsi_host_data *hostdata, | ||
110 | int max_requests); | ||
111 | int (*reset_crq_queue)(struct crq_queue *queue, | ||
112 | struct ibmvscsi_host_data *hostdata); | ||
113 | int (*reenable_crq_queue)(struct crq_queue *queue, | ||
114 | struct ibmvscsi_host_data *hostdata); | ||
115 | int (*send_crq)(struct ibmvscsi_host_data *hostdata, | ||
116 | u64 word1, u64 word2); | ||
117 | }; | ||
118 | |||
119 | extern struct ibmvscsi_ops iseriesvscsi_ops; | ||
120 | extern struct ibmvscsi_ops rpavscsi_ops; | ||
117 | 121 | ||
118 | #endif /* IBMVSCSI_H */ | 122 | #endif /* IBMVSCSI_H */ |
diff --git a/drivers/scsi/ibmvscsi/ibmvstgt.c b/drivers/scsi/ibmvscsi/ibmvstgt.c index 8ba7dd09d01d..82bcab688b44 100644 --- a/drivers/scsi/ibmvscsi/ibmvstgt.c +++ b/drivers/scsi/ibmvscsi/ibmvstgt.c | |||
@@ -25,6 +25,7 @@ | |||
25 | #include <linux/module.h> | 25 | #include <linux/module.h> |
26 | #include <scsi/scsi.h> | 26 | #include <scsi/scsi.h> |
27 | #include <scsi/scsi_host.h> | 27 | #include <scsi/scsi_host.h> |
28 | #include <scsi/scsi_transport_srp.h> | ||
28 | #include <scsi/scsi_tgt.h> | 29 | #include <scsi/scsi_tgt.h> |
29 | #include <scsi/libsrp.h> | 30 | #include <scsi/libsrp.h> |
30 | #include <asm/hvcall.h> | 31 | #include <asm/hvcall.h> |
@@ -68,9 +69,12 @@ struct vio_port { | |||
68 | unsigned long liobn; | 69 | unsigned long liobn; |
69 | unsigned long riobn; | 70 | unsigned long riobn; |
70 | struct srp_target *target; | 71 | struct srp_target *target; |
72 | |||
73 | struct srp_rport *rport; | ||
71 | }; | 74 | }; |
72 | 75 | ||
73 | static struct workqueue_struct *vtgtd; | 76 | static struct workqueue_struct *vtgtd; |
77 | static struct scsi_transport_template *ibmvstgt_transport_template; | ||
74 | 78 | ||
75 | /* | 79 | /* |
76 | * These are fixed for the system and come from the Open Firmware device tree. | 80 | * These are fixed for the system and come from the Open Firmware device tree. |
@@ -188,6 +192,7 @@ static int send_rsp(struct iu_entry *iue, struct scsi_cmnd *sc, | |||
188 | static void handle_cmd_queue(struct srp_target *target) | 192 | static void handle_cmd_queue(struct srp_target *target) |
189 | { | 193 | { |
190 | struct Scsi_Host *shost = target->shost; | 194 | struct Scsi_Host *shost = target->shost; |
195 | struct srp_rport *rport = target_to_port(target)->rport; | ||
191 | struct iu_entry *iue; | 196 | struct iu_entry *iue; |
192 | struct srp_cmd *cmd; | 197 | struct srp_cmd *cmd; |
193 | unsigned long flags; | 198 | unsigned long flags; |
@@ -200,7 +205,8 @@ retry: | |||
200 | if (!test_and_set_bit(V_FLYING, &iue->flags)) { | 205 | if (!test_and_set_bit(V_FLYING, &iue->flags)) { |
201 | spin_unlock_irqrestore(&target->lock, flags); | 206 | spin_unlock_irqrestore(&target->lock, flags); |
202 | cmd = iue->sbuf->buf; | 207 | cmd = iue->sbuf->buf; |
203 | err = srp_cmd_queue(shost, cmd, iue, 0); | 208 | err = srp_cmd_queue(shost, cmd, iue, |
209 | (unsigned long)rport, 0); | ||
204 | if (err) { | 210 | if (err) { |
205 | eprintk("cannot queue cmd %p %d\n", cmd, err); | 211 | eprintk("cannot queue cmd %p %d\n", cmd, err); |
206 | srp_iu_put(iue); | 212 | srp_iu_put(iue); |
@@ -359,6 +365,16 @@ static void process_login(struct iu_entry *iue) | |||
359 | union viosrp_iu *iu = vio_iu(iue); | 365 | union viosrp_iu *iu = vio_iu(iue); |
360 | struct srp_login_rsp *rsp = &iu->srp.login_rsp; | 366 | struct srp_login_rsp *rsp = &iu->srp.login_rsp; |
361 | uint64_t tag = iu->srp.rsp.tag; | 367 | uint64_t tag = iu->srp.rsp.tag; |
368 | struct Scsi_Host *shost = iue->target->shost; | ||
369 | struct srp_target *target = host_to_srp_target(shost); | ||
370 | struct vio_port *vport = target_to_port(target); | ||
371 | struct srp_rport_identifiers ids; | ||
372 | |||
373 | memset(&ids, 0, sizeof(ids)); | ||
374 | sprintf(ids.port_id, "%x", vport->dma_dev->unit_address); | ||
375 | ids.roles = SRP_RPORT_ROLE_INITIATOR; | ||
376 | if (!vport->rport) | ||
377 | vport->rport = srp_rport_add(shost, &ids); | ||
362 | 378 | ||
363 | /* TODO handle case that requested size is wrong and | 379 | /* TODO handle case that requested size is wrong and |
364 | * buffer format is wrong | 380 | * buffer format is wrong |
@@ -412,7 +428,9 @@ static int process_tsk_mgmt(struct iu_entry *iue) | |||
412 | fn = 0; | 428 | fn = 0; |
413 | } | 429 | } |
414 | if (fn) | 430 | if (fn) |
415 | scsi_tgt_tsk_mgmt_request(iue->target->shost, fn, | 431 | scsi_tgt_tsk_mgmt_request(iue->target->shost, |
432 | (unsigned long)iue->target->shost, | ||
433 | fn, | ||
416 | iu->srp.tsk_mgmt.task_tag, | 434 | iu->srp.tsk_mgmt.task_tag, |
417 | (struct scsi_lun *) &iu->srp.tsk_mgmt.lun, | 435 | (struct scsi_lun *) &iu->srp.tsk_mgmt.lun, |
418 | iue); | 436 | iue); |
@@ -721,7 +739,8 @@ static int ibmvstgt_eh_abort_handler(struct scsi_cmnd *sc) | |||
721 | return 0; | 739 | return 0; |
722 | } | 740 | } |
723 | 741 | ||
724 | static int ibmvstgt_tsk_mgmt_response(u64 mid, int result) | 742 | static int ibmvstgt_tsk_mgmt_response(struct Scsi_Host *shost, |
743 | u64 itn_id, u64 mid, int result) | ||
725 | { | 744 | { |
726 | struct iu_entry *iue = (struct iu_entry *) ((void *) mid); | 745 | struct iu_entry *iue = (struct iu_entry *) ((void *) mid); |
727 | union viosrp_iu *iu = vio_iu(iue); | 746 | union viosrp_iu *iu = vio_iu(iue); |
@@ -747,6 +766,20 @@ static int ibmvstgt_tsk_mgmt_response(u64 mid, int result) | |||
747 | return 0; | 766 | return 0; |
748 | } | 767 | } |
749 | 768 | ||
769 | static int ibmvstgt_it_nexus_response(struct Scsi_Host *shost, u64 itn_id, | ||
770 | int result) | ||
771 | { | ||
772 | struct srp_target *target = host_to_srp_target(shost); | ||
773 | struct vio_port *vport = target_to_port(target); | ||
774 | |||
775 | if (result) { | ||
776 | eprintk("%p %d\n", shost, result); | ||
777 | srp_rport_del(vport->rport); | ||
778 | vport->rport = NULL; | ||
779 | } | ||
780 | return 0; | ||
781 | } | ||
782 | |||
750 | static ssize_t system_id_show(struct class_device *cdev, char *buf) | 783 | static ssize_t system_id_show(struct class_device *cdev, char *buf) |
751 | { | 784 | { |
752 | return snprintf(buf, PAGE_SIZE, "%s\n", system_id); | 785 | return snprintf(buf, PAGE_SIZE, "%s\n", system_id); |
@@ -785,9 +818,9 @@ static struct scsi_host_template ibmvstgt_sht = { | |||
785 | .max_sectors = DEFAULT_MAX_SECTORS, | 818 | .max_sectors = DEFAULT_MAX_SECTORS, |
786 | .transfer_response = ibmvstgt_cmd_done, | 819 | .transfer_response = ibmvstgt_cmd_done, |
787 | .eh_abort_handler = ibmvstgt_eh_abort_handler, | 820 | .eh_abort_handler = ibmvstgt_eh_abort_handler, |
788 | .tsk_mgmt_response = ibmvstgt_tsk_mgmt_response, | ||
789 | .shost_attrs = ibmvstgt_attrs, | 821 | .shost_attrs = ibmvstgt_attrs, |
790 | .proc_name = TGT_NAME, | 822 | .proc_name = TGT_NAME, |
823 | .supported_mode = MODE_TARGET, | ||
791 | }; | 824 | }; |
792 | 825 | ||
793 | static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) | 826 | static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) |
@@ -804,6 +837,7 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) | |||
804 | shost = scsi_host_alloc(&ibmvstgt_sht, sizeof(struct srp_target)); | 837 | shost = scsi_host_alloc(&ibmvstgt_sht, sizeof(struct srp_target)); |
805 | if (!shost) | 838 | if (!shost) |
806 | goto free_vport; | 839 | goto free_vport; |
840 | shost->transportt = ibmvstgt_transport_template; | ||
807 | err = scsi_tgt_alloc_queue(shost); | 841 | err = scsi_tgt_alloc_queue(shost); |
808 | if (err) | 842 | if (err) |
809 | goto put_host; | 843 | goto put_host; |
@@ -837,8 +871,8 @@ static int ibmvstgt_probe(struct vio_dev *dev, const struct vio_device_id *id) | |||
837 | err = scsi_add_host(shost, target->dev); | 871 | err = scsi_add_host(shost, target->dev); |
838 | if (err) | 872 | if (err) |
839 | goto destroy_queue; | 873 | goto destroy_queue; |
840 | return 0; | ||
841 | 874 | ||
875 | return 0; | ||
842 | destroy_queue: | 876 | destroy_queue: |
843 | crq_queue_destroy(target); | 877 | crq_queue_destroy(target); |
844 | free_srp_target: | 878 | free_srp_target: |
@@ -857,6 +891,7 @@ static int ibmvstgt_remove(struct vio_dev *dev) | |||
857 | struct vio_port *vport = target->ldata; | 891 | struct vio_port *vport = target->ldata; |
858 | 892 | ||
859 | crq_queue_destroy(target); | 893 | crq_queue_destroy(target); |
894 | srp_remove_host(shost); | ||
860 | scsi_remove_host(shost); | 895 | scsi_remove_host(shost); |
861 | scsi_tgt_free_queue(shost); | 896 | scsi_tgt_free_queue(shost); |
862 | srp_target_free(target); | 897 | srp_target_free(target); |
@@ -909,15 +944,25 @@ static int get_system_info(void) | |||
909 | return 0; | 944 | return 0; |
910 | } | 945 | } |
911 | 946 | ||
947 | static struct srp_function_template ibmvstgt_transport_functions = { | ||
948 | .tsk_mgmt_response = ibmvstgt_tsk_mgmt_response, | ||
949 | .it_nexus_response = ibmvstgt_it_nexus_response, | ||
950 | }; | ||
951 | |||
912 | static int ibmvstgt_init(void) | 952 | static int ibmvstgt_init(void) |
913 | { | 953 | { |
914 | int err = -ENOMEM; | 954 | int err = -ENOMEM; |
915 | 955 | ||
916 | printk("IBM eServer i/pSeries Virtual SCSI Target Driver\n"); | 956 | printk("IBM eServer i/pSeries Virtual SCSI Target Driver\n"); |
917 | 957 | ||
958 | ibmvstgt_transport_template = | ||
959 | srp_attach_transport(&ibmvstgt_transport_functions); | ||
960 | if (!ibmvstgt_transport_template) | ||
961 | return err; | ||
962 | |||
918 | vtgtd = create_workqueue("ibmvtgtd"); | 963 | vtgtd = create_workqueue("ibmvtgtd"); |
919 | if (!vtgtd) | 964 | if (!vtgtd) |
920 | return err; | 965 | goto release_transport; |
921 | 966 | ||
922 | err = get_system_info(); | 967 | err = get_system_info(); |
923 | if (err) | 968 | if (err) |
@@ -928,9 +973,10 @@ static int ibmvstgt_init(void) | |||
928 | goto destroy_wq; | 973 | goto destroy_wq; |
929 | 974 | ||
930 | return 0; | 975 | return 0; |
931 | |||
932 | destroy_wq: | 976 | destroy_wq: |
933 | destroy_workqueue(vtgtd); | 977 | destroy_workqueue(vtgtd); |
978 | release_transport: | ||
979 | srp_release_transport(ibmvstgt_transport_template); | ||
934 | return err; | 980 | return err; |
935 | } | 981 | } |
936 | 982 | ||
@@ -940,6 +986,7 @@ static void ibmvstgt_exit(void) | |||
940 | 986 | ||
941 | destroy_workqueue(vtgtd); | 987 | destroy_workqueue(vtgtd); |
942 | vio_unregister_driver(&ibmvstgt_driver); | 988 | vio_unregister_driver(&ibmvstgt_driver); |
989 | srp_release_transport(ibmvstgt_transport_template); | ||
943 | } | 990 | } |
944 | 991 | ||
945 | MODULE_DESCRIPTION("IBM Virtual SCSI Target"); | 992 | MODULE_DESCRIPTION("IBM Virtual SCSI Target"); |
diff --git a/drivers/scsi/ibmvscsi/iseries_vscsi.c b/drivers/scsi/ibmvscsi/iseries_vscsi.c index 6aeb5f003c3c..0775fdee5fa8 100644 --- a/drivers/scsi/ibmvscsi/iseries_vscsi.c +++ b/drivers/scsi/ibmvscsi/iseries_vscsi.c | |||
@@ -53,7 +53,7 @@ struct srp_lp_event { | |||
53 | /** | 53 | /** |
54 | * standard interface for handling logical partition events. | 54 | * standard interface for handling logical partition events. |
55 | */ | 55 | */ |
56 | static void ibmvscsi_handle_event(struct HvLpEvent *lpevt) | 56 | static void iseriesvscsi_handle_event(struct HvLpEvent *lpevt) |
57 | { | 57 | { |
58 | struct srp_lp_event *evt = (struct srp_lp_event *)lpevt; | 58 | struct srp_lp_event *evt = (struct srp_lp_event *)lpevt; |
59 | 59 | ||
@@ -74,9 +74,9 @@ static void ibmvscsi_handle_event(struct HvLpEvent *lpevt) | |||
74 | /* ------------------------------------------------------------ | 74 | /* ------------------------------------------------------------ |
75 | * Routines for driver initialization | 75 | * Routines for driver initialization |
76 | */ | 76 | */ |
77 | int ibmvscsi_init_crq_queue(struct crq_queue *queue, | 77 | static int iseriesvscsi_init_crq_queue(struct crq_queue *queue, |
78 | struct ibmvscsi_host_data *hostdata, | 78 | struct ibmvscsi_host_data *hostdata, |
79 | int max_requests) | 79 | int max_requests) |
80 | { | 80 | { |
81 | int rc; | 81 | int rc; |
82 | 82 | ||
@@ -88,7 +88,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
88 | goto viopath_open_failed; | 88 | goto viopath_open_failed; |
89 | } | 89 | } |
90 | 90 | ||
91 | rc = vio_setHandler(viomajorsubtype_scsi, ibmvscsi_handle_event); | 91 | rc = vio_setHandler(viomajorsubtype_scsi, iseriesvscsi_handle_event); |
92 | if (rc < 0) { | 92 | if (rc < 0) { |
93 | printk("vio_setHandler failed with rc %d in open_event_path\n", | 93 | printk("vio_setHandler failed with rc %d in open_event_path\n", |
94 | rc); | 94 | rc); |
@@ -102,9 +102,9 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
102 | return -1; | 102 | return -1; |
103 | } | 103 | } |
104 | 104 | ||
105 | void ibmvscsi_release_crq_queue(struct crq_queue *queue, | 105 | static void iseriesvscsi_release_crq_queue(struct crq_queue *queue, |
106 | struct ibmvscsi_host_data *hostdata, | 106 | struct ibmvscsi_host_data *hostdata, |
107 | int max_requests) | 107 | int max_requests) |
108 | { | 108 | { |
109 | vio_clearHandler(viomajorsubtype_scsi); | 109 | vio_clearHandler(viomajorsubtype_scsi); |
110 | viopath_close(viopath_hostLp, viomajorsubtype_scsi, max_requests); | 110 | viopath_close(viopath_hostLp, viomajorsubtype_scsi, max_requests); |
@@ -117,8 +117,8 @@ void ibmvscsi_release_crq_queue(struct crq_queue *queue, | |||
117 | * | 117 | * |
118 | * no-op for iSeries | 118 | * no-op for iSeries |
119 | */ | 119 | */ |
120 | int ibmvscsi_reset_crq_queue(struct crq_queue *queue, | 120 | static int iseriesvscsi_reset_crq_queue(struct crq_queue *queue, |
121 | struct ibmvscsi_host_data *hostdata) | 121 | struct ibmvscsi_host_data *hostdata) |
122 | { | 122 | { |
123 | return 0; | 123 | return 0; |
124 | } | 124 | } |
@@ -130,19 +130,20 @@ int ibmvscsi_reset_crq_queue(struct crq_queue *queue, | |||
130 | * | 130 | * |
131 | * no-op for iSeries | 131 | * no-op for iSeries |
132 | */ | 132 | */ |
133 | int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, | 133 | static int iseriesvscsi_reenable_crq_queue(struct crq_queue *queue, |
134 | struct ibmvscsi_host_data *hostdata) | 134 | struct ibmvscsi_host_data *hostdata) |
135 | { | 135 | { |
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
138 | 138 | ||
139 | /** | 139 | /** |
140 | * ibmvscsi_send_crq: - Send a CRQ | 140 | * iseriesvscsi_send_crq: - Send a CRQ |
141 | * @hostdata: the adapter | 141 | * @hostdata: the adapter |
142 | * @word1: the first 64 bits of the data | 142 | * @word1: the first 64 bits of the data |
143 | * @word2: the second 64 bits of the data | 143 | * @word2: the second 64 bits of the data |
144 | */ | 144 | */ |
145 | int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) | 145 | static int iseriesvscsi_send_crq(struct ibmvscsi_host_data *hostdata, |
146 | u64 word1, u64 word2) | ||
146 | { | 147 | { |
147 | single_host_data = hostdata; | 148 | single_host_data = hostdata; |
148 | return HvCallEvent_signalLpEventFast(viopath_hostLp, | 149 | return HvCallEvent_signalLpEventFast(viopath_hostLp, |
@@ -156,3 +157,11 @@ int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) | |||
156 | VIOVERSION << 16, word1, word2, 0, | 157 | VIOVERSION << 16, word1, word2, 0, |
157 | 0); | 158 | 0); |
158 | } | 159 | } |
160 | |||
161 | struct ibmvscsi_ops iseriesvscsi_ops = { | ||
162 | .init_crq_queue = iseriesvscsi_init_crq_queue, | ||
163 | .release_crq_queue = iseriesvscsi_release_crq_queue, | ||
164 | .reset_crq_queue = iseriesvscsi_reset_crq_queue, | ||
165 | .reenable_crq_queue = iseriesvscsi_reenable_crq_queue, | ||
166 | .send_crq = iseriesvscsi_send_crq, | ||
167 | }; | ||
diff --git a/drivers/scsi/ibmvscsi/rpa_vscsi.c b/drivers/scsi/ibmvscsi/rpa_vscsi.c index 9c14e789df5f..182146100dc1 100644 --- a/drivers/scsi/ibmvscsi/rpa_vscsi.c +++ b/drivers/scsi/ibmvscsi/rpa_vscsi.c | |||
@@ -42,14 +42,14 @@ static unsigned int partition_number = -1; | |||
42 | * Routines for managing the command/response queue | 42 | * Routines for managing the command/response queue |
43 | */ | 43 | */ |
44 | /** | 44 | /** |
45 | * ibmvscsi_handle_event: - Interrupt handler for crq events | 45 | * rpavscsi_handle_event: - Interrupt handler for crq events |
46 | * @irq: number of irq to handle, not used | 46 | * @irq: number of irq to handle, not used |
47 | * @dev_instance: ibmvscsi_host_data of host that received interrupt | 47 | * @dev_instance: ibmvscsi_host_data of host that received interrupt |
48 | * | 48 | * |
49 | * Disables interrupts and schedules srp_task | 49 | * Disables interrupts and schedules srp_task |
50 | * Always returns IRQ_HANDLED | 50 | * Always returns IRQ_HANDLED |
51 | */ | 51 | */ |
52 | static irqreturn_t ibmvscsi_handle_event(int irq, void *dev_instance) | 52 | static irqreturn_t rpavscsi_handle_event(int irq, void *dev_instance) |
53 | { | 53 | { |
54 | struct ibmvscsi_host_data *hostdata = | 54 | struct ibmvscsi_host_data *hostdata = |
55 | (struct ibmvscsi_host_data *)dev_instance; | 55 | (struct ibmvscsi_host_data *)dev_instance; |
@@ -66,9 +66,9 @@ static irqreturn_t ibmvscsi_handle_event(int irq, void *dev_instance) | |||
66 | * Frees irq, deallocates a page for messages, unmaps dma, and unregisters | 66 | * Frees irq, deallocates a page for messages, unmaps dma, and unregisters |
67 | * the crq with the hypervisor. | 67 | * the crq with the hypervisor. |
68 | */ | 68 | */ |
69 | void ibmvscsi_release_crq_queue(struct crq_queue *queue, | 69 | static void rpavscsi_release_crq_queue(struct crq_queue *queue, |
70 | struct ibmvscsi_host_data *hostdata, | 70 | struct ibmvscsi_host_data *hostdata, |
71 | int max_requests) | 71 | int max_requests) |
72 | { | 72 | { |
73 | long rc; | 73 | long rc; |
74 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); | 74 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); |
@@ -108,12 +108,13 @@ static struct viosrp_crq *crq_queue_next_crq(struct crq_queue *queue) | |||
108 | } | 108 | } |
109 | 109 | ||
110 | /** | 110 | /** |
111 | * ibmvscsi_send_crq: - Send a CRQ | 111 | * rpavscsi_send_crq: - Send a CRQ |
112 | * @hostdata: the adapter | 112 | * @hostdata: the adapter |
113 | * @word1: the first 64 bits of the data | 113 | * @word1: the first 64 bits of the data |
114 | * @word2: the second 64 bits of the data | 114 | * @word2: the second 64 bits of the data |
115 | */ | 115 | */ |
116 | int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) | 116 | static int rpavscsi_send_crq(struct ibmvscsi_host_data *hostdata, |
117 | u64 word1, u64 word2) | ||
117 | { | 118 | { |
118 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); | 119 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); |
119 | 120 | ||
@@ -121,10 +122,10 @@ int ibmvscsi_send_crq(struct ibmvscsi_host_data *hostdata, u64 word1, u64 word2) | |||
121 | } | 122 | } |
122 | 123 | ||
123 | /** | 124 | /** |
124 | * ibmvscsi_task: - Process srps asynchronously | 125 | * rpavscsi_task: - Process srps asynchronously |
125 | * @data: ibmvscsi_host_data of host | 126 | * @data: ibmvscsi_host_data of host |
126 | */ | 127 | */ |
127 | static void ibmvscsi_task(void *data) | 128 | static void rpavscsi_task(void *data) |
128 | { | 129 | { |
129 | struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)data; | 130 | struct ibmvscsi_host_data *hostdata = (struct ibmvscsi_host_data *)data; |
130 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); | 131 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); |
@@ -190,6 +191,42 @@ static void set_adapter_info(struct ibmvscsi_host_data *hostdata) | |||
190 | } | 191 | } |
191 | 192 | ||
192 | /** | 193 | /** |
194 | * reset_crq_queue: - resets a crq after a failure | ||
195 | * @queue: crq_queue to initialize and register | ||
196 | * @hostdata: ibmvscsi_host_data of host | ||
197 | * | ||
198 | */ | ||
199 | static int rpavscsi_reset_crq_queue(struct crq_queue *queue, | ||
200 | struct ibmvscsi_host_data *hostdata) | ||
201 | { | ||
202 | int rc; | ||
203 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); | ||
204 | |||
205 | /* Close the CRQ */ | ||
206 | do { | ||
207 | rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); | ||
208 | } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); | ||
209 | |||
210 | /* Clean out the queue */ | ||
211 | memset(queue->msgs, 0x00, PAGE_SIZE); | ||
212 | queue->cur = 0; | ||
213 | |||
214 | set_adapter_info(hostdata); | ||
215 | |||
216 | /* And re-open it again */ | ||
217 | rc = plpar_hcall_norets(H_REG_CRQ, | ||
218 | vdev->unit_address, | ||
219 | queue->msg_token, PAGE_SIZE); | ||
220 | if (rc == 2) { | ||
221 | /* Adapter is good, but other end is not ready */ | ||
222 | dev_warn(hostdata->dev, "Partner adapter not ready\n"); | ||
223 | } else if (rc != 0) { | ||
224 | dev_warn(hostdata->dev, "couldn't register crq--rc 0x%x\n", rc); | ||
225 | } | ||
226 | return rc; | ||
227 | } | ||
228 | |||
229 | /** | ||
193 | * initialize_crq_queue: - Initializes and registers CRQ with hypervisor | 230 | * initialize_crq_queue: - Initializes and registers CRQ with hypervisor |
194 | * @queue: crq_queue to initialize and register | 231 | * @queue: crq_queue to initialize and register |
195 | * @hostdata: ibmvscsi_host_data of host | 232 | * @hostdata: ibmvscsi_host_data of host |
@@ -198,9 +235,9 @@ static void set_adapter_info(struct ibmvscsi_host_data *hostdata) | |||
198 | * the crq with the hypervisor. | 235 | * the crq with the hypervisor. |
199 | * Returns zero on success. | 236 | * Returns zero on success. |
200 | */ | 237 | */ |
201 | int ibmvscsi_init_crq_queue(struct crq_queue *queue, | 238 | static int rpavscsi_init_crq_queue(struct crq_queue *queue, |
202 | struct ibmvscsi_host_data *hostdata, | 239 | struct ibmvscsi_host_data *hostdata, |
203 | int max_requests) | 240 | int max_requests) |
204 | { | 241 | { |
205 | int rc; | 242 | int rc; |
206 | int retrc; | 243 | int retrc; |
@@ -227,7 +264,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
227 | queue->msg_token, PAGE_SIZE); | 264 | queue->msg_token, PAGE_SIZE); |
228 | if (rc == H_RESOURCE) | 265 | if (rc == H_RESOURCE) |
229 | /* maybe kexecing and resource is busy. try a reset */ | 266 | /* maybe kexecing and resource is busy. try a reset */ |
230 | rc = ibmvscsi_reset_crq_queue(queue, | 267 | rc = rpavscsi_reset_crq_queue(queue, |
231 | hostdata); | 268 | hostdata); |
232 | 269 | ||
233 | if (rc == 2) { | 270 | if (rc == 2) { |
@@ -240,7 +277,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
240 | } | 277 | } |
241 | 278 | ||
242 | if (request_irq(vdev->irq, | 279 | if (request_irq(vdev->irq, |
243 | ibmvscsi_handle_event, | 280 | rpavscsi_handle_event, |
244 | 0, "ibmvscsi", (void *)hostdata) != 0) { | 281 | 0, "ibmvscsi", (void *)hostdata) != 0) { |
245 | dev_err(hostdata->dev, "couldn't register irq 0x%x\n", | 282 | dev_err(hostdata->dev, "couldn't register irq 0x%x\n", |
246 | vdev->irq); | 283 | vdev->irq); |
@@ -256,7 +293,7 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
256 | queue->cur = 0; | 293 | queue->cur = 0; |
257 | spin_lock_init(&queue->lock); | 294 | spin_lock_init(&queue->lock); |
258 | 295 | ||
259 | tasklet_init(&hostdata->srp_task, (void *)ibmvscsi_task, | 296 | tasklet_init(&hostdata->srp_task, (void *)rpavscsi_task, |
260 | (unsigned long)hostdata); | 297 | (unsigned long)hostdata); |
261 | 298 | ||
262 | return retrc; | 299 | return retrc; |
@@ -281,8 +318,8 @@ int ibmvscsi_init_crq_queue(struct crq_queue *queue, | |||
281 | * @hostdata: ibmvscsi_host_data of host | 318 | * @hostdata: ibmvscsi_host_data of host |
282 | * | 319 | * |
283 | */ | 320 | */ |
284 | int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, | 321 | static int rpavscsi_reenable_crq_queue(struct crq_queue *queue, |
285 | struct ibmvscsi_host_data *hostdata) | 322 | struct ibmvscsi_host_data *hostdata) |
286 | { | 323 | { |
287 | int rc; | 324 | int rc; |
288 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); | 325 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); |
@@ -297,38 +334,10 @@ int ibmvscsi_reenable_crq_queue(struct crq_queue *queue, | |||
297 | return rc; | 334 | return rc; |
298 | } | 335 | } |
299 | 336 | ||
300 | /** | 337 | struct ibmvscsi_ops rpavscsi_ops = { |
301 | * reset_crq_queue: - resets a crq after a failure | 338 | .init_crq_queue = rpavscsi_init_crq_queue, |
302 | * @queue: crq_queue to initialize and register | 339 | .release_crq_queue = rpavscsi_release_crq_queue, |
303 | * @hostdata: ibmvscsi_host_data of host | 340 | .reset_crq_queue = rpavscsi_reset_crq_queue, |
304 | * | 341 | .reenable_crq_queue = rpavscsi_reenable_crq_queue, |
305 | */ | 342 | .send_crq = rpavscsi_send_crq, |
306 | int ibmvscsi_reset_crq_queue(struct crq_queue *queue, | 343 | }; |
307 | struct ibmvscsi_host_data *hostdata) | ||
308 | { | ||
309 | int rc; | ||
310 | struct vio_dev *vdev = to_vio_dev(hostdata->dev); | ||
311 | |||
312 | /* Close the CRQ */ | ||
313 | do { | ||
314 | rc = plpar_hcall_norets(H_FREE_CRQ, vdev->unit_address); | ||
315 | } while ((rc == H_BUSY) || (H_IS_LONG_BUSY(rc))); | ||
316 | |||
317 | /* Clean out the queue */ | ||
318 | memset(queue->msgs, 0x00, PAGE_SIZE); | ||
319 | queue->cur = 0; | ||
320 | |||
321 | set_adapter_info(hostdata); | ||
322 | |||
323 | /* And re-open it again */ | ||
324 | rc = plpar_hcall_norets(H_REG_CRQ, | ||
325 | vdev->unit_address, | ||
326 | queue->msg_token, PAGE_SIZE); | ||
327 | if (rc == 2) { | ||
328 | /* Adapter is good, but other end is not ready */ | ||
329 | dev_warn(hostdata->dev, "Partner adapter not ready\n"); | ||
330 | } else if (rc != 0) { | ||
331 | dev_warn(hostdata->dev, "couldn't register crq--rc 0x%x\n", rc); | ||
332 | } | ||
333 | return rc; | ||
334 | } | ||
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c index 1cc01acc2808..d81bb076a15a 100644 --- a/drivers/scsi/ide-scsi.c +++ b/drivers/scsi/ide-scsi.c | |||
@@ -82,14 +82,12 @@ typedef struct idescsi_pc_s { | |||
82 | */ | 82 | */ |
83 | #define PC_DMA_IN_PROGRESS 0 /* 1 while DMA in progress */ | 83 | #define PC_DMA_IN_PROGRESS 0 /* 1 while DMA in progress */ |
84 | #define PC_WRITING 1 /* Data direction */ | 84 | #define PC_WRITING 1 /* Data direction */ |
85 | #define PC_TRANSFORM 2 /* transform SCSI commands */ | ||
86 | #define PC_TIMEDOUT 3 /* command timed out */ | 85 | #define PC_TIMEDOUT 3 /* command timed out */ |
87 | #define PC_DMA_OK 4 /* Use DMA */ | 86 | #define PC_DMA_OK 4 /* Use DMA */ |
88 | 87 | ||
89 | /* | 88 | /* |
90 | * SCSI command transformation layer | 89 | * SCSI command transformation layer |
91 | */ | 90 | */ |
92 | #define IDESCSI_TRANSFORM 0 /* Enable/Disable transformation */ | ||
93 | #define IDESCSI_SG_TRANSFORM 1 /* /dev/sg transformation */ | 91 | #define IDESCSI_SG_TRANSFORM 1 /* /dev/sg transformation */ |
94 | 92 | ||
95 | /* | 93 | /* |
@@ -175,7 +173,8 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne | |||
175 | char *buf; | 173 | char *buf; |
176 | 174 | ||
177 | while (bcount) { | 175 | while (bcount) { |
178 | if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) { | 176 | if (pc->sg - scsi_sglist(pc->scsi_cmd) > |
177 | scsi_sg_count(pc->scsi_cmd)) { | ||
179 | printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n"); | 178 | printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n"); |
180 | idescsi_discard_data (drive, bcount); | 179 | idescsi_discard_data (drive, bcount); |
181 | return; | 180 | return; |
@@ -210,7 +209,8 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign | |||
210 | char *buf; | 209 | char *buf; |
211 | 210 | ||
212 | while (bcount) { | 211 | while (bcount) { |
213 | if (pc->sg - (struct scatterlist *) pc->scsi_cmd->request_buffer > pc->scsi_cmd->use_sg) { | 212 | if (pc->sg - scsi_sglist(pc->scsi_cmd) > |
213 | scsi_sg_count(pc->scsi_cmd)) { | ||
214 | printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n"); | 214 | printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n"); |
215 | idescsi_output_zeros (drive, bcount); | 215 | idescsi_output_zeros (drive, bcount); |
216 | return; | 216 | return; |
@@ -239,77 +239,6 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign | |||
239 | } | 239 | } |
240 | } | 240 | } |
241 | 241 | ||
242 | /* | ||
243 | * Most of the SCSI commands are supported directly by ATAPI devices. | ||
244 | * idescsi_transform_pc handles the few exceptions. | ||
245 | */ | ||
246 | static inline void idescsi_transform_pc1 (ide_drive_t *drive, idescsi_pc_t *pc) | ||
247 | { | ||
248 | u8 *c = pc->c, *scsi_buf = pc->buffer, *sc = pc->scsi_cmd->cmnd; | ||
249 | char *atapi_buf; | ||
250 | |||
251 | if (!test_bit(PC_TRANSFORM, &pc->flags)) | ||
252 | return; | ||
253 | if (drive->media == ide_cdrom || drive->media == ide_optical) { | ||
254 | if (c[0] == READ_6 || c[0] == WRITE_6) { | ||
255 | c[8] = c[4]; c[5] = c[3]; c[4] = c[2]; | ||
256 | c[3] = c[1] & 0x1f; c[2] = 0; c[1] &= 0xe0; | ||
257 | c[0] += (READ_10 - READ_6); | ||
258 | } | ||
259 | if (c[0] == MODE_SENSE || c[0] == MODE_SELECT) { | ||
260 | unsigned short new_len; | ||
261 | if (!scsi_buf) | ||
262 | return; | ||
263 | if ((atapi_buf = kmalloc(pc->buffer_size + 4, GFP_ATOMIC)) == NULL) | ||
264 | return; | ||
265 | memset(atapi_buf, 0, pc->buffer_size + 4); | ||
266 | memset (c, 0, 12); | ||
267 | c[0] = sc[0] | 0x40; | ||
268 | c[1] = sc[1]; | ||
269 | c[2] = sc[2]; | ||
270 | new_len = sc[4] + 4; | ||
271 | c[8] = new_len; | ||
272 | c[7] = new_len >> 8; | ||
273 | c[9] = sc[5]; | ||
274 | if (c[0] == MODE_SELECT_10) { | ||
275 | atapi_buf[1] = scsi_buf[0]; /* Mode data length */ | ||
276 | atapi_buf[2] = scsi_buf[1]; /* Medium type */ | ||
277 | atapi_buf[3] = scsi_buf[2]; /* Device specific parameter */ | ||
278 | atapi_buf[7] = scsi_buf[3]; /* Block descriptor length */ | ||
279 | memcpy(atapi_buf + 8, scsi_buf + 4, pc->buffer_size - 4); | ||
280 | } | ||
281 | pc->buffer = atapi_buf; | ||
282 | pc->request_transfer += 4; | ||
283 | pc->buffer_size += 4; | ||
284 | } | ||
285 | } | ||
286 | } | ||
287 | |||
288 | static inline void idescsi_transform_pc2 (ide_drive_t *drive, idescsi_pc_t *pc) | ||
289 | { | ||
290 | u8 *atapi_buf = pc->buffer; | ||
291 | u8 *sc = pc->scsi_cmd->cmnd; | ||
292 | u8 *scsi_buf = pc->scsi_cmd->request_buffer; | ||
293 | |||
294 | if (!test_bit(PC_TRANSFORM, &pc->flags)) | ||
295 | return; | ||
296 | if (drive->media == ide_cdrom || drive->media == ide_optical) { | ||
297 | if (pc->c[0] == MODE_SENSE_10 && sc[0] == MODE_SENSE) { | ||
298 | scsi_buf[0] = atapi_buf[1]; /* Mode data length */ | ||
299 | scsi_buf[1] = atapi_buf[2]; /* Medium type */ | ||
300 | scsi_buf[2] = atapi_buf[3]; /* Device specific parameter */ | ||
301 | scsi_buf[3] = atapi_buf[7]; /* Block descriptor length */ | ||
302 | memcpy(scsi_buf + 4, atapi_buf + 8, pc->request_transfer - 8); | ||
303 | } | ||
304 | if (pc->c[0] == INQUIRY) { | ||
305 | scsi_buf[2] |= 2; /* ansi_revision */ | ||
306 | scsi_buf[3] = (scsi_buf[3] & 0xf0) | 2; /* response data format */ | ||
307 | } | ||
308 | } | ||
309 | if (atapi_buf && atapi_buf != scsi_buf) | ||
310 | kfree(atapi_buf); | ||
311 | } | ||
312 | |||
313 | static void hexdump(u8 *x, int len) | 242 | static void hexdump(u8 *x, int len) |
314 | { | 243 | { |
315 | int i; | 244 | int i; |
@@ -393,7 +322,6 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) | |||
393 | idescsi_pc_t *pc = (idescsi_pc_t *) rq->special; | 322 | idescsi_pc_t *pc = (idescsi_pc_t *) rq->special; |
394 | int log = test_bit(IDESCSI_LOG_CMD, &scsi->log); | 323 | int log = test_bit(IDESCSI_LOG_CMD, &scsi->log); |
395 | struct Scsi_Host *host; | 324 | struct Scsi_Host *host; |
396 | u8 *scsi_buf; | ||
397 | int errors = rq->errors; | 325 | int errors = rq->errors; |
398 | unsigned long flags; | 326 | unsigned long flags; |
399 | 327 | ||
@@ -434,15 +362,6 @@ static int idescsi_end_request (ide_drive_t *drive, int uptodate, int nrsecs) | |||
434 | pc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16); | 362 | pc->scsi_cmd->result = (CHECK_CONDITION << 1) | (DID_OK << 16); |
435 | } else { | 363 | } else { |
436 | pc->scsi_cmd->result = DID_OK << 16; | 364 | pc->scsi_cmd->result = DID_OK << 16; |
437 | idescsi_transform_pc2 (drive, pc); | ||
438 | if (log) { | ||
439 | printk ("ide-scsi: %s: suc %lu", drive->name, pc->scsi_cmd->serial_number); | ||
440 | if (!test_bit(PC_WRITING, &pc->flags) && pc->actually_transferred && pc->actually_transferred <= 1024 && pc->buffer) { | ||
441 | printk(", rst = "); | ||
442 | scsi_buf = pc->scsi_cmd->request_buffer; | ||
443 | hexdump(scsi_buf, min_t(unsigned, 16, pc->scsi_cmd->request_bufflen)); | ||
444 | } else printk("\n"); | ||
445 | } | ||
446 | } | 365 | } |
447 | host = pc->scsi_cmd->device->host; | 366 | host = pc->scsi_cmd->device->host; |
448 | spin_lock_irqsave(host->host_lock, flags); | 367 | spin_lock_irqsave(host->host_lock, flags); |
@@ -637,19 +556,14 @@ static int idescsi_map_sg(ide_drive_t *drive, idescsi_pc_t *pc) | |||
637 | return 1; | 556 | return 1; |
638 | 557 | ||
639 | sg = hwif->sg_table; | 558 | sg = hwif->sg_table; |
640 | scsi_sg = pc->scsi_cmd->request_buffer; | 559 | scsi_sg = scsi_sglist(pc->scsi_cmd); |
641 | segments = pc->scsi_cmd->use_sg; | 560 | segments = scsi_sg_count(pc->scsi_cmd); |
642 | 561 | ||
643 | if (segments > hwif->sg_max_nents) | 562 | if (segments > hwif->sg_max_nents) |
644 | return 1; | 563 | return 1; |
645 | 564 | ||
646 | if (!segments) { | 565 | hwif->sg_nents = segments; |
647 | hwif->sg_nents = 1; | 566 | memcpy(sg, scsi_sg, sizeof(*sg) * segments); |
648 | sg_init_one(sg, pc->scsi_cmd->request_buffer, pc->request_transfer); | ||
649 | } else { | ||
650 | hwif->sg_nents = segments; | ||
651 | memcpy(sg, scsi_sg, sizeof(*sg) * segments); | ||
652 | } | ||
653 | 567 | ||
654 | return 0; | 568 | return 0; |
655 | } | 569 | } |
@@ -744,7 +658,6 @@ static void idescsi_setup (ide_drive_t *drive, idescsi_scsi_t *scsi) | |||
744 | { | 658 | { |
745 | if (drive->id && (drive->id->config & 0x0060) == 0x20) | 659 | if (drive->id && (drive->id->config & 0x0060) == 0x20) |
746 | set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags); | 660 | set_bit (IDESCSI_DRQ_INTERRUPT, &scsi->flags); |
747 | set_bit(IDESCSI_TRANSFORM, &scsi->transform); | ||
748 | clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); | 661 | clear_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); |
749 | #if IDESCSI_DEBUG_LOG | 662 | #if IDESCSI_DEBUG_LOG |
750 | set_bit(IDESCSI_LOG_CMD, &scsi->log); | 663 | set_bit(IDESCSI_LOG_CMD, &scsi->log); |
@@ -758,6 +671,7 @@ static void ide_scsi_remove(ide_drive_t *drive) | |||
758 | struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost); | 671 | struct ide_scsi_obj *scsi = scsihost_to_idescsi(scsihost); |
759 | struct gendisk *g = scsi->disk; | 672 | struct gendisk *g = scsi->disk; |
760 | 673 | ||
674 | scsi_remove_host(scsihost); | ||
761 | ide_proc_unregister_driver(drive, scsi->driver); | 675 | ide_proc_unregister_driver(drive, scsi->driver); |
762 | 676 | ||
763 | ide_unregister_region(g); | 677 | ide_unregister_region(g); |
@@ -766,7 +680,6 @@ static void ide_scsi_remove(ide_drive_t *drive) | |||
766 | g->private_data = NULL; | 680 | g->private_data = NULL; |
767 | put_disk(g); | 681 | put_disk(g); |
768 | 682 | ||
769 | scsi_remove_host(scsihost); | ||
770 | ide_scsi_put(scsi); | 683 | ide_scsi_put(scsi); |
771 | } | 684 | } |
772 | 685 | ||
@@ -838,6 +751,8 @@ static struct block_device_operations idescsi_ops = { | |||
838 | static int idescsi_slave_configure(struct scsi_device * sdp) | 751 | static int idescsi_slave_configure(struct scsi_device * sdp) |
839 | { | 752 | { |
840 | /* Configure detected device */ | 753 | /* Configure detected device */ |
754 | sdp->use_10_for_rw = 1; | ||
755 | sdp->use_10_for_ms = 1; | ||
841 | scsi_adjust_queue_depth(sdp, MSG_SIMPLE_TAG, sdp->host->cmd_per_lun); | 756 | scsi_adjust_queue_depth(sdp, MSG_SIMPLE_TAG, sdp->host->cmd_per_lun); |
842 | return 0; | 757 | return 0; |
843 | } | 758 | } |
@@ -862,24 +777,6 @@ static int idescsi_ioctl (struct scsi_device *dev, int cmd, void __user *arg) | |||
862 | return -EINVAL; | 777 | return -EINVAL; |
863 | } | 778 | } |
864 | 779 | ||
865 | static inline int should_transform(ide_drive_t *drive, struct scsi_cmnd *cmd) | ||
866 | { | ||
867 | idescsi_scsi_t *scsi = drive_to_idescsi(drive); | ||
868 | |||
869 | /* this was a layering violation and we can't support it | ||
870 | anymore, sorry. */ | ||
871 | #if 0 | ||
872 | struct gendisk *disk = cmd->request->rq_disk; | ||
873 | |||
874 | if (disk) { | ||
875 | struct struct scsi_device_Template **p = disk->private_data; | ||
876 | if (strcmp((*p)->scsi_driverfs_driver.name, "sg") == 0) | ||
877 | return test_bit(IDESCSI_SG_TRANSFORM, &scsi->transform); | ||
878 | } | ||
879 | #endif | ||
880 | return test_bit(IDESCSI_TRANSFORM, &scsi->transform); | ||
881 | } | ||
882 | |||
883 | static int idescsi_queue (struct scsi_cmnd *cmd, | 780 | static int idescsi_queue (struct scsi_cmnd *cmd, |
884 | void (*done)(struct scsi_cmnd *)) | 781 | void (*done)(struct scsi_cmnd *)) |
885 | { | 782 | { |
@@ -905,23 +802,14 @@ static int idescsi_queue (struct scsi_cmnd *cmd, | |||
905 | pc->flags = 0; | 802 | pc->flags = 0; |
906 | pc->rq = rq; | 803 | pc->rq = rq; |
907 | memcpy (pc->c, cmd->cmnd, cmd->cmd_len); | 804 | memcpy (pc->c, cmd->cmnd, cmd->cmd_len); |
908 | if (cmd->use_sg) { | 805 | pc->buffer = NULL; |
909 | pc->buffer = NULL; | 806 | pc->sg = scsi_sglist(cmd); |
910 | pc->sg = cmd->request_buffer; | ||
911 | } else { | ||
912 | pc->buffer = cmd->request_buffer; | ||
913 | pc->sg = NULL; | ||
914 | } | ||
915 | pc->b_count = 0; | 807 | pc->b_count = 0; |
916 | pc->request_transfer = pc->buffer_size = cmd->request_bufflen; | 808 | pc->request_transfer = pc->buffer_size = scsi_bufflen(cmd); |
917 | pc->scsi_cmd = cmd; | 809 | pc->scsi_cmd = cmd; |
918 | pc->done = done; | 810 | pc->done = done; |
919 | pc->timeout = jiffies + cmd->timeout_per_command; | 811 | pc->timeout = jiffies + cmd->timeout_per_command; |
920 | 812 | ||
921 | if (should_transform(drive, cmd)) | ||
922 | set_bit(PC_TRANSFORM, &pc->flags); | ||
923 | idescsi_transform_pc1 (drive, pc); | ||
924 | |||
925 | if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) { | 813 | if (test_bit(IDESCSI_LOG_CMD, &scsi->log)) { |
926 | printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number); | 814 | printk ("ide-scsi: %s: que %lu, cmd = ", drive->name, cmd->serial_number); |
927 | hexdump(cmd->cmnd, cmd->cmd_len); | 815 | hexdump(cmd->cmnd, cmd->cmd_len); |
diff --git a/drivers/scsi/imm.c b/drivers/scsi/imm.c index 005d2b05f32d..74cdc1f0a78f 100644 --- a/drivers/scsi/imm.c +++ b/drivers/scsi/imm.c | |||
@@ -740,10 +740,6 @@ static void imm_interrupt(struct work_struct *work) | |||
740 | struct Scsi_Host *host = cmd->device->host; | 740 | struct Scsi_Host *host = cmd->device->host; |
741 | unsigned long flags; | 741 | unsigned long flags; |
742 | 742 | ||
743 | if (!cmd) { | ||
744 | printk("IMM: bug in imm_interrupt\n"); | ||
745 | return; | ||
746 | } | ||
747 | if (imm_engine(dev, cmd)) { | 743 | if (imm_engine(dev, cmd)) { |
748 | schedule_delayed_work(&dev->imm_tq, 1); | 744 | schedule_delayed_work(&dev->imm_tq, 1); |
749 | return; | 745 | return; |
diff --git a/drivers/scsi/in2000.c b/drivers/scsi/in2000.c index 312190a69389..ab7cbf3449ce 100644 --- a/drivers/scsi/in2000.c +++ b/drivers/scsi/in2000.c | |||
@@ -343,7 +343,7 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | |||
343 | instance = cmd->device->host; | 343 | instance = cmd->device->host; |
344 | hostdata = (struct IN2000_hostdata *) instance->hostdata; | 344 | hostdata = (struct IN2000_hostdata *) instance->hostdata; |
345 | 345 | ||
346 | DB(DB_QUEUE_COMMAND, scmd_printk(KERN_DEBUG, cmd, "Q-%02x-%ld(", cmd->cmnd[0], cmd->pid)) | 346 | DB(DB_QUEUE_COMMAND, scmd_printk(KERN_DEBUG, cmd, "Q-%02x-%ld(", cmd->cmnd[0], cmd->serial_number)) |
347 | 347 | ||
348 | /* Set up a few fields in the Scsi_Cmnd structure for our own use: | 348 | /* Set up a few fields in the Scsi_Cmnd structure for our own use: |
349 | * - host_scribble is the pointer to the next cmd in the input queue | 349 | * - host_scribble is the pointer to the next cmd in the input queue |
@@ -427,7 +427,7 @@ static int in2000_queuecommand(Scsi_Cmnd * cmd, void (*done) (Scsi_Cmnd *)) | |||
427 | 427 | ||
428 | in2000_execute(cmd->device->host); | 428 | in2000_execute(cmd->device->host); |
429 | 429 | ||
430 | DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->pid)) | 430 | DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->serial_number)) |
431 | return 0; | 431 | return 0; |
432 | } | 432 | } |
433 | 433 | ||
@@ -703,7 +703,7 @@ static void in2000_execute(struct Scsi_Host *instance) | |||
703 | * to search the input_Q again... | 703 | * to search the input_Q again... |
704 | */ | 704 | */ |
705 | 705 | ||
706 | DB(DB_EXECUTE, printk("%s%ld)EX-2 ", (cmd->SCp.phase) ? "d:" : "", cmd->pid)) | 706 | DB(DB_EXECUTE, printk("%s%ld)EX-2 ", (cmd->SCp.phase) ? "d:" : "", cmd->serial_number)) |
707 | 707 | ||
708 | } | 708 | } |
709 | 709 | ||
@@ -1147,7 +1147,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id) | |||
1147 | case CSR_XFER_DONE | PHS_COMMAND: | 1147 | case CSR_XFER_DONE | PHS_COMMAND: |
1148 | case CSR_UNEXP | PHS_COMMAND: | 1148 | case CSR_UNEXP | PHS_COMMAND: |
1149 | case CSR_SRV_REQ | PHS_COMMAND: | 1149 | case CSR_SRV_REQ | PHS_COMMAND: |
1150 | DB(DB_INTR, printk("CMND-%02x,%ld", cmd->cmnd[0], cmd->pid)) | 1150 | DB(DB_INTR, printk("CMND-%02x,%ld", cmd->cmnd[0], cmd->serial_number)) |
1151 | transfer_pio(cmd->cmnd, cmd->cmd_len, DATA_OUT_DIR, hostdata); | 1151 | transfer_pio(cmd->cmnd, cmd->cmd_len, DATA_OUT_DIR, hostdata); |
1152 | hostdata->state = S_CONNECTED; | 1152 | hostdata->state = S_CONNECTED; |
1153 | break; | 1153 | break; |
@@ -1189,7 +1189,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id) | |||
1189 | switch (msg) { | 1189 | switch (msg) { |
1190 | 1190 | ||
1191 | case COMMAND_COMPLETE: | 1191 | case COMMAND_COMPLETE: |
1192 | DB(DB_INTR, printk("CCMP-%ld", cmd->pid)) | 1192 | DB(DB_INTR, printk("CCMP-%ld", cmd->serial_number)) |
1193 | write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK); | 1193 | write_3393_cmd(hostdata, WD_CMD_NEGATE_ACK); |
1194 | hostdata->state = S_PRE_CMP_DISC; | 1194 | hostdata->state = S_PRE_CMP_DISC; |
1195 | break; | 1195 | break; |
@@ -1327,7 +1327,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id) | |||
1327 | 1327 | ||
1328 | write_3393(hostdata, WD_SOURCE_ID, SRCID_ER); | 1328 | write_3393(hostdata, WD_SOURCE_ID, SRCID_ER); |
1329 | if (phs == 0x60) { | 1329 | if (phs == 0x60) { |
1330 | DB(DB_INTR, printk("SX-DONE-%ld", cmd->pid)) | 1330 | DB(DB_INTR, printk("SX-DONE-%ld", cmd->serial_number)) |
1331 | cmd->SCp.Message = COMMAND_COMPLETE; | 1331 | cmd->SCp.Message = COMMAND_COMPLETE; |
1332 | lun = read_3393(hostdata, WD_TARGET_LUN); | 1332 | lun = read_3393(hostdata, WD_TARGET_LUN); |
1333 | DB(DB_INTR, printk(":%d.%d", cmd->SCp.Status, lun)) | 1333 | DB(DB_INTR, printk(":%d.%d", cmd->SCp.Status, lun)) |
@@ -1348,7 +1348,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id) | |||
1348 | 1348 | ||
1349 | in2000_execute(instance); | 1349 | in2000_execute(instance); |
1350 | } else { | 1350 | } else { |
1351 | printk("%02x:%02x:%02x-%ld: Unknown SEL_XFER_DONE phase!!---", asr, sr, phs, cmd->pid); | 1351 | printk("%02x:%02x:%02x-%ld: Unknown SEL_XFER_DONE phase!!---", asr, sr, phs, cmd->serial_number); |
1352 | } | 1352 | } |
1353 | break; | 1353 | break; |
1354 | 1354 | ||
@@ -1415,7 +1415,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id) | |||
1415 | spin_unlock_irqrestore(instance->host_lock, flags); | 1415 | spin_unlock_irqrestore(instance->host_lock, flags); |
1416 | return IRQ_HANDLED; | 1416 | return IRQ_HANDLED; |
1417 | } | 1417 | } |
1418 | DB(DB_INTR, printk("UNEXP_DISC-%ld", cmd->pid)) | 1418 | DB(DB_INTR, printk("UNEXP_DISC-%ld", cmd->serial_number)) |
1419 | hostdata->connected = NULL; | 1419 | hostdata->connected = NULL; |
1420 | hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); | 1420 | hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); |
1421 | hostdata->state = S_UNCONNECTED; | 1421 | hostdata->state = S_UNCONNECTED; |
@@ -1440,7 +1440,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id) | |||
1440 | */ | 1440 | */ |
1441 | 1441 | ||
1442 | write_3393(hostdata, WD_SOURCE_ID, SRCID_ER); | 1442 | write_3393(hostdata, WD_SOURCE_ID, SRCID_ER); |
1443 | DB(DB_INTR, printk("DISC-%ld", cmd->pid)) | 1443 | DB(DB_INTR, printk("DISC-%ld", cmd->serial_number)) |
1444 | if (cmd == NULL) { | 1444 | if (cmd == NULL) { |
1445 | printk(" - Already disconnected! "); | 1445 | printk(" - Already disconnected! "); |
1446 | hostdata->state = S_UNCONNECTED; | 1446 | hostdata->state = S_UNCONNECTED; |
@@ -1573,7 +1573,7 @@ static irqreturn_t in2000_intr(int irqnum, void *dev_id) | |||
1573 | } else | 1573 | } else |
1574 | hostdata->state = S_CONNECTED; | 1574 | hostdata->state = S_CONNECTED; |
1575 | 1575 | ||
1576 | DB(DB_INTR, printk("-%ld", cmd->pid)) | 1576 | DB(DB_INTR, printk("-%ld", cmd->serial_number)) |
1577 | break; | 1577 | break; |
1578 | 1578 | ||
1579 | default: | 1579 | default: |
@@ -1702,7 +1702,7 @@ static int __in2000_abort(Scsi_Cmnd * cmd) | |||
1702 | prev->host_scribble = cmd->host_scribble; | 1702 | prev->host_scribble = cmd->host_scribble; |
1703 | cmd->host_scribble = NULL; | 1703 | cmd->host_scribble = NULL; |
1704 | cmd->result = DID_ABORT << 16; | 1704 | cmd->result = DID_ABORT << 16; |
1705 | printk(KERN_WARNING "scsi%d: Abort - removing command %ld from input_Q. ", instance->host_no, cmd->pid); | 1705 | printk(KERN_WARNING "scsi%d: Abort - removing command %ld from input_Q. ", instance->host_no, cmd->serial_number); |
1706 | cmd->scsi_done(cmd); | 1706 | cmd->scsi_done(cmd); |
1707 | return SUCCESS; | 1707 | return SUCCESS; |
1708 | } | 1708 | } |
@@ -1723,7 +1723,7 @@ static int __in2000_abort(Scsi_Cmnd * cmd) | |||
1723 | 1723 | ||
1724 | if (hostdata->connected == cmd) { | 1724 | if (hostdata->connected == cmd) { |
1725 | 1725 | ||
1726 | printk(KERN_WARNING "scsi%d: Aborting connected command %ld - ", instance->host_no, cmd->pid); | 1726 | printk(KERN_WARNING "scsi%d: Aborting connected command %ld - ", instance->host_no, cmd->serial_number); |
1727 | 1727 | ||
1728 | printk("sending wd33c93 ABORT command - "); | 1728 | printk("sending wd33c93 ABORT command - "); |
1729 | write_3393(hostdata, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED); | 1729 | write_3393(hostdata, WD_CONTROL, CTRL_IDI | CTRL_EDI | CTRL_POLLED); |
@@ -2268,7 +2268,7 @@ static int in2000_proc_info(struct Scsi_Host *instance, char *buf, char **start, | |||
2268 | strcat(bp, "\nconnected: "); | 2268 | strcat(bp, "\nconnected: "); |
2269 | if (hd->connected) { | 2269 | if (hd->connected) { |
2270 | cmd = (Scsi_Cmnd *) hd->connected; | 2270 | cmd = (Scsi_Cmnd *) hd->connected; |
2271 | sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); | 2271 | sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); |
2272 | strcat(bp, tbuf); | 2272 | strcat(bp, tbuf); |
2273 | } | 2273 | } |
2274 | } | 2274 | } |
@@ -2276,7 +2276,7 @@ static int in2000_proc_info(struct Scsi_Host *instance, char *buf, char **start, | |||
2276 | strcat(bp, "\ninput_Q: "); | 2276 | strcat(bp, "\ninput_Q: "); |
2277 | cmd = (Scsi_Cmnd *) hd->input_Q; | 2277 | cmd = (Scsi_Cmnd *) hd->input_Q; |
2278 | while (cmd) { | 2278 | while (cmd) { |
2279 | sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); | 2279 | sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); |
2280 | strcat(bp, tbuf); | 2280 | strcat(bp, tbuf); |
2281 | cmd = (Scsi_Cmnd *) cmd->host_scribble; | 2281 | cmd = (Scsi_Cmnd *) cmd->host_scribble; |
2282 | } | 2282 | } |
@@ -2285,7 +2285,7 @@ static int in2000_proc_info(struct Scsi_Host *instance, char *buf, char **start, | |||
2285 | strcat(bp, "\ndisconnected_Q:"); | 2285 | strcat(bp, "\ndisconnected_Q:"); |
2286 | cmd = (Scsi_Cmnd *) hd->disconnected_Q; | 2286 | cmd = (Scsi_Cmnd *) hd->disconnected_Q; |
2287 | while (cmd) { | 2287 | while (cmd) { |
2288 | sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); | 2288 | sprintf(tbuf, " %ld-%d:%d(%02x)", cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); |
2289 | strcat(bp, tbuf); | 2289 | strcat(bp, tbuf); |
2290 | cmd = (Scsi_Cmnd *) cmd->host_scribble; | 2290 | cmd = (Scsi_Cmnd *) cmd->host_scribble; |
2291 | } | 2291 | } |
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c index 492a51bd6aa8..2ed099e2c20d 100644 --- a/drivers/scsi/ips.c +++ b/drivers/scsi/ips.c | |||
@@ -204,8 +204,8 @@ module_param(ips, charp, 0); | |||
204 | /* | 204 | /* |
205 | * DRIVER_VER | 205 | * DRIVER_VER |
206 | */ | 206 | */ |
207 | #define IPS_VERSION_HIGH "7.12" | 207 | #define IPS_VERSION_HIGH IPS_VER_MAJOR_STRING "." IPS_VER_MINOR_STRING |
208 | #define IPS_VERSION_LOW ".05 " | 208 | #define IPS_VERSION_LOW "." IPS_VER_BUILD_STRING " " |
209 | 209 | ||
210 | #if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__) | 210 | #if !defined(__i386__) && !defined(__ia64__) && !defined(__x86_64__) |
211 | #warning "This driver has only been tested on the x86/ia64/x86_64 platforms" | 211 | #warning "This driver has only been tested on the x86/ia64/x86_64 platforms" |
@@ -656,6 +656,8 @@ ips_release(struct Scsi_Host *sh) | |||
656 | 656 | ||
657 | METHOD_TRACE("ips_release", 1); | 657 | METHOD_TRACE("ips_release", 1); |
658 | 658 | ||
659 | scsi_remove_host(sh); | ||
660 | |||
659 | for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++) ; | 661 | for (i = 0; i < IPS_MAX_ADAPTERS && ips_sh[i] != sh; i++) ; |
660 | 662 | ||
661 | if (i == IPS_MAX_ADAPTERS) { | 663 | if (i == IPS_MAX_ADAPTERS) { |
@@ -707,7 +709,6 @@ ips_release(struct Scsi_Host *sh) | |||
707 | /* free IRQ */ | 709 | /* free IRQ */ |
708 | free_irq(ha->irq, ha); | 710 | free_irq(ha->irq, ha); |
709 | 711 | ||
710 | scsi_remove_host(sh); | ||
711 | scsi_host_put(sh); | 712 | scsi_host_put(sh); |
712 | 713 | ||
713 | ips_released_controllers++; | 714 | ips_released_controllers++; |
@@ -6946,7 +6947,7 @@ module_exit(ips_module_exit); | |||
6946 | static int __devinit | 6947 | static int __devinit |
6947 | ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent) | 6948 | ips_insert_device(struct pci_dev *pci_dev, const struct pci_device_id *ent) |
6948 | { | 6949 | { |
6949 | int index; | 6950 | int uninitialized_var(index); |
6950 | int rc; | 6951 | int rc; |
6951 | 6952 | ||
6952 | METHOD_TRACE("ips_insert_device", 1); | 6953 | METHOD_TRACE("ips_insert_device", 1); |
diff --git a/drivers/scsi/ips.h b/drivers/scsi/ips.h index 24123d537c58..3bcbd9ff056b 100644 --- a/drivers/scsi/ips.h +++ b/drivers/scsi/ips.h | |||
@@ -1172,12 +1172,13 @@ typedef struct { | |||
1172 | *************************************************************************/ | 1172 | *************************************************************************/ |
1173 | 1173 | ||
1174 | #define IPS_VER_MAJOR 7 | 1174 | #define IPS_VER_MAJOR 7 |
1175 | #define IPS_VER_MAJOR_STRING "7" | 1175 | #define IPS_VER_MAJOR_STRING __stringify(IPS_VER_MAJOR) |
1176 | #define IPS_VER_MINOR 12 | 1176 | #define IPS_VER_MINOR 12 |
1177 | #define IPS_VER_MINOR_STRING "12" | 1177 | #define IPS_VER_MINOR_STRING __stringify(IPS_VER_MINOR) |
1178 | #define IPS_VER_BUILD 02 | 1178 | #define IPS_VER_BUILD 05 |
1179 | #define IPS_VER_BUILD_STRING "02" | 1179 | #define IPS_VER_BUILD_STRING __stringify(IPS_VER_BUILD) |
1180 | #define IPS_VER_STRING "7.12.02" | 1180 | #define IPS_VER_STRING IPS_VER_MAJOR_STRING "." \ |
1181 | IPS_VER_MINOR_STRING "." IPS_VER_BUILD_STRING | ||
1181 | #define IPS_RELEASE_ID 0x00020000 | 1182 | #define IPS_RELEASE_ID 0x00020000 |
1182 | #define IPS_BUILD_IDENT 761 | 1183 | #define IPS_BUILD_IDENT 761 |
1183 | #define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002. All Rights Reserved." | 1184 | #define IPS_LEGALCOPYRIGHT_STRING "(C) Copyright IBM Corp. 1994, 2002. All Rights Reserved." |
diff --git a/drivers/scsi/libsrp.c b/drivers/scsi/libsrp.c index 732446e63963..2ad0a27dbaab 100644 --- a/drivers/scsi/libsrp.c +++ b/drivers/scsi/libsrp.c | |||
@@ -392,7 +392,7 @@ static int vscsis_data_length(struct srp_cmd *cmd, enum dma_data_direction dir) | |||
392 | } | 392 | } |
393 | 393 | ||
394 | int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info, | 394 | int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info, |
395 | u64 addr) | 395 | u64 itn_id, u64 addr) |
396 | { | 396 | { |
397 | enum dma_data_direction dir; | 397 | enum dma_data_direction dir; |
398 | struct scsi_cmnd *sc; | 398 | struct scsi_cmnd *sc; |
@@ -428,7 +428,8 @@ int srp_cmd_queue(struct Scsi_Host *shost, struct srp_cmd *cmd, void *info, | |||
428 | sc->request_bufflen = len; | 428 | sc->request_bufflen = len; |
429 | sc->request_buffer = (void *) (unsigned long) addr; | 429 | sc->request_buffer = (void *) (unsigned long) addr; |
430 | sc->tag = tag; | 430 | sc->tag = tag; |
431 | err = scsi_tgt_queue_command(sc, (struct scsi_lun *) &cmd->lun, cmd->tag); | 431 | err = scsi_tgt_queue_command(sc, itn_id, (struct scsi_lun *)&cmd->lun, |
432 | cmd->tag); | ||
432 | if (err) | 433 | if (err) |
433 | scsi_host_put_command(shost, sc); | 434 | scsi_host_put_command(shost, sc); |
434 | 435 | ||
diff --git a/drivers/scsi/lpfc/lpfc_debugfs.c b/drivers/scsi/lpfc/lpfc_debugfs.c index 2e3c01bebed6..149fdd25f8e8 100644 --- a/drivers/scsi/lpfc/lpfc_debugfs.c +++ b/drivers/scsi/lpfc/lpfc_debugfs.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include "lpfc_crtn.h" | 43 | #include "lpfc_crtn.h" |
44 | #include "lpfc_vport.h" | 44 | #include "lpfc_vport.h" |
45 | #include "lpfc_version.h" | 45 | #include "lpfc_version.h" |
46 | #include "lpfc_vport.h" | ||
47 | #include "lpfc_debugfs.h" | 46 | #include "lpfc_debugfs.h" |
48 | 47 | ||
49 | #ifdef CONFIG_LPFC_DEBUG_FS | 48 | #ifdef CONFIG_LPFC_DEBUG_FS |
@@ -902,7 +901,7 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) | |||
902 | } | 901 | } |
903 | } | 902 | } |
904 | 903 | ||
905 | vport->disc_trc = kmalloc( | 904 | vport->disc_trc = kmzlloc( |
906 | (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc), | 905 | (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc), |
907 | GFP_KERNEL); | 906 | GFP_KERNEL); |
908 | 907 | ||
@@ -913,8 +912,6 @@ lpfc_debugfs_initialize(struct lpfc_vport *vport) | |||
913 | goto debug_failed; | 912 | goto debug_failed; |
914 | } | 913 | } |
915 | atomic_set(&vport->disc_trc_cnt, 0); | 914 | atomic_set(&vport->disc_trc_cnt, 0); |
916 | memset(vport->disc_trc, 0, | ||
917 | (sizeof(struct lpfc_debugfs_trc) * lpfc_debugfs_max_disc_trc)); | ||
918 | 915 | ||
919 | snprintf(name, sizeof(name), "discovery_trace"); | 916 | snprintf(name, sizeof(name), "discovery_trace"); |
920 | vport->debug_disc_trc = | 917 | vport->debug_disc_trc = |
diff --git a/drivers/scsi/lpfc/lpfc_init.c b/drivers/scsi/lpfc/lpfc_init.c index 414350ab584e..ecebdfa00470 100644 --- a/drivers/scsi/lpfc/lpfc_init.c +++ b/drivers/scsi/lpfc/lpfc_init.c | |||
@@ -43,7 +43,6 @@ | |||
43 | #include "lpfc_crtn.h" | 43 | #include "lpfc_crtn.h" |
44 | #include "lpfc_vport.h" | 44 | #include "lpfc_vport.h" |
45 | #include "lpfc_version.h" | 45 | #include "lpfc_version.h" |
46 | #include "lpfc_vport.h" | ||
47 | 46 | ||
48 | static int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); | 47 | static int lpfc_parse_vpd(struct lpfc_hba *, uint8_t *, int); |
49 | static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *); | 48 | static void lpfc_get_hba_model_desc(struct lpfc_hba *, uint8_t *, uint8_t *); |
@@ -1266,11 +1265,10 @@ lpfc_hba_init(struct lpfc_hba *phba, uint32_t *hbainit) | |||
1266 | uint32_t *HashWorking; | 1265 | uint32_t *HashWorking; |
1267 | uint32_t *pwwnn = (uint32_t *) phba->wwnn; | 1266 | uint32_t *pwwnn = (uint32_t *) phba->wwnn; |
1268 | 1267 | ||
1269 | HashWorking = kmalloc(80 * sizeof(uint32_t), GFP_KERNEL); | 1268 | HashWorking = kcalloc(80, sizeof(uint32_t), GFP_KERNEL); |
1270 | if (!HashWorking) | 1269 | if (!HashWorking) |
1271 | return; | 1270 | return; |
1272 | 1271 | ||
1273 | memset(HashWorking, 0, (80 * sizeof(uint32_t))); | ||
1274 | HashWorking[0] = HashWorking[78] = *pwwnn++; | 1272 | HashWorking[0] = HashWorking[78] = *pwwnn++; |
1275 | HashWorking[1] = HashWorking[79] = *pwwnn; | 1273 | HashWorking[1] = HashWorking[79] = *pwwnn; |
1276 | 1274 | ||
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c index 17d7dc05149b..cd674938ccd5 100644 --- a/drivers/scsi/lpfc/lpfc_scsi.c +++ b/drivers/scsi/lpfc/lpfc_scsi.c | |||
@@ -202,10 +202,9 @@ lpfc_new_scsi_buf(struct lpfc_vport *vport) | |||
202 | dma_addr_t pdma_phys; | 202 | dma_addr_t pdma_phys; |
203 | uint16_t iotag; | 203 | uint16_t iotag; |
204 | 204 | ||
205 | psb = kmalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL); | 205 | psb = kzalloc(sizeof(struct lpfc_scsi_buf), GFP_KERNEL); |
206 | if (!psb) | 206 | if (!psb) |
207 | return NULL; | 207 | return NULL; |
208 | memset(psb, 0, sizeof (struct lpfc_scsi_buf)); | ||
209 | 208 | ||
210 | /* | 209 | /* |
211 | * Get memory from the pci pool to map the virt space to pci bus space | 210 | * Get memory from the pci pool to map the virt space to pci bus space |
diff --git a/drivers/scsi/lpfc/lpfc_sli.c b/drivers/scsi/lpfc/lpfc_sli.c index ce5ff2bccba6..e5337ad4121e 100644 --- a/drivers/scsi/lpfc/lpfc_sli.c +++ b/drivers/scsi/lpfc/lpfc_sli.c | |||
@@ -675,7 +675,7 @@ lpfc_sli_hbqbuf_find(struct lpfc_hba *phba, uint32_t tag) | |||
675 | uint32_t hbqno; | 675 | uint32_t hbqno; |
676 | 676 | ||
677 | hbqno = tag >> 16; | 677 | hbqno = tag >> 16; |
678 | if (hbqno > LPFC_MAX_HBQS) | 678 | if (hbqno >= LPFC_MAX_HBQS) |
679 | return NULL; | 679 | return NULL; |
680 | 680 | ||
681 | list_for_each_entry(d_buf, &phba->hbqs[hbqno].hbq_buffer_list, list) { | 681 | list_for_each_entry(d_buf, &phba->hbqs[hbqno].hbq_buffer_list, list) { |
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c index da56163c30a8..e7e11f282c8f 100644 --- a/drivers/scsi/megaraid.c +++ b/drivers/scsi/megaraid.c | |||
@@ -4416,8 +4416,7 @@ mega_internal_command(adapter_t *adapter, megacmd_t *mc, mega_passthru *pthru) | |||
4416 | scmd = &adapter->int_scmd; | 4416 | scmd = &adapter->int_scmd; |
4417 | memset(scmd, 0, sizeof(Scsi_Cmnd)); | 4417 | memset(scmd, 0, sizeof(Scsi_Cmnd)); |
4418 | 4418 | ||
4419 | sdev = kmalloc(sizeof(struct scsi_device), GFP_KERNEL); | 4419 | sdev = kzalloc(sizeof(struct scsi_device), GFP_KERNEL); |
4420 | memset(sdev, 0, sizeof(struct scsi_device)); | ||
4421 | scmd->device = sdev; | 4420 | scmd->device = sdev; |
4422 | 4421 | ||
4423 | scmd->device->host = adapter->host; | 4422 | scmd->device->host = adapter->host; |
diff --git a/drivers/scsi/mvme16x_scsi.c b/drivers/scsi/mvme16x_scsi.c index 1bdddad48571..b264b499d982 100644 --- a/drivers/scsi/mvme16x_scsi.c +++ b/drivers/scsi/mvme16x_scsi.c | |||
@@ -48,13 +48,12 @@ mvme16x_probe(struct device *dev) | |||
48 | goto out; | 48 | goto out; |
49 | } | 49 | } |
50 | 50 | ||
51 | hostdata = kmalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); | 51 | hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); |
52 | if (hostdata == NULL) { | 52 | if (hostdata == NULL) { |
53 | printk(KERN_ERR "mvme16x-scsi: " | 53 | printk(KERN_ERR "mvme16x-scsi: " |
54 | "Failed to allocate host data\n"); | 54 | "Failed to allocate host data\n"); |
55 | goto out; | 55 | goto out; |
56 | } | 56 | } |
57 | memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters)); | ||
58 | 57 | ||
59 | /* Fill in the required pieces of hostdata */ | 58 | /* Fill in the required pieces of hostdata */ |
60 | hostdata->base = (void __iomem *)0xfff47000UL; | 59 | hostdata->base = (void __iomem *)0xfff47000UL; |
diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 030ba49f33ff..016c462bc771 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c | |||
@@ -8143,12 +8143,7 @@ static int ncr53c8xx_abort(struct scsi_cmnd *cmd) | |||
8143 | unsigned long flags; | 8143 | unsigned long flags; |
8144 | struct scsi_cmnd *done_list; | 8144 | struct scsi_cmnd *done_list; |
8145 | 8145 | ||
8146 | #if defined SCSI_RESET_SYNCHRONOUS && defined SCSI_RESET_ASYNCHRONOUS | 8146 | printk("ncr53c8xx_abort: command pid %lu\n", cmd->serial_number); |
8147 | printk("ncr53c8xx_abort: pid=%lu serial_number=%ld\n", | ||
8148 | cmd->pid, cmd->serial_number); | ||
8149 | #else | ||
8150 | printk("ncr53c8xx_abort: command pid %lu\n", cmd->pid); | ||
8151 | #endif | ||
8152 | 8147 | ||
8153 | NCR_LOCK_NCB(np, flags); | 8148 | NCR_LOCK_NCB(np, flags); |
8154 | 8149 | ||
@@ -8528,18 +8523,15 @@ struct Scsi_Host * __init ncr_attach(struct scsi_host_template *tpnt, | |||
8528 | } | 8523 | } |
8529 | 8524 | ||
8530 | 8525 | ||
8531 | int ncr53c8xx_release(struct Scsi_Host *host) | 8526 | void ncr53c8xx_release(struct Scsi_Host *host) |
8532 | { | 8527 | { |
8533 | struct host_data *host_data; | 8528 | struct host_data *host_data = shost_priv(host); |
8534 | #ifdef DEBUG_NCR53C8XX | 8529 | #ifdef DEBUG_NCR53C8XX |
8535 | printk("ncr53c8xx: release\n"); | 8530 | printk("ncr53c8xx: release\n"); |
8536 | #endif | 8531 | #endif |
8537 | if (!host) | 8532 | if (host_data->ncb) |
8538 | return 1; | ||
8539 | host_data = (struct host_data *)host->hostdata; | ||
8540 | if (host_data && host_data->ncb) | ||
8541 | ncr_detach(host_data->ncb); | 8533 | ncr_detach(host_data->ncb); |
8542 | return 1; | 8534 | scsi_host_put(host); |
8543 | } | 8535 | } |
8544 | 8536 | ||
8545 | static void ncr53c8xx_set_period(struct scsi_target *starget, int period) | 8537 | static void ncr53c8xx_set_period(struct scsi_target *starget, int period) |
diff --git a/drivers/scsi/ncr53c8xx.h b/drivers/scsi/ncr53c8xx.h index b39357d9af8d..0e008dacf679 100644 --- a/drivers/scsi/ncr53c8xx.h +++ b/drivers/scsi/ncr53c8xx.h | |||
@@ -1321,7 +1321,7 @@ struct ncr_device { | |||
1321 | }; | 1321 | }; |
1322 | 1322 | ||
1323 | extern struct Scsi_Host *ncr_attach(struct scsi_host_template *tpnt, int unit, struct ncr_device *device); | 1323 | extern struct Scsi_Host *ncr_attach(struct scsi_host_template *tpnt, int unit, struct ncr_device *device); |
1324 | extern int ncr53c8xx_release(struct Scsi_Host *host); | 1324 | extern void ncr53c8xx_release(struct Scsi_Host *host); |
1325 | irqreturn_t ncr53c8xx_intr(int irq, void *dev_id); | 1325 | irqreturn_t ncr53c8xx_intr(int irq, void *dev_id); |
1326 | extern int ncr53c8xx_init(void); | 1326 | extern int ncr53c8xx_init(void); |
1327 | extern void ncr53c8xx_exit(void); | 1327 | extern void ncr53c8xx_exit(void); |
diff --git a/drivers/scsi/osst.c b/drivers/scsi/osst.c index 08060fb478b6..331b789937c4 100644 --- a/drivers/scsi/osst.c +++ b/drivers/scsi/osst.c | |||
@@ -3298,7 +3298,7 @@ static ssize_t osst_write(struct file * filp, const char __user * buf, size_t co | |||
3298 | char * name = tape_name(STp); | 3298 | char * name = tape_name(STp); |
3299 | 3299 | ||
3300 | 3300 | ||
3301 | if (down_interruptible(&STp->lock)) | 3301 | if (mutex_lock_interruptible(&STp->lock)) |
3302 | return (-ERESTARTSYS); | 3302 | return (-ERESTARTSYS); |
3303 | 3303 | ||
3304 | /* | 3304 | /* |
@@ -3600,7 +3600,7 @@ if (SRpnt) printk(KERN_ERR "%s:A: Not supposed to have SRpnt at line %d\n", name | |||
3600 | out: | 3600 | out: |
3601 | if (SRpnt != NULL) osst_release_request(SRpnt); | 3601 | if (SRpnt != NULL) osst_release_request(SRpnt); |
3602 | 3602 | ||
3603 | up(&STp->lock); | 3603 | mutex_unlock(&STp->lock); |
3604 | 3604 | ||
3605 | return retval; | 3605 | return retval; |
3606 | } | 3606 | } |
@@ -3619,7 +3619,7 @@ static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, lo | |||
3619 | char * name = tape_name(STp); | 3619 | char * name = tape_name(STp); |
3620 | 3620 | ||
3621 | 3621 | ||
3622 | if (down_interruptible(&STp->lock)) | 3622 | if (mutex_lock_interruptible(&STp->lock)) |
3623 | return (-ERESTARTSYS); | 3623 | return (-ERESTARTSYS); |
3624 | 3624 | ||
3625 | /* | 3625 | /* |
@@ -3785,7 +3785,7 @@ static ssize_t osst_read(struct file * filp, char __user * buf, size_t count, lo | |||
3785 | out: | 3785 | out: |
3786 | if (SRpnt != NULL) osst_release_request(SRpnt); | 3786 | if (SRpnt != NULL) osst_release_request(SRpnt); |
3787 | 3787 | ||
3788 | up(&STp->lock); | 3788 | mutex_unlock(&STp->lock); |
3789 | 3789 | ||
3790 | return retval; | 3790 | return retval; |
3791 | } | 3791 | } |
@@ -4852,7 +4852,7 @@ static int osst_ioctl(struct inode * inode,struct file * file, | |||
4852 | char * name = tape_name(STp); | 4852 | char * name = tape_name(STp); |
4853 | void __user * p = (void __user *)arg; | 4853 | void __user * p = (void __user *)arg; |
4854 | 4854 | ||
4855 | if (down_interruptible(&STp->lock)) | 4855 | if (mutex_lock_interruptible(&STp->lock)) |
4856 | return -ERESTARTSYS; | 4856 | return -ERESTARTSYS; |
4857 | 4857 | ||
4858 | #if DEBUG | 4858 | #if DEBUG |
@@ -5163,14 +5163,14 @@ static int osst_ioctl(struct inode * inode,struct file * file, | |||
5163 | } | 5163 | } |
5164 | if (SRpnt) osst_release_request(SRpnt); | 5164 | if (SRpnt) osst_release_request(SRpnt); |
5165 | 5165 | ||
5166 | up(&STp->lock); | 5166 | mutex_unlock(&STp->lock); |
5167 | 5167 | ||
5168 | return scsi_ioctl(STp->device, cmd_in, p); | 5168 | return scsi_ioctl(STp->device, cmd_in, p); |
5169 | 5169 | ||
5170 | out: | 5170 | out: |
5171 | if (SRpnt) osst_release_request(SRpnt); | 5171 | if (SRpnt) osst_release_request(SRpnt); |
5172 | 5172 | ||
5173 | up(&STp->lock); | 5173 | mutex_unlock(&STp->lock); |
5174 | 5174 | ||
5175 | return retval; | 5175 | return retval; |
5176 | } | 5176 | } |
@@ -5778,13 +5778,12 @@ static int osst_probe(struct device *dev) | |||
5778 | dev_num = i; | 5778 | dev_num = i; |
5779 | 5779 | ||
5780 | /* allocate a struct osst_tape for this device */ | 5780 | /* allocate a struct osst_tape for this device */ |
5781 | tpnt = kmalloc(sizeof(struct osst_tape), GFP_ATOMIC); | 5781 | tpnt = kzalloc(sizeof(struct osst_tape), GFP_ATOMIC); |
5782 | if (tpnt == NULL) { | 5782 | if (!tpnt) { |
5783 | write_unlock(&os_scsi_tapes_lock); | 5783 | write_unlock(&os_scsi_tapes_lock); |
5784 | printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n"); | 5784 | printk(KERN_ERR "osst :E: Can't allocate device descriptor, device not attached.\n"); |
5785 | goto out_put_disk; | 5785 | goto out_put_disk; |
5786 | } | 5786 | } |
5787 | memset(tpnt, 0, sizeof(struct osst_tape)); | ||
5788 | 5787 | ||
5789 | /* allocate a buffer for this device */ | 5788 | /* allocate a buffer for this device */ |
5790 | i = SDp->host->sg_tablesize; | 5789 | i = SDp->host->sg_tablesize; |
@@ -5866,7 +5865,7 @@ static int osst_probe(struct device *dev) | |||
5866 | tpnt->modes[2].defined = 1; | 5865 | tpnt->modes[2].defined = 1; |
5867 | tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0; | 5866 | tpnt->density_changed = tpnt->compression_changed = tpnt->blksize_changed = 0; |
5868 | 5867 | ||
5869 | init_MUTEX(&tpnt->lock); | 5868 | mutex_init(&tpnt->lock); |
5870 | osst_nr_dev++; | 5869 | osst_nr_dev++; |
5871 | write_unlock(&os_scsi_tapes_lock); | 5870 | write_unlock(&os_scsi_tapes_lock); |
5872 | 5871 | ||
diff --git a/drivers/scsi/osst.h b/drivers/scsi/osst.h index 2cc7b5a1606a..5aa22740b5df 100644 --- a/drivers/scsi/osst.h +++ b/drivers/scsi/osst.h | |||
@@ -4,6 +4,7 @@ | |||
4 | 4 | ||
5 | #include <asm/byteorder.h> | 5 | #include <asm/byteorder.h> |
6 | #include <linux/completion.h> | 6 | #include <linux/completion.h> |
7 | #include <linux/mutex.h> | ||
7 | 8 | ||
8 | /* FIXME - rename and use the following two types or delete them! | 9 | /* FIXME - rename and use the following two types or delete them! |
9 | * and the types really should go to st.h anyway... | 10 | * and the types really should go to st.h anyway... |
@@ -532,7 +533,7 @@ struct osst_tape { | |||
532 | struct scsi_driver *driver; | 533 | struct scsi_driver *driver; |
533 | unsigned capacity; | 534 | unsigned capacity; |
534 | struct scsi_device *device; | 535 | struct scsi_device *device; |
535 | struct semaphore lock; /* for serialization */ | 536 | struct mutex lock; /* for serialization */ |
536 | struct completion wait; /* for SCSI commands */ | 537 | struct completion wait; /* for SCSI commands */ |
537 | struct osst_buffer * buffer; | 538 | struct osst_buffer * buffer; |
538 | 539 | ||
diff --git a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c index 445cfbbca9b3..a45d89b14147 100644 --- a/drivers/scsi/pcmcia/nsp_cs.c +++ b/drivers/scsi/pcmcia/nsp_cs.c | |||
@@ -25,8 +25,6 @@ | |||
25 | 25 | ||
26 | ***********************************************************************/ | 26 | ***********************************************************************/ |
27 | 27 | ||
28 | /* $Id: nsp_cs.c,v 1.23 2003/08/18 11:09:19 elca Exp $ */ | ||
29 | |||
30 | #include <linux/version.h> | 28 | #include <linux/version.h> |
31 | #include <linux/module.h> | 29 | #include <linux/module.h> |
32 | #include <linux/kernel.h> | 30 | #include <linux/kernel.h> |
@@ -59,7 +57,7 @@ | |||
59 | #include "nsp_cs.h" | 57 | #include "nsp_cs.h" |
60 | 58 | ||
61 | MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>"); | 59 | MODULE_AUTHOR("YOKOTA Hiroshi <yokota@netlab.is.tsukuba.ac.jp>"); |
62 | MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module $Revision: 1.23 $"); | 60 | MODULE_DESCRIPTION("WorkBit NinjaSCSI-3 / NinjaSCSI-32Bi(16bit) PCMCIA SCSI host adapter module"); |
63 | MODULE_SUPPORTED_DEVICE("sd,sr,sg,st"); | 61 | MODULE_SUPPORTED_DEVICE("sd,sr,sg,st"); |
64 | #ifdef MODULE_LICENSE | 62 | #ifdef MODULE_LICENSE |
65 | MODULE_LICENSE("GPL"); | 63 | MODULE_LICENSE("GPL"); |
@@ -83,10 +81,6 @@ static struct scsi_host_template nsp_driver_template = { | |||
83 | .proc_name = "nsp_cs", | 81 | .proc_name = "nsp_cs", |
84 | .proc_info = nsp_proc_info, | 82 | .proc_info = nsp_proc_info, |
85 | .name = "WorkBit NinjaSCSI-3/32Bi(16bit)", | 83 | .name = "WorkBit NinjaSCSI-3/32Bi(16bit)", |
86 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) | ||
87 | .detect = nsp_detect_old, | ||
88 | .release = nsp_release_old, | ||
89 | #endif | ||
90 | .info = nsp_info, | 84 | .info = nsp_info, |
91 | .queuecommand = nsp_queuecommand, | 85 | .queuecommand = nsp_queuecommand, |
92 | /* .eh_abort_handler = nsp_eh_abort,*/ | 86 | /* .eh_abort_handler = nsp_eh_abort,*/ |
@@ -97,9 +91,6 @@ static struct scsi_host_template nsp_driver_template = { | |||
97 | .sg_tablesize = SG_ALL, | 91 | .sg_tablesize = SG_ALL, |
98 | .cmd_per_lun = 1, | 92 | .cmd_per_lun = 1, |
99 | .use_clustering = DISABLE_CLUSTERING, | 93 | .use_clustering = DISABLE_CLUSTERING, |
100 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,2)) | ||
101 | .use_new_eh_code = 1, | ||
102 | #endif | ||
103 | }; | 94 | }; |
104 | 95 | ||
105 | static nsp_hw_data nsp_data_base; /* attach <-> detect glue */ | 96 | static nsp_hw_data nsp_data_base; /* attach <-> detect glue */ |
@@ -1313,11 +1304,7 @@ static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht) | |||
1313 | nsp_hw_data *data_b = &nsp_data_base, *data; | 1304 | nsp_hw_data *data_b = &nsp_data_base, *data; |
1314 | 1305 | ||
1315 | nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id); | 1306 | nsp_dbg(NSP_DEBUG_INIT, "this_id=%d", sht->this_id); |
1316 | #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) | ||
1317 | host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data)); | 1307 | host = scsi_host_alloc(&nsp_driver_template, sizeof(nsp_hw_data)); |
1318 | #else | ||
1319 | host = scsi_register(sht, sizeof(nsp_hw_data)); | ||
1320 | #endif | ||
1321 | if (host == NULL) { | 1308 | if (host == NULL) { |
1322 | nsp_dbg(NSP_DEBUG_INIT, "host failed"); | 1309 | nsp_dbg(NSP_DEBUG_INIT, "host failed"); |
1323 | return NULL; | 1310 | return NULL; |
@@ -1354,37 +1341,6 @@ static struct Scsi_Host *nsp_detect(struct scsi_host_template *sht) | |||
1354 | return host; /* detect done. */ | 1341 | return host; /* detect done. */ |
1355 | } | 1342 | } |
1356 | 1343 | ||
1357 | #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)) | ||
1358 | static int nsp_detect_old(struct scsi_host_template *sht) | ||
1359 | { | ||
1360 | if (nsp_detect(sht) == NULL) { | ||
1361 | return 0; | ||
1362 | } else { | ||
1363 | //MOD_INC_USE_COUNT; | ||
1364 | return 1; | ||
1365 | } | ||
1366 | } | ||
1367 | |||
1368 | |||
1369 | static int nsp_release_old(struct Scsi_Host *shpnt) | ||
1370 | { | ||
1371 | //nsp_hw_data *data = (nsp_hw_data *)shpnt->hostdata; | ||
1372 | |||
1373 | /* PCMCIA Card Service dose same things below. */ | ||
1374 | /* So we do nothing. */ | ||
1375 | //if (shpnt->irq) { | ||
1376 | // free_irq(shpnt->irq, data->ScsiInfo); | ||
1377 | //} | ||
1378 | //if (shpnt->io_port) { | ||
1379 | // release_region(shpnt->io_port, shpnt->n_io_port); | ||
1380 | //} | ||
1381 | |||
1382 | //MOD_DEC_USE_COUNT; | ||
1383 | |||
1384 | return 0; | ||
1385 | } | ||
1386 | #endif | ||
1387 | |||
1388 | /*----------------------------------------------------------------*/ | 1344 | /*----------------------------------------------------------------*/ |
1389 | /* return info string */ | 1345 | /* return info string */ |
1390 | /*----------------------------------------------------------------*/ | 1346 | /*----------------------------------------------------------------*/ |
@@ -1403,19 +1359,9 @@ static const char *nsp_info(struct Scsi_Host *shpnt) | |||
1403 | nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length, length - (pos - buffer));\ | 1359 | nsp_dbg(NSP_DEBUG_PROC, "buffer=0x%p pos=0x%p length=%d %d\n", buffer, pos, length, length - (pos - buffer));\ |
1404 | } \ | 1360 | } \ |
1405 | } while(0) | 1361 | } while(0) |
1406 | static int | 1362 | |
1407 | nsp_proc_info( | 1363 | static int nsp_proc_info(struct Scsi_Host *host, char *buffer, char **start, |
1408 | #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) | 1364 | off_t offset, int length, int inout) |
1409 | struct Scsi_Host *host, | ||
1410 | #endif | ||
1411 | char *buffer, | ||
1412 | char **start, | ||
1413 | off_t offset, | ||
1414 | int length, | ||
1415 | #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) | ||
1416 | int hostno, | ||
1417 | #endif | ||
1418 | int inout) | ||
1419 | { | 1365 | { |
1420 | int id; | 1366 | int id; |
1421 | char *pos = buffer; | 1367 | char *pos = buffer; |
@@ -1423,24 +1369,13 @@ nsp_proc_info( | |||
1423 | int speed; | 1369 | int speed; |
1424 | unsigned long flags; | 1370 | unsigned long flags; |
1425 | nsp_hw_data *data; | 1371 | nsp_hw_data *data; |
1426 | #if !(LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) | ||
1427 | struct Scsi_Host *host; | ||
1428 | #else | ||
1429 | int hostno; | 1372 | int hostno; |
1430 | #endif | 1373 | |
1431 | if (inout) { | 1374 | if (inout) { |
1432 | return -EINVAL; | 1375 | return -EINVAL; |
1433 | } | 1376 | } |
1434 | 1377 | ||
1435 | #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,73)) | ||
1436 | hostno = host->host_no; | 1378 | hostno = host->host_no; |
1437 | #else | ||
1438 | /* search this HBA host */ | ||
1439 | host = scsi_host_hn_get(hostno); | ||
1440 | if (host == NULL) { | ||
1441 | return -ESRCH; | ||
1442 | } | ||
1443 | #endif | ||
1444 | data = (nsp_hw_data *)host->hostdata; | 1379 | data = (nsp_hw_data *)host->hostdata; |
1445 | 1380 | ||
1446 | 1381 | ||
@@ -1675,10 +1610,6 @@ static int nsp_cs_config(struct pcmcia_device *link) | |||
1675 | cistpl_cftable_entry_t dflt = { 0 }; | 1610 | cistpl_cftable_entry_t dflt = { 0 }; |
1676 | struct Scsi_Host *host; | 1611 | struct Scsi_Host *host; |
1677 | nsp_hw_data *data = &nsp_data_base; | 1612 | nsp_hw_data *data = &nsp_data_base; |
1678 | #if !(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) | ||
1679 | struct scsi_device *dev; | ||
1680 | dev_node_t **tail, *node; | ||
1681 | #endif | ||
1682 | 1613 | ||
1683 | nsp_dbg(NSP_DEBUG_INIT, "in"); | 1614 | nsp_dbg(NSP_DEBUG_INIT, "in"); |
1684 | 1615 | ||
@@ -1811,17 +1742,7 @@ static int nsp_cs_config(struct pcmcia_device *link) | |||
1811 | goto cs_failed; | 1742 | goto cs_failed; |
1812 | } | 1743 | } |
1813 | 1744 | ||
1814 | #if (LINUX_VERSION_CODE > KERNEL_VERSION(2,5,2)) | ||
1815 | host = nsp_detect(&nsp_driver_template); | 1745 | host = nsp_detect(&nsp_driver_template); |
1816 | #else | ||
1817 | scsi_register_host(&nsp_driver_template); | ||
1818 | for (host = scsi_host_get_next(NULL); host != NULL; | ||
1819 | host = scsi_host_get_next(host)) { | ||
1820 | if (host->hostt == &nsp_driver_template) { | ||
1821 | break; | ||
1822 | } | ||
1823 | } | ||
1824 | #endif | ||
1825 | 1746 | ||
1826 | if (host == NULL) { | 1747 | if (host == NULL) { |
1827 | nsp_dbg(NSP_DEBUG_INIT, "detect failed"); | 1748 | nsp_dbg(NSP_DEBUG_INIT, "detect failed"); |
@@ -1829,7 +1750,6 @@ static int nsp_cs_config(struct pcmcia_device *link) | |||
1829 | } | 1750 | } |
1830 | 1751 | ||
1831 | 1752 | ||
1832 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) | ||
1833 | ret = scsi_add_host (host, NULL); | 1753 | ret = scsi_add_host (host, NULL); |
1834 | if (ret) | 1754 | if (ret) |
1835 | goto cs_failed; | 1755 | goto cs_failed; |
@@ -1840,52 +1760,6 @@ static int nsp_cs_config(struct pcmcia_device *link) | |||
1840 | link->dev_node = &info->node; | 1760 | link->dev_node = &info->node; |
1841 | info->host = host; | 1761 | info->host = host; |
1842 | 1762 | ||
1843 | #else | ||
1844 | nsp_dbg(NSP_DEBUG_INIT, "GET_SCSI_INFO"); | ||
1845 | tail = &link->dev_node; | ||
1846 | info->ndev = 0; | ||
1847 | |||
1848 | nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host); | ||
1849 | |||
1850 | for (dev = host->host_queue; dev != NULL; dev = dev->next) { | ||
1851 | unsigned long id; | ||
1852 | id = (dev->id & 0x0f) + ((dev->lun & 0x0f) << 4) + | ||
1853 | ((dev->channel & 0x0f) << 8) + | ||
1854 | ((dev->host->host_no & 0x0f) << 12); | ||
1855 | node = &info->node[info->ndev]; | ||
1856 | node->minor = 0; | ||
1857 | switch (dev->type) { | ||
1858 | case TYPE_TAPE: | ||
1859 | node->major = SCSI_TAPE_MAJOR; | ||
1860 | snprintf(node->dev_name, sizeof(node->dev_name), "st#%04lx", id); | ||
1861 | break; | ||
1862 | case TYPE_DISK: | ||
1863 | case TYPE_MOD: | ||
1864 | node->major = SCSI_DISK0_MAJOR; | ||
1865 | snprintf(node->dev_name, sizeof(node->dev_name), "sd#%04lx", id); | ||
1866 | break; | ||
1867 | case TYPE_ROM: | ||
1868 | case TYPE_WORM: | ||
1869 | node->major = SCSI_CDROM_MAJOR; | ||
1870 | snprintf(node->dev_name, sizeof(node->dev_name), "sr#%04lx", id); | ||
1871 | break; | ||
1872 | default: | ||
1873 | node->major = SCSI_GENERIC_MAJOR; | ||
1874 | snprintf(node->dev_name, sizeof(node->dev_name), "sg#%04lx", id); | ||
1875 | break; | ||
1876 | } | ||
1877 | *tail = node; tail = &node->next; | ||
1878 | info->ndev++; | ||
1879 | info->host = dev->host; | ||
1880 | } | ||
1881 | |||
1882 | *tail = NULL; | ||
1883 | if (info->ndev == 0) { | ||
1884 | nsp_msg(KERN_INFO, "no SCSI devices found"); | ||
1885 | } | ||
1886 | nsp_dbg(NSP_DEBUG_INIT, "host=0x%p", host); | ||
1887 | #endif | ||
1888 | |||
1889 | /* Finally, report what we've done */ | 1763 | /* Finally, report what we've done */ |
1890 | printk(KERN_INFO "nsp_cs: index 0x%02x: ", | 1764 | printk(KERN_INFO "nsp_cs: index 0x%02x: ", |
1891 | link->conf.ConfigIndex); | 1765 | link->conf.ConfigIndex); |
@@ -1938,13 +1812,9 @@ static void nsp_cs_release(struct pcmcia_device *link) | |||
1938 | nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link); | 1812 | nsp_dbg(NSP_DEBUG_INIT, "link=0x%p", link); |
1939 | 1813 | ||
1940 | /* Unlink the device chain */ | 1814 | /* Unlink the device chain */ |
1941 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2)) | ||
1942 | if (info->host != NULL) { | 1815 | if (info->host != NULL) { |
1943 | scsi_remove_host(info->host); | 1816 | scsi_remove_host(info->host); |
1944 | } | 1817 | } |
1945 | #else | ||
1946 | scsi_unregister_host(&nsp_driver_template); | ||
1947 | #endif | ||
1948 | link->dev_node = NULL; | 1818 | link->dev_node = NULL; |
1949 | 1819 | ||
1950 | if (link->win) { | 1820 | if (link->win) { |
@@ -1954,11 +1824,9 @@ static void nsp_cs_release(struct pcmcia_device *link) | |||
1954 | } | 1824 | } |
1955 | pcmcia_disable_device(link); | 1825 | pcmcia_disable_device(link); |
1956 | 1826 | ||
1957 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,2)) | ||
1958 | if (info->host != NULL) { | 1827 | if (info->host != NULL) { |
1959 | scsi_host_put(info->host); | 1828 | scsi_host_put(info->host); |
1960 | } | 1829 | } |
1961 | #endif | ||
1962 | } /* nsp_cs_release */ | 1830 | } /* nsp_cs_release */ |
1963 | 1831 | ||
1964 | static int nsp_cs_suspend(struct pcmcia_device *link) | 1832 | static int nsp_cs_suspend(struct pcmcia_device *link) |
@@ -2005,7 +1873,6 @@ static int nsp_cs_resume(struct pcmcia_device *link) | |||
2005 | /*======================================================================* | 1873 | /*======================================================================* |
2006 | * module entry point | 1874 | * module entry point |
2007 | *====================================================================*/ | 1875 | *====================================================================*/ |
2008 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68)) | ||
2009 | static struct pcmcia_device_id nsp_cs_ids[] = { | 1876 | static struct pcmcia_device_id nsp_cs_ids[] = { |
2010 | PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16 ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a), | 1877 | PCMCIA_DEVICE_PROD_ID123("IO DATA", "CBSC16 ", "1", 0x547e66dc, 0x0d63a3fd, 0x51de003a), |
2011 | PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a), | 1878 | PCMCIA_DEVICE_PROD_ID123("KME ", "SCSI-CARD-001", "1", 0x534c02bc, 0x52008408, 0x51de003a), |
@@ -2029,28 +1896,12 @@ static struct pcmcia_driver nsp_driver = { | |||
2029 | .suspend = nsp_cs_suspend, | 1896 | .suspend = nsp_cs_suspend, |
2030 | .resume = nsp_cs_resume, | 1897 | .resume = nsp_cs_resume, |
2031 | }; | 1898 | }; |
2032 | #endif | ||
2033 | 1899 | ||
2034 | static int __init nsp_cs_init(void) | 1900 | static int __init nsp_cs_init(void) |
2035 | { | 1901 | { |
2036 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,68)) | ||
2037 | nsp_msg(KERN_INFO, "loading..."); | 1902 | nsp_msg(KERN_INFO, "loading..."); |
2038 | 1903 | ||
2039 | return pcmcia_register_driver(&nsp_driver); | 1904 | return pcmcia_register_driver(&nsp_driver); |
2040 | #else | ||
2041 | servinfo_t serv; | ||
2042 | |||
2043 | nsp_msg(KERN_INFO, "loading..."); | ||
2044 | pcmcia_get_card_services_info(&serv); | ||
2045 | if (serv.Revision != CS_RELEASE_CODE) { | ||
2046 | nsp_msg(KERN_DEBUG, "Card Services release does not match!"); | ||
2047 | return -EINVAL; | ||
2048 | } | ||
2049 | register_pcmcia_driver(&dev_info, &nsp_cs_attach, &nsp_cs_detach); | ||
2050 | |||
2051 | nsp_dbg(NSP_DEBUG_INIT, "out"); | ||
2052 | return 0; | ||
2053 | #endif | ||
2054 | } | 1905 | } |
2055 | 1906 | ||
2056 | static void __exit nsp_cs_exit(void) | 1907 | static void __exit nsp_cs_exit(void) |
diff --git a/drivers/scsi/pcmcia/nsp_cs.h b/drivers/scsi/pcmcia/nsp_cs.h index 9102cbdf1359..b7f0fa246413 100644 --- a/drivers/scsi/pcmcia/nsp_cs.h +++ b/drivers/scsi/pcmcia/nsp_cs.h | |||
@@ -10,8 +10,6 @@ | |||
10 | 10 | ||
11 | =========================================================*/ | 11 | =========================================================*/ |
12 | 12 | ||
13 | /* $Id: nsp_cs.h,v 1.19 2003/08/18 11:09:19 elca Exp $ */ | ||
14 | |||
15 | #ifndef __nsp_cs__ | 13 | #ifndef __nsp_cs__ |
16 | #define __nsp_cs__ | 14 | #define __nsp_cs__ |
17 | 15 | ||
@@ -227,13 +225,7 @@ | |||
227 | typedef struct scsi_info_t { | 225 | typedef struct scsi_info_t { |
228 | struct pcmcia_device *p_dev; | 226 | struct pcmcia_device *p_dev; |
229 | struct Scsi_Host *host; | 227 | struct Scsi_Host *host; |
230 | #if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,74)) | ||
231 | dev_node_t node; | 228 | dev_node_t node; |
232 | #else | ||
233 | int ndev; | ||
234 | dev_node_t node[8]; | ||
235 | struct bus_operations *bus; | ||
236 | #endif | ||
237 | int stop; | 229 | int stop; |
238 | } scsi_info_t; | 230 | } scsi_info_t; |
239 | 231 | ||
diff --git a/drivers/scsi/pluto.c b/drivers/scsi/pluto.c index d953d43fe2e6..0363c1cd68c1 100644 --- a/drivers/scsi/pluto.c +++ b/drivers/scsi/pluto.c | |||
@@ -111,13 +111,12 @@ int __init pluto_detect(struct scsi_host_template *tpnt) | |||
111 | #endif | 111 | #endif |
112 | return 0; | 112 | return 0; |
113 | } | 113 | } |
114 | fcs = kmalloc(sizeof (struct ctrl_inquiry) * fcscount, GFP_DMA); | 114 | fcs = kcalloc(fcscount, sizeof (struct ctrl_inquiry), GFP_DMA); |
115 | if (!fcs) { | 115 | if (!fcs) { |
116 | printk ("PLUTO: Not enough memory to probe\n"); | 116 | printk ("PLUTO: Not enough memory to probe\n"); |
117 | return 0; | 117 | return 0; |
118 | } | 118 | } |
119 | 119 | ||
120 | memset (fcs, 0, sizeof (struct ctrl_inquiry) * fcscount); | ||
121 | memset (&dev, 0, sizeof(dev)); | 120 | memset (&dev, 0, sizeof(dev)); |
122 | atomic_set (&fcss, fcscount); | 121 | atomic_set (&fcss, fcscount); |
123 | 122 | ||
@@ -161,7 +160,6 @@ int __init pluto_detect(struct scsi_host_template *tpnt) | |||
161 | 160 | ||
162 | SCpnt->request->cmd_flags &= ~REQ_STARTED; | 161 | SCpnt->request->cmd_flags &= ~REQ_STARTED; |
163 | 162 | ||
164 | SCpnt->done = pluto_detect_done; | ||
165 | SCpnt->request_bufflen = 256; | 163 | SCpnt->request_bufflen = 256; |
166 | SCpnt->request_buffer = fcs[i].inquiry; | 164 | SCpnt->request_buffer = fcs[i].inquiry; |
167 | PLD(("set up %d %08lx\n", i, (long)SCpnt)) | 165 | PLD(("set up %d %08lx\n", i, (long)SCpnt)) |
@@ -196,7 +194,7 @@ int __init pluto_detect(struct scsi_host_template *tpnt) | |||
196 | SCpnt = &(fcs[i].cmd); | 194 | SCpnt = &(fcs[i].cmd); |
197 | 195 | ||
198 | /* Let FC mid-level free allocated resources */ | 196 | /* Let FC mid-level free allocated resources */ |
199 | SCpnt->done (SCpnt); | 197 | pluto_detect_scsi_done(SCpnt); |
200 | 198 | ||
201 | if (!SCpnt->result) { | 199 | if (!SCpnt->result) { |
202 | struct pluto_inquiry *inq; | 200 | struct pluto_inquiry *inq; |
@@ -211,7 +209,7 @@ int __init pluto_detect(struct scsi_host_template *tpnt) | |||
211 | char *p; | 209 | char *p; |
212 | long *ages; | 210 | long *ages; |
213 | 211 | ||
214 | ages = kmalloc (((inq->channels + 1) * inq->targets) * sizeof(long), GFP_KERNEL); | 212 | ages = kcalloc((inq->channels + 1) * inq->targets, sizeof(long), GFP_KERNEL); |
215 | if (!ages) continue; | 213 | if (!ages) continue; |
216 | 214 | ||
217 | host = scsi_register (tpnt, sizeof (struct pluto)); | 215 | host = scsi_register (tpnt, sizeof (struct pluto)); |
@@ -238,7 +236,6 @@ int __init pluto_detect(struct scsi_host_template *tpnt) | |||
238 | fc->channels = inq->channels + 1; | 236 | fc->channels = inq->channels + 1; |
239 | fc->targets = inq->targets; | 237 | fc->targets = inq->targets; |
240 | fc->ages = ages; | 238 | fc->ages = ages; |
241 | memset (ages, 0, ((inq->channels + 1) * inq->targets) * sizeof(long)); | ||
242 | 239 | ||
243 | pluto->fc = fc; | 240 | pluto->fc = fc; |
244 | memcpy (pluto->rev_str, inq->revision, 4); | 241 | memcpy (pluto->rev_str, inq->revision, 4); |
@@ -260,7 +257,7 @@ int __init pluto_detect(struct scsi_host_template *tpnt) | |||
260 | } else | 257 | } else |
261 | fc->fcp_register(fc, TYPE_SCSI_FCP, 1); | 258 | fc->fcp_register(fc, TYPE_SCSI_FCP, 1); |
262 | } | 259 | } |
263 | kfree((char *)fcs); | 260 | kfree(fcs); |
264 | if (nplutos) | 261 | if (nplutos) |
265 | printk ("PLUTO: Total of %d SparcSTORAGE Arrays found\n", nplutos); | 262 | printk ("PLUTO: Total of %d SparcSTORAGE Arrays found\n", nplutos); |
266 | return nplutos; | 263 | return nplutos; |
diff --git a/drivers/scsi/ps3rom.c b/drivers/scsi/ps3rom.c index b50f1e14f2a5..0f43d1d046d9 100644 --- a/drivers/scsi/ps3rom.c +++ b/drivers/scsi/ps3rom.c | |||
@@ -100,16 +100,16 @@ static int fill_from_dev_buffer(struct scsi_cmnd *cmd, const void *buf) | |||
100 | struct scatterlist *sgpnt; | 100 | struct scatterlist *sgpnt; |
101 | unsigned int buflen; | 101 | unsigned int buflen; |
102 | 102 | ||
103 | buflen = cmd->request_bufflen; | 103 | buflen = scsi_bufflen(cmd); |
104 | if (!buflen) | 104 | if (!buflen) |
105 | return 0; | 105 | return 0; |
106 | 106 | ||
107 | if (!cmd->request_buffer) | 107 | if (!scsi_sglist(cmd)) |
108 | return -1; | 108 | return -1; |
109 | 109 | ||
110 | sgpnt = cmd->request_buffer; | ||
111 | active = 1; | 110 | active = 1; |
112 | for (k = 0, req_len = 0, act_len = 0; k < cmd->use_sg; ++k, ++sgpnt) { | 111 | req_len = act_len = 0; |
112 | scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) { | ||
113 | if (active) { | 113 | if (active) { |
114 | kaddr = kmap_atomic(sgpnt->page, KM_IRQ0); | 114 | kaddr = kmap_atomic(sgpnt->page, KM_IRQ0); |
115 | len = sgpnt->length; | 115 | len = sgpnt->length; |
@@ -124,7 +124,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd *cmd, const void *buf) | |||
124 | } | 124 | } |
125 | req_len += sgpnt->length; | 125 | req_len += sgpnt->length; |
126 | } | 126 | } |
127 | cmd->resid = req_len - act_len; | 127 | scsi_set_resid(cmd, req_len - act_len); |
128 | return 0; | 128 | return 0; |
129 | } | 129 | } |
130 | 130 | ||
@@ -138,15 +138,15 @@ static int fetch_to_dev_buffer(struct scsi_cmnd *cmd, void *buf) | |||
138 | struct scatterlist *sgpnt; | 138 | struct scatterlist *sgpnt; |
139 | unsigned int buflen; | 139 | unsigned int buflen; |
140 | 140 | ||
141 | buflen = cmd->request_bufflen; | 141 | buflen = scsi_bufflen(cmd); |
142 | if (!buflen) | 142 | if (!buflen) |
143 | return 0; | 143 | return 0; |
144 | 144 | ||
145 | if (!cmd->request_buffer) | 145 | if (!scsi_sglist(cmd)) |
146 | return -1; | 146 | return -1; |
147 | 147 | ||
148 | sgpnt = cmd->request_buffer; | 148 | req_len = fin = 0; |
149 | for (k = 0, req_len = 0, fin = 0; k < cmd->use_sg; ++k, ++sgpnt) { | 149 | scsi_for_each_sg(cmd, sgpnt, scsi_sg_count(cmd), k) { |
150 | kaddr = kmap_atomic(sgpnt->page, KM_IRQ0); | 150 | kaddr = kmap_atomic(sgpnt->page, KM_IRQ0); |
151 | len = sgpnt->length; | 151 | len = sgpnt->length; |
152 | if ((req_len + len) > buflen) { | 152 | if ((req_len + len) > buflen) { |
@@ -177,12 +177,12 @@ static int ps3rom_atapi_request(struct ps3_storage_device *dev, | |||
177 | memcpy(&atapi_cmnd.pkt, cmd->cmnd, 12); | 177 | memcpy(&atapi_cmnd.pkt, cmd->cmnd, 12); |
178 | atapi_cmnd.pktlen = 12; | 178 | atapi_cmnd.pktlen = 12; |
179 | atapi_cmnd.block_size = 1; /* transfer size is block_size * blocks */ | 179 | atapi_cmnd.block_size = 1; /* transfer size is block_size * blocks */ |
180 | atapi_cmnd.blocks = atapi_cmnd.arglen = cmd->request_bufflen; | 180 | atapi_cmnd.blocks = atapi_cmnd.arglen = scsi_bufflen(cmd); |
181 | atapi_cmnd.buffer = dev->bounce_lpar; | 181 | atapi_cmnd.buffer = dev->bounce_lpar; |
182 | 182 | ||
183 | switch (cmd->sc_data_direction) { | 183 | switch (cmd->sc_data_direction) { |
184 | case DMA_FROM_DEVICE: | 184 | case DMA_FROM_DEVICE: |
185 | if (cmd->request_bufflen >= CD_FRAMESIZE) | 185 | if (scsi_bufflen(cmd) >= CD_FRAMESIZE) |
186 | atapi_cmnd.proto = DMA_PROTO; | 186 | atapi_cmnd.proto = DMA_PROTO; |
187 | else | 187 | else |
188 | atapi_cmnd.proto = PIO_DATA_IN_PROTO; | 188 | atapi_cmnd.proto = PIO_DATA_IN_PROTO; |
@@ -190,7 +190,7 @@ static int ps3rom_atapi_request(struct ps3_storage_device *dev, | |||
190 | break; | 190 | break; |
191 | 191 | ||
192 | case DMA_TO_DEVICE: | 192 | case DMA_TO_DEVICE: |
193 | if (cmd->request_bufflen >= CD_FRAMESIZE) | 193 | if (scsi_bufflen(cmd) >= CD_FRAMESIZE) |
194 | atapi_cmnd.proto = DMA_PROTO; | 194 | atapi_cmnd.proto = DMA_PROTO; |
195 | else | 195 | else |
196 | atapi_cmnd.proto = PIO_DATA_OUT_PROTO; | 196 | atapi_cmnd.proto = PIO_DATA_OUT_PROTO; |
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c index 54d8bdf86852..fba8aa8a81b5 100644 --- a/drivers/scsi/qla1280.c +++ b/drivers/scsi/qla1280.c | |||
@@ -4086,7 +4086,7 @@ __qla1280_print_scsi_cmd(struct scsi_cmnd *cmd) | |||
4086 | } */ | 4086 | } */ |
4087 | printk(" tag=%d, transfersize=0x%x \n", | 4087 | printk(" tag=%d, transfersize=0x%x \n", |
4088 | cmd->tag, cmd->transfersize); | 4088 | cmd->tag, cmd->transfersize); |
4089 | printk(" Pid=%li, SP=0x%p\n", cmd->pid, CMD_SP(cmd)); | 4089 | printk(" Pid=%li, SP=0x%p\n", cmd->serial_number, CMD_SP(cmd)); |
4090 | printk(" underflow size = 0x%x, direction=0x%x\n", | 4090 | printk(" underflow size = 0x%x, direction=0x%x\n", |
4091 | cmd->underflow, cmd->sc_data_direction); | 4091 | cmd->underflow, cmd->sc_data_direction); |
4092 | } | 4092 | } |
diff --git a/drivers/scsi/qla2xxx/qla_attr.c b/drivers/scsi/qla2xxx/qla_attr.c index 0f2a9f5d801c..05fa7796a559 100644 --- a/drivers/scsi/qla2xxx/qla_attr.c +++ b/drivers/scsi/qla2xxx/qla_attr.c | |||
@@ -18,7 +18,7 @@ qla2x00_sysfs_read_fw_dump(struct kobject *kobj, | |||
18 | struct bin_attribute *bin_attr, | 18 | struct bin_attribute *bin_attr, |
19 | char *buf, loff_t off, size_t count) | 19 | char *buf, loff_t off, size_t count) |
20 | { | 20 | { |
21 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | 21 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
22 | struct device, kobj))); | 22 | struct device, kobj))); |
23 | char *rbuf = (char *)ha->fw_dump; | 23 | char *rbuf = (char *)ha->fw_dump; |
24 | 24 | ||
@@ -39,7 +39,7 @@ qla2x00_sysfs_write_fw_dump(struct kobject *kobj, | |||
39 | struct bin_attribute *bin_attr, | 39 | struct bin_attribute *bin_attr, |
40 | char *buf, loff_t off, size_t count) | 40 | char *buf, loff_t off, size_t count) |
41 | { | 41 | { |
42 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | 42 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
43 | struct device, kobj))); | 43 | struct device, kobj))); |
44 | int reading; | 44 | int reading; |
45 | 45 | ||
@@ -89,7 +89,7 @@ qla2x00_sysfs_read_nvram(struct kobject *kobj, | |||
89 | struct bin_attribute *bin_attr, | 89 | struct bin_attribute *bin_attr, |
90 | char *buf, loff_t off, size_t count) | 90 | char *buf, loff_t off, size_t count) |
91 | { | 91 | { |
92 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | 92 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
93 | struct device, kobj))); | 93 | struct device, kobj))); |
94 | int size = ha->nvram_size; | 94 | int size = ha->nvram_size; |
95 | char *nvram_cache = ha->nvram; | 95 | char *nvram_cache = ha->nvram; |
@@ -112,7 +112,7 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj, | |||
112 | struct bin_attribute *bin_attr, | 112 | struct bin_attribute *bin_attr, |
113 | char *buf, loff_t off, size_t count) | 113 | char *buf, loff_t off, size_t count) |
114 | { | 114 | { |
115 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | 115 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
116 | struct device, kobj))); | 116 | struct device, kobj))); |
117 | unsigned long flags; | 117 | unsigned long flags; |
118 | uint16_t cnt; | 118 | uint16_t cnt; |
@@ -146,7 +146,7 @@ qla2x00_sysfs_write_nvram(struct kobject *kobj, | |||
146 | /* Write NVRAM. */ | 146 | /* Write NVRAM. */ |
147 | spin_lock_irqsave(&ha->hardware_lock, flags); | 147 | spin_lock_irqsave(&ha->hardware_lock, flags); |
148 | ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count); | 148 | ha->isp_ops->write_nvram(ha, (uint8_t *)buf, ha->nvram_base, count); |
149 | ha->isp_ops->read_nvram(ha, (uint8_t *)&ha->nvram, ha->nvram_base, | 149 | ha->isp_ops->read_nvram(ha, (uint8_t *)ha->nvram, ha->nvram_base, |
150 | count); | 150 | count); |
151 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 151 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
152 | 152 | ||
@@ -170,15 +170,15 @@ qla2x00_sysfs_read_optrom(struct kobject *kobj, | |||
170 | struct bin_attribute *bin_attr, | 170 | struct bin_attribute *bin_attr, |
171 | char *buf, loff_t off, size_t count) | 171 | char *buf, loff_t off, size_t count) |
172 | { | 172 | { |
173 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | 173 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
174 | struct device, kobj))); | 174 | struct device, kobj))); |
175 | 175 | ||
176 | if (ha->optrom_state != QLA_SREADING) | 176 | if (ha->optrom_state != QLA_SREADING) |
177 | return 0; | 177 | return 0; |
178 | if (off > ha->optrom_size) | 178 | if (off > ha->optrom_region_size) |
179 | return 0; | 179 | return 0; |
180 | if (off + count > ha->optrom_size) | 180 | if (off + count > ha->optrom_region_size) |
181 | count = ha->optrom_size - off; | 181 | count = ha->optrom_region_size - off; |
182 | 182 | ||
183 | memcpy(buf, &ha->optrom_buffer[off], count); | 183 | memcpy(buf, &ha->optrom_buffer[off], count); |
184 | 184 | ||
@@ -190,15 +190,15 @@ qla2x00_sysfs_write_optrom(struct kobject *kobj, | |||
190 | struct bin_attribute *bin_attr, | 190 | struct bin_attribute *bin_attr, |
191 | char *buf, loff_t off, size_t count) | 191 | char *buf, loff_t off, size_t count) |
192 | { | 192 | { |
193 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | 193 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
194 | struct device, kobj))); | 194 | struct device, kobj))); |
195 | 195 | ||
196 | if (ha->optrom_state != QLA_SWRITING) | 196 | if (ha->optrom_state != QLA_SWRITING) |
197 | return -EINVAL; | 197 | return -EINVAL; |
198 | if (off > ha->optrom_size) | 198 | if (off > ha->optrom_region_size) |
199 | return -ERANGE; | 199 | return -ERANGE; |
200 | if (off + count > ha->optrom_size) | 200 | if (off + count > ha->optrom_region_size) |
201 | count = ha->optrom_size - off; | 201 | count = ha->optrom_region_size - off; |
202 | 202 | ||
203 | memcpy(&ha->optrom_buffer[off], buf, count); | 203 | memcpy(&ha->optrom_buffer[off], buf, count); |
204 | 204 | ||
@@ -220,14 +220,18 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, | |||
220 | struct bin_attribute *bin_attr, | 220 | struct bin_attribute *bin_attr, |
221 | char *buf, loff_t off, size_t count) | 221 | char *buf, loff_t off, size_t count) |
222 | { | 222 | { |
223 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | 223 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
224 | struct device, kobj))); | 224 | struct device, kobj))); |
225 | int val; | 225 | uint32_t start = 0; |
226 | uint32_t size = ha->optrom_size; | ||
227 | int val, valid; | ||
226 | 228 | ||
227 | if (off) | 229 | if (off) |
228 | return 0; | 230 | return 0; |
229 | 231 | ||
230 | if (sscanf(buf, "%d", &val) != 1) | 232 | if (sscanf(buf, "%d:%x:%x", &val, &start, &size) < 1) |
233 | return -EINVAL; | ||
234 | if (start > ha->optrom_size) | ||
231 | return -EINVAL; | 235 | return -EINVAL; |
232 | 236 | ||
233 | switch (val) { | 237 | switch (val) { |
@@ -237,6 +241,11 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, | |||
237 | break; | 241 | break; |
238 | 242 | ||
239 | ha->optrom_state = QLA_SWAITING; | 243 | ha->optrom_state = QLA_SWAITING; |
244 | |||
245 | DEBUG2(qla_printk(KERN_INFO, ha, | ||
246 | "Freeing flash region allocation -- 0x%x bytes.\n", | ||
247 | ha->optrom_region_size)); | ||
248 | |||
240 | vfree(ha->optrom_buffer); | 249 | vfree(ha->optrom_buffer); |
241 | ha->optrom_buffer = NULL; | 250 | ha->optrom_buffer = NULL; |
242 | break; | 251 | break; |
@@ -244,44 +253,107 @@ qla2x00_sysfs_write_optrom_ctl(struct kobject *kobj, | |||
244 | if (ha->optrom_state != QLA_SWAITING) | 253 | if (ha->optrom_state != QLA_SWAITING) |
245 | break; | 254 | break; |
246 | 255 | ||
256 | if (start & 0xfff) { | ||
257 | qla_printk(KERN_WARNING, ha, | ||
258 | "Invalid start region 0x%x/0x%x.\n", start, size); | ||
259 | return -EINVAL; | ||
260 | } | ||
261 | |||
262 | ha->optrom_region_start = start; | ||
263 | ha->optrom_region_size = start + size > ha->optrom_size ? | ||
264 | ha->optrom_size - start : size; | ||
265 | |||
247 | ha->optrom_state = QLA_SREADING; | 266 | ha->optrom_state = QLA_SREADING; |
248 | ha->optrom_buffer = (uint8_t *)vmalloc(ha->optrom_size); | 267 | ha->optrom_buffer = vmalloc(ha->optrom_region_size); |
249 | if (ha->optrom_buffer == NULL) { | 268 | if (ha->optrom_buffer == NULL) { |
250 | qla_printk(KERN_WARNING, ha, | 269 | qla_printk(KERN_WARNING, ha, |
251 | "Unable to allocate memory for optrom retrieval " | 270 | "Unable to allocate memory for optrom retrieval " |
252 | "(%x).\n", ha->optrom_size); | 271 | "(%x).\n", ha->optrom_region_size); |
253 | 272 | ||
254 | ha->optrom_state = QLA_SWAITING; | 273 | ha->optrom_state = QLA_SWAITING; |
255 | return count; | 274 | return count; |
256 | } | 275 | } |
257 | 276 | ||
258 | memset(ha->optrom_buffer, 0, ha->optrom_size); | 277 | DEBUG2(qla_printk(KERN_INFO, ha, |
259 | ha->isp_ops->read_optrom(ha, ha->optrom_buffer, 0, | 278 | "Reading flash region -- 0x%x/0x%x.\n", |
260 | ha->optrom_size); | 279 | ha->optrom_region_start, ha->optrom_region_size)); |
280 | |||
281 | memset(ha->optrom_buffer, 0, ha->optrom_region_size); | ||
282 | ha->isp_ops->read_optrom(ha, ha->optrom_buffer, | ||
283 | ha->optrom_region_start, ha->optrom_region_size); | ||
261 | break; | 284 | break; |
262 | case 2: | 285 | case 2: |
263 | if (ha->optrom_state != QLA_SWAITING) | 286 | if (ha->optrom_state != QLA_SWAITING) |
264 | break; | 287 | break; |
265 | 288 | ||
289 | /* | ||
290 | * We need to be more restrictive on which FLASH regions are | ||
291 | * allowed to be updated via user-space. Regions accessible | ||
292 | * via this method include: | ||
293 | * | ||
294 | * ISP21xx/ISP22xx/ISP23xx type boards: | ||
295 | * | ||
296 | * 0x000000 -> 0x020000 -- Boot code. | ||
297 | * | ||
298 | * ISP2322/ISP24xx type boards: | ||
299 | * | ||
300 | * 0x000000 -> 0x07ffff -- Boot code. | ||
301 | * 0x080000 -> 0x0fffff -- Firmware. | ||
302 | * | ||
303 | * ISP25xx type boards: | ||
304 | * | ||
305 | * 0x000000 -> 0x07ffff -- Boot code. | ||
306 | * 0x080000 -> 0x0fffff -- Firmware. | ||
307 | * 0x120000 -> 0x12ffff -- VPD and HBA parameters. | ||
308 | */ | ||
309 | valid = 0; | ||
310 | if (ha->optrom_size == OPTROM_SIZE_2300 && start == 0) | ||
311 | valid = 1; | ||
312 | else if (start == (FA_BOOT_CODE_ADDR*4) || | ||
313 | start == (FA_RISC_CODE_ADDR*4)) | ||
314 | valid = 1; | ||
315 | else if (IS_QLA25XX(ha) && start == (FA_VPD_NVRAM_ADDR*4)) | ||
316 | valid = 1; | ||
317 | if (!valid) { | ||
318 | qla_printk(KERN_WARNING, ha, | ||
319 | "Invalid start region 0x%x/0x%x.\n", start, size); | ||
320 | return -EINVAL; | ||
321 | } | ||
322 | |||
323 | ha->optrom_region_start = start; | ||
324 | ha->optrom_region_size = start + size > ha->optrom_size ? | ||
325 | ha->optrom_size - start : size; | ||
326 | |||
266 | ha->optrom_state = QLA_SWRITING; | 327 | ha->optrom_state = QLA_SWRITING; |
267 | ha->optrom_buffer = (uint8_t *)vmalloc(ha->optrom_size); | 328 | ha->optrom_buffer = vmalloc(ha->optrom_region_size); |
268 | if (ha->optrom_buffer == NULL) { | 329 | if (ha->optrom_buffer == NULL) { |
269 | qla_printk(KERN_WARNING, ha, | 330 | qla_printk(KERN_WARNING, ha, |
270 | "Unable to allocate memory for optrom update " | 331 | "Unable to allocate memory for optrom update " |
271 | "(%x).\n", ha->optrom_size); | 332 | "(%x).\n", ha->optrom_region_size); |
272 | 333 | ||
273 | ha->optrom_state = QLA_SWAITING; | 334 | ha->optrom_state = QLA_SWAITING; |
274 | return count; | 335 | return count; |
275 | } | 336 | } |
276 | memset(ha->optrom_buffer, 0, ha->optrom_size); | 337 | |
338 | DEBUG2(qla_printk(KERN_INFO, ha, | ||
339 | "Staging flash region write -- 0x%x/0x%x.\n", | ||
340 | ha->optrom_region_start, ha->optrom_region_size)); | ||
341 | |||
342 | memset(ha->optrom_buffer, 0, ha->optrom_region_size); | ||
277 | break; | 343 | break; |
278 | case 3: | 344 | case 3: |
279 | if (ha->optrom_state != QLA_SWRITING) | 345 | if (ha->optrom_state != QLA_SWRITING) |
280 | break; | 346 | break; |
281 | 347 | ||
282 | ha->isp_ops->write_optrom(ha, ha->optrom_buffer, 0, | 348 | DEBUG2(qla_printk(KERN_INFO, ha, |
283 | ha->optrom_size); | 349 | "Writing flash region -- 0x%x/0x%x.\n", |
350 | ha->optrom_region_start, ha->optrom_region_size)); | ||
351 | |||
352 | ha->isp_ops->write_optrom(ha, ha->optrom_buffer, | ||
353 | ha->optrom_region_start, ha->optrom_region_size); | ||
284 | break; | 354 | break; |
355 | default: | ||
356 | count = -EINVAL; | ||
285 | } | 357 | } |
286 | return count; | 358 | return count; |
287 | } | 359 | } |
@@ -300,7 +372,7 @@ qla2x00_sysfs_read_vpd(struct kobject *kobj, | |||
300 | struct bin_attribute *bin_attr, | 372 | struct bin_attribute *bin_attr, |
301 | char *buf, loff_t off, size_t count) | 373 | char *buf, loff_t off, size_t count) |
302 | { | 374 | { |
303 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | 375 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
304 | struct device, kobj))); | 376 | struct device, kobj))); |
305 | int size = ha->vpd_size; | 377 | int size = ha->vpd_size; |
306 | char *vpd_cache = ha->vpd; | 378 | char *vpd_cache = ha->vpd; |
@@ -323,7 +395,7 @@ qla2x00_sysfs_write_vpd(struct kobject *kobj, | |||
323 | struct bin_attribute *bin_attr, | 395 | struct bin_attribute *bin_attr, |
324 | char *buf, loff_t off, size_t count) | 396 | char *buf, loff_t off, size_t count) |
325 | { | 397 | { |
326 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | 398 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
327 | struct device, kobj))); | 399 | struct device, kobj))); |
328 | unsigned long flags; | 400 | unsigned long flags; |
329 | 401 | ||
@@ -354,7 +426,7 @@ qla2x00_sysfs_read_sfp(struct kobject *kobj, | |||
354 | struct bin_attribute *bin_attr, | 426 | struct bin_attribute *bin_attr, |
355 | char *buf, loff_t off, size_t count) | 427 | char *buf, loff_t off, size_t count) |
356 | { | 428 | { |
357 | struct scsi_qla_host *ha = to_qla_host(dev_to_shost(container_of(kobj, | 429 | struct scsi_qla_host *ha = shost_priv(dev_to_shost(container_of(kobj, |
358 | struct device, kobj))); | 430 | struct device, kobj))); |
359 | uint16_t iter, addr, offset; | 431 | uint16_t iter, addr, offset; |
360 | int rval; | 432 | int rval; |
@@ -459,7 +531,7 @@ qla2x00_drvr_version_show(struct class_device *cdev, char *buf) | |||
459 | static ssize_t | 531 | static ssize_t |
460 | qla2x00_fw_version_show(struct class_device *cdev, char *buf) | 532 | qla2x00_fw_version_show(struct class_device *cdev, char *buf) |
461 | { | 533 | { |
462 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 534 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
463 | char fw_str[30]; | 535 | char fw_str[30]; |
464 | 536 | ||
465 | return snprintf(buf, PAGE_SIZE, "%s\n", | 537 | return snprintf(buf, PAGE_SIZE, "%s\n", |
@@ -469,7 +541,7 @@ qla2x00_fw_version_show(struct class_device *cdev, char *buf) | |||
469 | static ssize_t | 541 | static ssize_t |
470 | qla2x00_serial_num_show(struct class_device *cdev, char *buf) | 542 | qla2x00_serial_num_show(struct class_device *cdev, char *buf) |
471 | { | 543 | { |
472 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 544 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
473 | uint32_t sn; | 545 | uint32_t sn; |
474 | 546 | ||
475 | sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; | 547 | sn = ((ha->serial0 & 0x1f) << 16) | (ha->serial2 << 8) | ha->serial1; |
@@ -480,14 +552,14 @@ qla2x00_serial_num_show(struct class_device *cdev, char *buf) | |||
480 | static ssize_t | 552 | static ssize_t |
481 | qla2x00_isp_name_show(struct class_device *cdev, char *buf) | 553 | qla2x00_isp_name_show(struct class_device *cdev, char *buf) |
482 | { | 554 | { |
483 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 555 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
484 | return snprintf(buf, PAGE_SIZE, "ISP%04X\n", ha->pdev->device); | 556 | return snprintf(buf, PAGE_SIZE, "ISP%04X\n", ha->pdev->device); |
485 | } | 557 | } |
486 | 558 | ||
487 | static ssize_t | 559 | static ssize_t |
488 | qla2x00_isp_id_show(struct class_device *cdev, char *buf) | 560 | qla2x00_isp_id_show(struct class_device *cdev, char *buf) |
489 | { | 561 | { |
490 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 562 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
491 | return snprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n", | 563 | return snprintf(buf, PAGE_SIZE, "%04x %04x %04x %04x\n", |
492 | ha->product_id[0], ha->product_id[1], ha->product_id[2], | 564 | ha->product_id[0], ha->product_id[1], ha->product_id[2], |
493 | ha->product_id[3]); | 565 | ha->product_id[3]); |
@@ -496,14 +568,14 @@ qla2x00_isp_id_show(struct class_device *cdev, char *buf) | |||
496 | static ssize_t | 568 | static ssize_t |
497 | qla2x00_model_name_show(struct class_device *cdev, char *buf) | 569 | qla2x00_model_name_show(struct class_device *cdev, char *buf) |
498 | { | 570 | { |
499 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 571 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
500 | return snprintf(buf, PAGE_SIZE, "%s\n", ha->model_number); | 572 | return snprintf(buf, PAGE_SIZE, "%s\n", ha->model_number); |
501 | } | 573 | } |
502 | 574 | ||
503 | static ssize_t | 575 | static ssize_t |
504 | qla2x00_model_desc_show(struct class_device *cdev, char *buf) | 576 | qla2x00_model_desc_show(struct class_device *cdev, char *buf) |
505 | { | 577 | { |
506 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 578 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
507 | return snprintf(buf, PAGE_SIZE, "%s\n", | 579 | return snprintf(buf, PAGE_SIZE, "%s\n", |
508 | ha->model_desc ? ha->model_desc: ""); | 580 | ha->model_desc ? ha->model_desc: ""); |
509 | } | 581 | } |
@@ -511,7 +583,7 @@ qla2x00_model_desc_show(struct class_device *cdev, char *buf) | |||
511 | static ssize_t | 583 | static ssize_t |
512 | qla2x00_pci_info_show(struct class_device *cdev, char *buf) | 584 | qla2x00_pci_info_show(struct class_device *cdev, char *buf) |
513 | { | 585 | { |
514 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 586 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
515 | char pci_info[30]; | 587 | char pci_info[30]; |
516 | 588 | ||
517 | return snprintf(buf, PAGE_SIZE, "%s\n", | 589 | return snprintf(buf, PAGE_SIZE, "%s\n", |
@@ -521,7 +593,7 @@ qla2x00_pci_info_show(struct class_device *cdev, char *buf) | |||
521 | static ssize_t | 593 | static ssize_t |
522 | qla2x00_state_show(struct class_device *cdev, char *buf) | 594 | qla2x00_state_show(struct class_device *cdev, char *buf) |
523 | { | 595 | { |
524 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 596 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
525 | int len = 0; | 597 | int len = 0; |
526 | 598 | ||
527 | if (atomic_read(&ha->loop_state) == LOOP_DOWN || | 599 | if (atomic_read(&ha->loop_state) == LOOP_DOWN || |
@@ -559,7 +631,7 @@ qla2x00_state_show(struct class_device *cdev, char *buf) | |||
559 | static ssize_t | 631 | static ssize_t |
560 | qla2x00_zio_show(struct class_device *cdev, char *buf) | 632 | qla2x00_zio_show(struct class_device *cdev, char *buf) |
561 | { | 633 | { |
562 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 634 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
563 | int len = 0; | 635 | int len = 0; |
564 | 636 | ||
565 | switch (ha->zio_mode) { | 637 | switch (ha->zio_mode) { |
@@ -576,7 +648,7 @@ qla2x00_zio_show(struct class_device *cdev, char *buf) | |||
576 | static ssize_t | 648 | static ssize_t |
577 | qla2x00_zio_store(struct class_device *cdev, const char *buf, size_t count) | 649 | qla2x00_zio_store(struct class_device *cdev, const char *buf, size_t count) |
578 | { | 650 | { |
579 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 651 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
580 | int val = 0; | 652 | int val = 0; |
581 | uint16_t zio_mode; | 653 | uint16_t zio_mode; |
582 | 654 | ||
@@ -602,7 +674,7 @@ qla2x00_zio_store(struct class_device *cdev, const char *buf, size_t count) | |||
602 | static ssize_t | 674 | static ssize_t |
603 | qla2x00_zio_timer_show(struct class_device *cdev, char *buf) | 675 | qla2x00_zio_timer_show(struct class_device *cdev, char *buf) |
604 | { | 676 | { |
605 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 677 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
606 | 678 | ||
607 | return snprintf(buf, PAGE_SIZE, "%d us\n", ha->zio_timer * 100); | 679 | return snprintf(buf, PAGE_SIZE, "%d us\n", ha->zio_timer * 100); |
608 | } | 680 | } |
@@ -611,7 +683,7 @@ static ssize_t | |||
611 | qla2x00_zio_timer_store(struct class_device *cdev, const char *buf, | 683 | qla2x00_zio_timer_store(struct class_device *cdev, const char *buf, |
612 | size_t count) | 684 | size_t count) |
613 | { | 685 | { |
614 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 686 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
615 | int val = 0; | 687 | int val = 0; |
616 | uint16_t zio_timer; | 688 | uint16_t zio_timer; |
617 | 689 | ||
@@ -629,7 +701,7 @@ qla2x00_zio_timer_store(struct class_device *cdev, const char *buf, | |||
629 | static ssize_t | 701 | static ssize_t |
630 | qla2x00_beacon_show(struct class_device *cdev, char *buf) | 702 | qla2x00_beacon_show(struct class_device *cdev, char *buf) |
631 | { | 703 | { |
632 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 704 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
633 | int len = 0; | 705 | int len = 0; |
634 | 706 | ||
635 | if (ha->beacon_blink_led) | 707 | if (ha->beacon_blink_led) |
@@ -643,7 +715,7 @@ static ssize_t | |||
643 | qla2x00_beacon_store(struct class_device *cdev, const char *buf, | 715 | qla2x00_beacon_store(struct class_device *cdev, const char *buf, |
644 | size_t count) | 716 | size_t count) |
645 | { | 717 | { |
646 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 718 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
647 | int val = 0; | 719 | int val = 0; |
648 | int rval; | 720 | int rval; |
649 | 721 | ||
@@ -673,7 +745,7 @@ qla2x00_beacon_store(struct class_device *cdev, const char *buf, | |||
673 | static ssize_t | 745 | static ssize_t |
674 | qla2x00_optrom_bios_version_show(struct class_device *cdev, char *buf) | 746 | qla2x00_optrom_bios_version_show(struct class_device *cdev, char *buf) |
675 | { | 747 | { |
676 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 748 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
677 | 749 | ||
678 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1], | 750 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->bios_revision[1], |
679 | ha->bios_revision[0]); | 751 | ha->bios_revision[0]); |
@@ -682,7 +754,7 @@ qla2x00_optrom_bios_version_show(struct class_device *cdev, char *buf) | |||
682 | static ssize_t | 754 | static ssize_t |
683 | qla2x00_optrom_efi_version_show(struct class_device *cdev, char *buf) | 755 | qla2x00_optrom_efi_version_show(struct class_device *cdev, char *buf) |
684 | { | 756 | { |
685 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 757 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
686 | 758 | ||
687 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1], | 759 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->efi_revision[1], |
688 | ha->efi_revision[0]); | 760 | ha->efi_revision[0]); |
@@ -691,7 +763,7 @@ qla2x00_optrom_efi_version_show(struct class_device *cdev, char *buf) | |||
691 | static ssize_t | 763 | static ssize_t |
692 | qla2x00_optrom_fcode_version_show(struct class_device *cdev, char *buf) | 764 | qla2x00_optrom_fcode_version_show(struct class_device *cdev, char *buf) |
693 | { | 765 | { |
694 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 766 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
695 | 767 | ||
696 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1], | 768 | return snprintf(buf, PAGE_SIZE, "%d.%02d\n", ha->fcode_revision[1], |
697 | ha->fcode_revision[0]); | 769 | ha->fcode_revision[0]); |
@@ -700,7 +772,7 @@ qla2x00_optrom_fcode_version_show(struct class_device *cdev, char *buf) | |||
700 | static ssize_t | 772 | static ssize_t |
701 | qla2x00_optrom_fw_version_show(struct class_device *cdev, char *buf) | 773 | qla2x00_optrom_fw_version_show(struct class_device *cdev, char *buf) |
702 | { | 774 | { |
703 | scsi_qla_host_t *ha = to_qla_host(class_to_shost(cdev)); | 775 | scsi_qla_host_t *ha = shost_priv(class_to_shost(cdev)); |
704 | 776 | ||
705 | return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n", | 777 | return snprintf(buf, PAGE_SIZE, "%d.%02d.%02d %d\n", |
706 | ha->fw_revision[0], ha->fw_revision[1], ha->fw_revision[2], | 778 | ha->fw_revision[0], ha->fw_revision[1], ha->fw_revision[2], |
@@ -757,7 +829,7 @@ struct class_device_attribute *qla2x00_host_attrs[] = { | |||
757 | static void | 829 | static void |
758 | qla2x00_get_host_port_id(struct Scsi_Host *shost) | 830 | qla2x00_get_host_port_id(struct Scsi_Host *shost) |
759 | { | 831 | { |
760 | scsi_qla_host_t *ha = to_qla_host(shost); | 832 | scsi_qla_host_t *ha = shost_priv(shost); |
761 | 833 | ||
762 | fc_host_port_id(shost) = ha->d_id.b.domain << 16 | | 834 | fc_host_port_id(shost) = ha->d_id.b.domain << 16 | |
763 | ha->d_id.b.area << 8 | ha->d_id.b.al_pa; | 835 | ha->d_id.b.area << 8 | ha->d_id.b.al_pa; |
@@ -766,7 +838,7 @@ qla2x00_get_host_port_id(struct Scsi_Host *shost) | |||
766 | static void | 838 | static void |
767 | qla2x00_get_host_speed(struct Scsi_Host *shost) | 839 | qla2x00_get_host_speed(struct Scsi_Host *shost) |
768 | { | 840 | { |
769 | scsi_qla_host_t *ha = to_qla_host(shost); | 841 | scsi_qla_host_t *ha = shost_priv(shost); |
770 | uint32_t speed = 0; | 842 | uint32_t speed = 0; |
771 | 843 | ||
772 | switch (ha->link_data_rate) { | 844 | switch (ha->link_data_rate) { |
@@ -786,7 +858,7 @@ qla2x00_get_host_speed(struct Scsi_Host *shost) | |||
786 | static void | 858 | static void |
787 | qla2x00_get_host_port_type(struct Scsi_Host *shost) | 859 | qla2x00_get_host_port_type(struct Scsi_Host *shost) |
788 | { | 860 | { |
789 | scsi_qla_host_t *ha = to_qla_host(shost); | 861 | scsi_qla_host_t *ha = shost_priv(shost); |
790 | uint32_t port_type = FC_PORTTYPE_UNKNOWN; | 862 | uint32_t port_type = FC_PORTTYPE_UNKNOWN; |
791 | 863 | ||
792 | switch (ha->current_topology) { | 864 | switch (ha->current_topology) { |
@@ -810,7 +882,7 @@ static void | |||
810 | qla2x00_get_starget_node_name(struct scsi_target *starget) | 882 | qla2x00_get_starget_node_name(struct scsi_target *starget) |
811 | { | 883 | { |
812 | struct Scsi_Host *host = dev_to_shost(starget->dev.parent); | 884 | struct Scsi_Host *host = dev_to_shost(starget->dev.parent); |
813 | scsi_qla_host_t *ha = to_qla_host(host); | 885 | scsi_qla_host_t *ha = shost_priv(host); |
814 | fc_port_t *fcport; | 886 | fc_port_t *fcport; |
815 | u64 node_name = 0; | 887 | u64 node_name = 0; |
816 | 888 | ||
@@ -828,7 +900,7 @@ static void | |||
828 | qla2x00_get_starget_port_name(struct scsi_target *starget) | 900 | qla2x00_get_starget_port_name(struct scsi_target *starget) |
829 | { | 901 | { |
830 | struct Scsi_Host *host = dev_to_shost(starget->dev.parent); | 902 | struct Scsi_Host *host = dev_to_shost(starget->dev.parent); |
831 | scsi_qla_host_t *ha = to_qla_host(host); | 903 | scsi_qla_host_t *ha = shost_priv(host); |
832 | fc_port_t *fcport; | 904 | fc_port_t *fcport; |
833 | u64 port_name = 0; | 905 | u64 port_name = 0; |
834 | 906 | ||
@@ -846,7 +918,7 @@ static void | |||
846 | qla2x00_get_starget_port_id(struct scsi_target *starget) | 918 | qla2x00_get_starget_port_id(struct scsi_target *starget) |
847 | { | 919 | { |
848 | struct Scsi_Host *host = dev_to_shost(starget->dev.parent); | 920 | struct Scsi_Host *host = dev_to_shost(starget->dev.parent); |
849 | scsi_qla_host_t *ha = to_qla_host(host); | 921 | scsi_qla_host_t *ha = shost_priv(host); |
850 | fc_port_t *fcport; | 922 | fc_port_t *fcport; |
851 | uint32_t port_id = ~0U; | 923 | uint32_t port_id = ~0U; |
852 | 924 | ||
@@ -865,7 +937,7 @@ static void | |||
865 | qla2x00_get_rport_loss_tmo(struct fc_rport *rport) | 937 | qla2x00_get_rport_loss_tmo(struct fc_rport *rport) |
866 | { | 938 | { |
867 | struct Scsi_Host *host = rport_to_shost(rport); | 939 | struct Scsi_Host *host = rport_to_shost(rport); |
868 | scsi_qla_host_t *ha = to_qla_host(host); | 940 | scsi_qla_host_t *ha = shost_priv(host); |
869 | 941 | ||
870 | rport->dev_loss_tmo = ha->port_down_retry_count + 5; | 942 | rport->dev_loss_tmo = ha->port_down_retry_count + 5; |
871 | } | 943 | } |
@@ -874,7 +946,7 @@ static void | |||
874 | qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) | 946 | qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) |
875 | { | 947 | { |
876 | struct Scsi_Host *host = rport_to_shost(rport); | 948 | struct Scsi_Host *host = rport_to_shost(rport); |
877 | scsi_qla_host_t *ha = to_qla_host(host); | 949 | scsi_qla_host_t *ha = shost_priv(host); |
878 | 950 | ||
879 | if (timeout) | 951 | if (timeout) |
880 | ha->port_down_retry_count = timeout; | 952 | ha->port_down_retry_count = timeout; |
@@ -887,7 +959,7 @@ qla2x00_set_rport_loss_tmo(struct fc_rport *rport, uint32_t timeout) | |||
887 | static int | 959 | static int |
888 | qla2x00_issue_lip(struct Scsi_Host *shost) | 960 | qla2x00_issue_lip(struct Scsi_Host *shost) |
889 | { | 961 | { |
890 | scsi_qla_host_t *ha = to_qla_host(shost); | 962 | scsi_qla_host_t *ha = shost_priv(shost); |
891 | 963 | ||
892 | set_bit(LOOP_RESET_NEEDED, &ha->dpc_flags); | 964 | set_bit(LOOP_RESET_NEEDED, &ha->dpc_flags); |
893 | return 0; | 965 | return 0; |
@@ -896,7 +968,7 @@ qla2x00_issue_lip(struct Scsi_Host *shost) | |||
896 | static struct fc_host_statistics * | 968 | static struct fc_host_statistics * |
897 | qla2x00_get_fc_host_stats(struct Scsi_Host *shost) | 969 | qla2x00_get_fc_host_stats(struct Scsi_Host *shost) |
898 | { | 970 | { |
899 | scsi_qla_host_t *ha = to_qla_host(shost); | 971 | scsi_qla_host_t *ha = shost_priv(shost); |
900 | int rval; | 972 | int rval; |
901 | uint16_t mb_stat[1]; | 973 | uint16_t mb_stat[1]; |
902 | link_stat_t stat_buf; | 974 | link_stat_t stat_buf; |
@@ -934,7 +1006,7 @@ done: | |||
934 | static void | 1006 | static void |
935 | qla2x00_get_host_symbolic_name(struct Scsi_Host *shost) | 1007 | qla2x00_get_host_symbolic_name(struct Scsi_Host *shost) |
936 | { | 1008 | { |
937 | scsi_qla_host_t *ha = to_qla_host(shost); | 1009 | scsi_qla_host_t *ha = shost_priv(shost); |
938 | 1010 | ||
939 | qla2x00_get_sym_node_name(ha, fc_host_symbolic_name(shost)); | 1011 | qla2x00_get_sym_node_name(ha, fc_host_symbolic_name(shost)); |
940 | } | 1012 | } |
@@ -942,7 +1014,7 @@ qla2x00_get_host_symbolic_name(struct Scsi_Host *shost) | |||
942 | static void | 1014 | static void |
943 | qla2x00_set_host_system_hostname(struct Scsi_Host *shost) | 1015 | qla2x00_set_host_system_hostname(struct Scsi_Host *shost) |
944 | { | 1016 | { |
945 | scsi_qla_host_t *ha = to_qla_host(shost); | 1017 | scsi_qla_host_t *ha = shost_priv(shost); |
946 | 1018 | ||
947 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); | 1019 | set_bit(REGISTER_FDMI_NEEDED, &ha->dpc_flags); |
948 | } | 1020 | } |
@@ -950,7 +1022,7 @@ qla2x00_set_host_system_hostname(struct Scsi_Host *shost) | |||
950 | static void | 1022 | static void |
951 | qla2x00_get_host_fabric_name(struct Scsi_Host *shost) | 1023 | qla2x00_get_host_fabric_name(struct Scsi_Host *shost) |
952 | { | 1024 | { |
953 | scsi_qla_host_t *ha = to_qla_host(shost); | 1025 | scsi_qla_host_t *ha = shost_priv(shost); |
954 | u64 node_name; | 1026 | u64 node_name; |
955 | 1027 | ||
956 | if (ha->device_flags & SWITCH_FOUND) | 1028 | if (ha->device_flags & SWITCH_FOUND) |
@@ -964,7 +1036,7 @@ qla2x00_get_host_fabric_name(struct Scsi_Host *shost) | |||
964 | static void | 1036 | static void |
965 | qla2x00_get_host_port_state(struct Scsi_Host *shost) | 1037 | qla2x00_get_host_port_state(struct Scsi_Host *shost) |
966 | { | 1038 | { |
967 | scsi_qla_host_t *ha = to_qla_host(shost); | 1039 | scsi_qla_host_t *ha = shost_priv(shost); |
968 | 1040 | ||
969 | if (!ha->flags.online) | 1041 | if (!ha->flags.online) |
970 | fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; | 1042 | fc_host_port_state(shost) = FC_PORTSTATE_OFFLINE; |
@@ -978,7 +1050,7 @@ static int | |||
978 | qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) | 1050 | qla24xx_vport_create(struct fc_vport *fc_vport, bool disable) |
979 | { | 1051 | { |
980 | int ret = 0; | 1052 | int ret = 0; |
981 | scsi_qla_host_t *ha = (scsi_qla_host_t *) fc_vport->shost->hostdata; | 1053 | scsi_qla_host_t *ha = shost_priv(fc_vport->shost); |
982 | scsi_qla_host_t *vha; | 1054 | scsi_qla_host_t *vha; |
983 | 1055 | ||
984 | ret = qla24xx_vport_create_req_sanity_check(fc_vport); | 1056 | ret = qla24xx_vport_create_req_sanity_check(fc_vport); |
@@ -1047,7 +1119,7 @@ vport_create_failed_2: | |||
1047 | int | 1119 | int |
1048 | qla24xx_vport_delete(struct fc_vport *fc_vport) | 1120 | qla24xx_vport_delete(struct fc_vport *fc_vport) |
1049 | { | 1121 | { |
1050 | scsi_qla_host_t *ha = (scsi_qla_host_t *) fc_vport->shost->hostdata; | 1122 | scsi_qla_host_t *ha = shost_priv(fc_vport->shost); |
1051 | scsi_qla_host_t *vha = fc_vport->dd_data; | 1123 | scsi_qla_host_t *vha = fc_vport->dd_data; |
1052 | 1124 | ||
1053 | qla24xx_disable_vp(vha); | 1125 | qla24xx_disable_vp(vha); |
@@ -1178,6 +1250,6 @@ qla2x00_init_host_attr(scsi_qla_host_t *ha) | |||
1178 | fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name); | 1250 | fc_host_node_name(ha->host) = wwn_to_u64(ha->node_name); |
1179 | fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name); | 1251 | fc_host_port_name(ha->host) = wwn_to_u64(ha->port_name); |
1180 | fc_host_supported_classes(ha->host) = FC_COS_CLASS3; | 1252 | fc_host_supported_classes(ha->host) = FC_COS_CLASS3; |
1181 | fc_host_max_npiv_vports(ha->host) = MAX_NUM_VPORT_FABRIC; | 1253 | fc_host_max_npiv_vports(ha->host) = ha->max_npiv_vports;; |
1182 | fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count; | 1254 | fc_host_npiv_vports_inuse(ha->host) = ha->cur_vport_count; |
1183 | } | 1255 | } |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.c b/drivers/scsi/qla2xxx/qla_dbg.c index c6680348b648..eaa04dabcdf6 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.c +++ b/drivers/scsi/qla2xxx/qla_dbg.c | |||
@@ -38,7 +38,7 @@ qla2xxx_copy_queues(scsi_qla_host_t *ha, void *ptr) | |||
38 | } | 38 | } |
39 | 39 | ||
40 | static int | 40 | static int |
41 | qla2xxx_dump_memory(scsi_qla_host_t *ha, uint32_t *code_ram, | 41 | qla24xx_dump_memory(scsi_qla_host_t *ha, uint32_t *code_ram, |
42 | uint32_t cram_size, uint32_t *ext_mem, void **nxt) | 42 | uint32_t cram_size, uint32_t *ext_mem, void **nxt) |
43 | { | 43 | { |
44 | int rval; | 44 | int rval; |
@@ -152,6 +152,103 @@ qla2xxx_dump_memory(scsi_qla_host_t *ha, uint32_t *code_ram, | |||
152 | return rval; | 152 | return rval; |
153 | } | 153 | } |
154 | 154 | ||
155 | static uint32_t * | ||
156 | qla24xx_read_window(struct device_reg_24xx __iomem *reg, uint32_t iobase, | ||
157 | uint32_t count, uint32_t *buf) | ||
158 | { | ||
159 | uint32_t __iomem *dmp_reg; | ||
160 | |||
161 | WRT_REG_DWORD(®->iobase_addr, iobase); | ||
162 | dmp_reg = ®->iobase_window; | ||
163 | while (count--) | ||
164 | *buf++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
165 | |||
166 | return buf; | ||
167 | } | ||
168 | |||
169 | static inline int | ||
170 | qla24xx_pause_risc(struct device_reg_24xx __iomem *reg) | ||
171 | { | ||
172 | int rval = QLA_SUCCESS; | ||
173 | uint32_t cnt; | ||
174 | |||
175 | if (RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) | ||
176 | return rval; | ||
177 | |||
178 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE); | ||
179 | for (cnt = 30000; (RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0 && | ||
180 | rval == QLA_SUCCESS; cnt--) { | ||
181 | if (cnt) | ||
182 | udelay(100); | ||
183 | else | ||
184 | rval = QLA_FUNCTION_TIMEOUT; | ||
185 | } | ||
186 | |||
187 | return rval; | ||
188 | } | ||
189 | |||
190 | static int | ||
191 | qla24xx_soft_reset(scsi_qla_host_t *ha) | ||
192 | { | ||
193 | int rval = QLA_SUCCESS; | ||
194 | uint32_t cnt; | ||
195 | uint16_t mb0, wd; | ||
196 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
197 | |||
198 | /* Reset RISC. */ | ||
199 | WRT_REG_DWORD(®->ctrl_status, CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); | ||
200 | for (cnt = 0; cnt < 30000; cnt++) { | ||
201 | if ((RD_REG_DWORD(®->ctrl_status) & CSRX_DMA_ACTIVE) == 0) | ||
202 | break; | ||
203 | |||
204 | udelay(10); | ||
205 | } | ||
206 | |||
207 | WRT_REG_DWORD(®->ctrl_status, | ||
208 | CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); | ||
209 | pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); | ||
210 | |||
211 | udelay(100); | ||
212 | /* Wait for firmware to complete NVRAM accesses. */ | ||
213 | mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); | ||
214 | for (cnt = 10000 ; cnt && mb0; cnt--) { | ||
215 | udelay(5); | ||
216 | mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); | ||
217 | barrier(); | ||
218 | } | ||
219 | |||
220 | /* Wait for soft-reset to complete. */ | ||
221 | for (cnt = 0; cnt < 30000; cnt++) { | ||
222 | if ((RD_REG_DWORD(®->ctrl_status) & | ||
223 | CSRX_ISP_SOFT_RESET) == 0) | ||
224 | break; | ||
225 | |||
226 | udelay(10); | ||
227 | } | ||
228 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_RESET); | ||
229 | RD_REG_DWORD(®->hccr); /* PCI Posting. */ | ||
230 | |||
231 | for (cnt = 30000; RD_REG_WORD(®->mailbox0) != 0 && | ||
232 | rval == QLA_SUCCESS; cnt--) { | ||
233 | if (cnt) | ||
234 | udelay(100); | ||
235 | else | ||
236 | rval = QLA_FUNCTION_TIMEOUT; | ||
237 | } | ||
238 | |||
239 | return rval; | ||
240 | } | ||
241 | |||
242 | static inline void | ||
243 | qla2xxx_read_window(struct device_reg_2xxx __iomem *reg, uint32_t count, | ||
244 | uint16_t *buf) | ||
245 | { | ||
246 | uint16_t __iomem *dmp_reg = ®->u.isp2300.fb_cmd; | ||
247 | |||
248 | while (count--) | ||
249 | *buf++ = htons(RD_REG_WORD(dmp_reg++)); | ||
250 | } | ||
251 | |||
155 | /** | 252 | /** |
156 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. | 253 | * qla2300_fw_dump() - Dumps binary data from the 2300 firmware. |
157 | * @ha: HA context | 254 | * @ha: HA context |
@@ -214,88 +311,61 @@ qla2300_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
214 | } | 311 | } |
215 | 312 | ||
216 | if (rval == QLA_SUCCESS) { | 313 | if (rval == QLA_SUCCESS) { |
217 | dmp_reg = (uint16_t __iomem *)(reg + 0); | 314 | dmp_reg = ®->flash_address; |
218 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) | 315 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) |
219 | fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | 316 | fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
220 | 317 | ||
221 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); | 318 | dmp_reg = ®->u.isp2300.req_q_in; |
222 | for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++) | 319 | for (cnt = 0; cnt < sizeof(fw->risc_host_reg) / 2; cnt++) |
223 | fw->risc_host_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | 320 | fw->risc_host_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
224 | 321 | ||
225 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x40); | 322 | dmp_reg = ®->u.isp2300.mailbox0; |
226 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) | 323 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) |
227 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | 324 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
228 | 325 | ||
229 | WRT_REG_WORD(®->ctrl_status, 0x40); | 326 | WRT_REG_WORD(®->ctrl_status, 0x40); |
230 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 327 | qla2xxx_read_window(reg, 32, fw->resp_dma_reg); |
231 | for (cnt = 0; cnt < sizeof(fw->resp_dma_reg) / 2; cnt++) | ||
232 | fw->resp_dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
233 | 328 | ||
234 | WRT_REG_WORD(®->ctrl_status, 0x50); | 329 | WRT_REG_WORD(®->ctrl_status, 0x50); |
235 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 330 | qla2xxx_read_window(reg, 48, fw->dma_reg); |
236 | for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) | ||
237 | fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
238 | 331 | ||
239 | WRT_REG_WORD(®->ctrl_status, 0x00); | 332 | WRT_REG_WORD(®->ctrl_status, 0x00); |
240 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); | 333 | dmp_reg = ®->risc_hw; |
241 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) | 334 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) |
242 | fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | 335 | fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
243 | 336 | ||
244 | WRT_REG_WORD(®->pcr, 0x2000); | 337 | WRT_REG_WORD(®->pcr, 0x2000); |
245 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 338 | qla2xxx_read_window(reg, 16, fw->risc_gp0_reg); |
246 | for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) | ||
247 | fw->risc_gp0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
248 | 339 | ||
249 | WRT_REG_WORD(®->pcr, 0x2200); | 340 | WRT_REG_WORD(®->pcr, 0x2200); |
250 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 341 | qla2xxx_read_window(reg, 16, fw->risc_gp1_reg); |
251 | for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) | ||
252 | fw->risc_gp1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
253 | 342 | ||
254 | WRT_REG_WORD(®->pcr, 0x2400); | 343 | WRT_REG_WORD(®->pcr, 0x2400); |
255 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 344 | qla2xxx_read_window(reg, 16, fw->risc_gp2_reg); |
256 | for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) | ||
257 | fw->risc_gp2_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
258 | 345 | ||
259 | WRT_REG_WORD(®->pcr, 0x2600); | 346 | WRT_REG_WORD(®->pcr, 0x2600); |
260 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 347 | qla2xxx_read_window(reg, 16, fw->risc_gp3_reg); |
261 | for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) | ||
262 | fw->risc_gp3_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
263 | 348 | ||
264 | WRT_REG_WORD(®->pcr, 0x2800); | 349 | WRT_REG_WORD(®->pcr, 0x2800); |
265 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 350 | qla2xxx_read_window(reg, 16, fw->risc_gp4_reg); |
266 | for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) | ||
267 | fw->risc_gp4_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
268 | 351 | ||
269 | WRT_REG_WORD(®->pcr, 0x2A00); | 352 | WRT_REG_WORD(®->pcr, 0x2A00); |
270 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 353 | qla2xxx_read_window(reg, 16, fw->risc_gp5_reg); |
271 | for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) | ||
272 | fw->risc_gp5_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
273 | 354 | ||
274 | WRT_REG_WORD(®->pcr, 0x2C00); | 355 | WRT_REG_WORD(®->pcr, 0x2C00); |
275 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 356 | qla2xxx_read_window(reg, 16, fw->risc_gp6_reg); |
276 | for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) | ||
277 | fw->risc_gp6_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
278 | 357 | ||
279 | WRT_REG_WORD(®->pcr, 0x2E00); | 358 | WRT_REG_WORD(®->pcr, 0x2E00); |
280 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 359 | qla2xxx_read_window(reg, 16, fw->risc_gp7_reg); |
281 | for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) | ||
282 | fw->risc_gp7_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
283 | 360 | ||
284 | WRT_REG_WORD(®->ctrl_status, 0x10); | 361 | WRT_REG_WORD(®->ctrl_status, 0x10); |
285 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 362 | qla2xxx_read_window(reg, 64, fw->frame_buf_hdw_reg); |
286 | for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) | ||
287 | fw->frame_buf_hdw_reg[cnt] = | ||
288 | htons(RD_REG_WORD(dmp_reg++)); | ||
289 | 363 | ||
290 | WRT_REG_WORD(®->ctrl_status, 0x20); | 364 | WRT_REG_WORD(®->ctrl_status, 0x20); |
291 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 365 | qla2xxx_read_window(reg, 64, fw->fpm_b0_reg); |
292 | for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) | ||
293 | fw->fpm_b0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
294 | 366 | ||
295 | WRT_REG_WORD(®->ctrl_status, 0x30); | 367 | WRT_REG_WORD(®->ctrl_status, 0x30); |
296 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 368 | qla2xxx_read_window(reg, 64, fw->fpm_b1_reg); |
297 | for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) | ||
298 | fw->fpm_b1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
299 | 369 | ||
300 | /* Reset RISC. */ | 370 | /* Reset RISC. */ |
301 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); | 371 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); |
@@ -567,83 +637,59 @@ qla2100_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
567 | rval = QLA_FUNCTION_TIMEOUT; | 637 | rval = QLA_FUNCTION_TIMEOUT; |
568 | } | 638 | } |
569 | if (rval == QLA_SUCCESS) { | 639 | if (rval == QLA_SUCCESS) { |
570 | dmp_reg = (uint16_t __iomem *)(reg + 0); | 640 | dmp_reg = ®->flash_address; |
571 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) | 641 | for (cnt = 0; cnt < sizeof(fw->pbiu_reg) / 2; cnt++) |
572 | fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | 642 | fw->pbiu_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
573 | 643 | ||
574 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x10); | 644 | dmp_reg = ®->u.isp2100.mailbox0; |
575 | for (cnt = 0; cnt < ha->mbx_count; cnt++) { | 645 | for (cnt = 0; cnt < ha->mbx_count; cnt++) { |
576 | if (cnt == 8) { | 646 | if (cnt == 8) |
577 | dmp_reg = (uint16_t __iomem *) | 647 | dmp_reg = ®->u_end.isp2200.mailbox8; |
578 | ((uint8_t __iomem *)reg + 0xe0); | 648 | |
579 | } | ||
580 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | 649 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
581 | } | 650 | } |
582 | 651 | ||
583 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x20); | 652 | dmp_reg = ®->u.isp2100.unused_2[0]; |
584 | for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) | 653 | for (cnt = 0; cnt < sizeof(fw->dma_reg) / 2; cnt++) |
585 | fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | 654 | fw->dma_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
586 | 655 | ||
587 | WRT_REG_WORD(®->ctrl_status, 0x00); | 656 | WRT_REG_WORD(®->ctrl_status, 0x00); |
588 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0xA0); | 657 | dmp_reg = ®->risc_hw; |
589 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) | 658 | for (cnt = 0; cnt < sizeof(fw->risc_hdw_reg) / 2; cnt++) |
590 | fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | 659 | fw->risc_hdw_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); |
591 | 660 | ||
592 | WRT_REG_WORD(®->pcr, 0x2000); | 661 | WRT_REG_WORD(®->pcr, 0x2000); |
593 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 662 | qla2xxx_read_window(reg, 16, fw->risc_gp0_reg); |
594 | for (cnt = 0; cnt < sizeof(fw->risc_gp0_reg) / 2; cnt++) | ||
595 | fw->risc_gp0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
596 | 663 | ||
597 | WRT_REG_WORD(®->pcr, 0x2100); | 664 | WRT_REG_WORD(®->pcr, 0x2100); |
598 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 665 | qla2xxx_read_window(reg, 16, fw->risc_gp1_reg); |
599 | for (cnt = 0; cnt < sizeof(fw->risc_gp1_reg) / 2; cnt++) | ||
600 | fw->risc_gp1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
601 | 666 | ||
602 | WRT_REG_WORD(®->pcr, 0x2200); | 667 | WRT_REG_WORD(®->pcr, 0x2200); |
603 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 668 | qla2xxx_read_window(reg, 16, fw->risc_gp2_reg); |
604 | for (cnt = 0; cnt < sizeof(fw->risc_gp2_reg) / 2; cnt++) | ||
605 | fw->risc_gp2_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
606 | 669 | ||
607 | WRT_REG_WORD(®->pcr, 0x2300); | 670 | WRT_REG_WORD(®->pcr, 0x2300); |
608 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 671 | qla2xxx_read_window(reg, 16, fw->risc_gp3_reg); |
609 | for (cnt = 0; cnt < sizeof(fw->risc_gp3_reg) / 2; cnt++) | ||
610 | fw->risc_gp3_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
611 | 672 | ||
612 | WRT_REG_WORD(®->pcr, 0x2400); | 673 | WRT_REG_WORD(®->pcr, 0x2400); |
613 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 674 | qla2xxx_read_window(reg, 16, fw->risc_gp4_reg); |
614 | for (cnt = 0; cnt < sizeof(fw->risc_gp4_reg) / 2; cnt++) | ||
615 | fw->risc_gp4_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
616 | 675 | ||
617 | WRT_REG_WORD(®->pcr, 0x2500); | 676 | WRT_REG_WORD(®->pcr, 0x2500); |
618 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 677 | qla2xxx_read_window(reg, 16, fw->risc_gp5_reg); |
619 | for (cnt = 0; cnt < sizeof(fw->risc_gp5_reg) / 2; cnt++) | ||
620 | fw->risc_gp5_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
621 | 678 | ||
622 | WRT_REG_WORD(®->pcr, 0x2600); | 679 | WRT_REG_WORD(®->pcr, 0x2600); |
623 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 680 | qla2xxx_read_window(reg, 16, fw->risc_gp6_reg); |
624 | for (cnt = 0; cnt < sizeof(fw->risc_gp6_reg) / 2; cnt++) | ||
625 | fw->risc_gp6_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
626 | 681 | ||
627 | WRT_REG_WORD(®->pcr, 0x2700); | 682 | WRT_REG_WORD(®->pcr, 0x2700); |
628 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 683 | qla2xxx_read_window(reg, 16, fw->risc_gp7_reg); |
629 | for (cnt = 0; cnt < sizeof(fw->risc_gp7_reg) / 2; cnt++) | ||
630 | fw->risc_gp7_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
631 | 684 | ||
632 | WRT_REG_WORD(®->ctrl_status, 0x10); | 685 | WRT_REG_WORD(®->ctrl_status, 0x10); |
633 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 686 | qla2xxx_read_window(reg, 16, fw->frame_buf_hdw_reg); |
634 | for (cnt = 0; cnt < sizeof(fw->frame_buf_hdw_reg) / 2; cnt++) | ||
635 | fw->frame_buf_hdw_reg[cnt] = | ||
636 | htons(RD_REG_WORD(dmp_reg++)); | ||
637 | 687 | ||
638 | WRT_REG_WORD(®->ctrl_status, 0x20); | 688 | WRT_REG_WORD(®->ctrl_status, 0x20); |
639 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 689 | qla2xxx_read_window(reg, 64, fw->fpm_b0_reg); |
640 | for (cnt = 0; cnt < sizeof(fw->fpm_b0_reg) / 2; cnt++) | ||
641 | fw->fpm_b0_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
642 | 690 | ||
643 | WRT_REG_WORD(®->ctrl_status, 0x30); | 691 | WRT_REG_WORD(®->ctrl_status, 0x30); |
644 | dmp_reg = (uint16_t __iomem *)((uint8_t __iomem *)reg + 0x80); | 692 | qla2xxx_read_window(reg, 64, fw->fpm_b1_reg); |
645 | for (cnt = 0; cnt < sizeof(fw->fpm_b1_reg) / 2; cnt++) | ||
646 | fw->fpm_b1_reg[cnt] = htons(RD_REG_WORD(dmp_reg++)); | ||
647 | 693 | ||
648 | /* Reset the ISP. */ | 694 | /* Reset the ISP. */ |
649 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); | 695 | WRT_REG_WORD(®->ctrl_status, CSR_ISP_SOFT_RESET); |
@@ -750,7 +796,6 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
750 | int rval; | 796 | int rval; |
751 | uint32_t cnt; | 797 | uint32_t cnt; |
752 | uint32_t risc_address; | 798 | uint32_t risc_address; |
753 | uint16_t mb0, wd; | ||
754 | 799 | ||
755 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 800 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
756 | uint32_t __iomem *dmp_reg; | 801 | uint32_t __iomem *dmp_reg; |
@@ -782,547 +827,198 @@ qla24xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
782 | fw = &ha->fw_dump->isp.isp24; | 827 | fw = &ha->fw_dump->isp.isp24; |
783 | qla2xxx_prep_dump(ha, ha->fw_dump); | 828 | qla2xxx_prep_dump(ha, ha->fw_dump); |
784 | 829 | ||
785 | rval = QLA_SUCCESS; | ||
786 | fw->host_status = htonl(RD_REG_DWORD(®->host_status)); | 830 | fw->host_status = htonl(RD_REG_DWORD(®->host_status)); |
787 | 831 | ||
788 | /* Pause RISC. */ | 832 | /* Pause RISC. */ |
789 | if ((RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0) { | 833 | rval = qla24xx_pause_risc(reg); |
790 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET | | 834 | if (rval != QLA_SUCCESS) |
791 | HCCRX_CLR_HOST_INT); | 835 | goto qla24xx_fw_dump_failed_0; |
792 | RD_REG_DWORD(®->hccr); /* PCI Posting. */ | 836 | |
793 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE); | 837 | /* Host interface registers. */ |
794 | for (cnt = 30000; | 838 | dmp_reg = ®->flash_addr; |
795 | (RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0 && | 839 | for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) |
796 | rval == QLA_SUCCESS; cnt--) { | 840 | fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); |
797 | if (cnt) | 841 | |
798 | udelay(100); | 842 | /* Disable interrupts. */ |
799 | else | 843 | WRT_REG_DWORD(®->ictrl, 0); |
800 | rval = QLA_FUNCTION_TIMEOUT; | 844 | RD_REG_DWORD(®->ictrl); |
801 | } | 845 | |
802 | } | 846 | /* Shadow registers. */ |
803 | 847 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); | |
804 | if (rval == QLA_SUCCESS) { | 848 | RD_REG_DWORD(®->iobase_addr); |
805 | /* Host interface registers. */ | 849 | WRT_REG_DWORD(®->iobase_select, 0xB0000000); |
806 | dmp_reg = (uint32_t __iomem *)(reg + 0); | 850 | fw->shadow_reg[0] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
807 | for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) | 851 | |
808 | fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | 852 | WRT_REG_DWORD(®->iobase_select, 0xB0100000); |
809 | 853 | fw->shadow_reg[1] = htonl(RD_REG_DWORD(®->iobase_sdata)); | |
810 | /* Disable interrupts. */ | 854 | |
811 | WRT_REG_DWORD(®->ictrl, 0); | 855 | WRT_REG_DWORD(®->iobase_select, 0xB0200000); |
812 | RD_REG_DWORD(®->ictrl); | 856 | fw->shadow_reg[2] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
813 | 857 | ||
814 | /* Shadow registers. */ | 858 | WRT_REG_DWORD(®->iobase_select, 0xB0300000); |
815 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); | 859 | fw->shadow_reg[3] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
816 | RD_REG_DWORD(®->iobase_addr); | 860 | |
817 | WRT_REG_DWORD(®->iobase_select, 0xB0000000); | 861 | WRT_REG_DWORD(®->iobase_select, 0xB0400000); |
818 | fw->shadow_reg[0] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 862 | fw->shadow_reg[4] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
819 | 863 | ||
820 | WRT_REG_DWORD(®->iobase_select, 0xB0100000); | 864 | WRT_REG_DWORD(®->iobase_select, 0xB0500000); |
821 | fw->shadow_reg[1] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 865 | fw->shadow_reg[5] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
822 | 866 | ||
823 | WRT_REG_DWORD(®->iobase_select, 0xB0200000); | 867 | WRT_REG_DWORD(®->iobase_select, 0xB0600000); |
824 | fw->shadow_reg[2] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 868 | fw->shadow_reg[6] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
825 | 869 | ||
826 | WRT_REG_DWORD(®->iobase_select, 0xB0300000); | 870 | /* Mailbox registers. */ |
827 | fw->shadow_reg[3] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 871 | mbx_reg = ®->mailbox0; |
828 | 872 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) | |
829 | WRT_REG_DWORD(®->iobase_select, 0xB0400000); | 873 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); |
830 | fw->shadow_reg[4] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 874 | |
831 | 875 | /* Transfer sequence registers. */ | |
832 | WRT_REG_DWORD(®->iobase_select, 0xB0500000); | 876 | iter_reg = fw->xseq_gp_reg; |
833 | fw->shadow_reg[5] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 877 | iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg); |
834 | 878 | iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg); | |
835 | WRT_REG_DWORD(®->iobase_select, 0xB0600000); | 879 | iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg); |
836 | fw->shadow_reg[6] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 880 | iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg); |
837 | 881 | iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg); | |
838 | /* Mailbox registers. */ | 882 | iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg); |
839 | mbx_reg = ®->mailbox0; | 883 | iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg); |
840 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) | 884 | qla24xx_read_window(reg, 0xBF70, 16, iter_reg); |
841 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); | 885 | |
842 | 886 | qla24xx_read_window(reg, 0xBFE0, 16, fw->xseq_0_reg); | |
843 | /* Transfer sequence registers. */ | 887 | qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg); |
844 | iter_reg = fw->xseq_gp_reg; | 888 | |
845 | WRT_REG_DWORD(®->iobase_addr, 0xBF00); | 889 | /* Receive sequence registers. */ |
846 | dmp_reg = ®->iobase_window; | 890 | iter_reg = fw->rseq_gp_reg; |
847 | for (cnt = 0; cnt < 16; cnt++) | 891 | iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg); |
848 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 892 | iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg); |
849 | 893 | iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg); | |
850 | WRT_REG_DWORD(®->iobase_addr, 0xBF10); | 894 | iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg); |
851 | dmp_reg = ®->iobase_window; | 895 | iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg); |
852 | for (cnt = 0; cnt < 16; cnt++) | 896 | iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg); |
853 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 897 | iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg); |
854 | 898 | qla24xx_read_window(reg, 0xFF70, 16, iter_reg); | |
855 | WRT_REG_DWORD(®->iobase_addr, 0xBF20); | 899 | |
856 | dmp_reg = ®->iobase_window; | 900 | qla24xx_read_window(reg, 0xFFD0, 16, fw->rseq_0_reg); |
857 | for (cnt = 0; cnt < 16; cnt++) | 901 | qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg); |
858 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 902 | qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg); |
859 | 903 | ||
860 | WRT_REG_DWORD(®->iobase_addr, 0xBF30); | 904 | /* Command DMA registers. */ |
861 | dmp_reg = ®->iobase_window; | 905 | qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg); |
862 | for (cnt = 0; cnt < 16; cnt++) | 906 | |
863 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 907 | /* Queues. */ |
864 | 908 | iter_reg = fw->req0_dma_reg; | |
865 | WRT_REG_DWORD(®->iobase_addr, 0xBF40); | 909 | iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg); |
866 | dmp_reg = ®->iobase_window; | 910 | dmp_reg = ®->iobase_q; |
867 | for (cnt = 0; cnt < 16; cnt++) | 911 | for (cnt = 0; cnt < 7; cnt++) |
868 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 912 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
869 | 913 | ||
870 | WRT_REG_DWORD(®->iobase_addr, 0xBF50); | 914 | iter_reg = fw->resp0_dma_reg; |
871 | dmp_reg = ®->iobase_window; | 915 | iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg); |
872 | for (cnt = 0; cnt < 16; cnt++) | 916 | dmp_reg = ®->iobase_q; |
873 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 917 | for (cnt = 0; cnt < 7; cnt++) |
874 | 918 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | |
875 | WRT_REG_DWORD(®->iobase_addr, 0xBF60); | 919 | |
876 | dmp_reg = ®->iobase_window; | 920 | iter_reg = fw->req1_dma_reg; |
877 | for (cnt = 0; cnt < 16; cnt++) | 921 | iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg); |
878 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 922 | dmp_reg = ®->iobase_q; |
879 | 923 | for (cnt = 0; cnt < 7; cnt++) | |
880 | WRT_REG_DWORD(®->iobase_addr, 0xBF70); | 924 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
881 | dmp_reg = ®->iobase_window; | 925 | |
882 | for (cnt = 0; cnt < 16; cnt++) | 926 | /* Transmit DMA registers. */ |
883 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 927 | iter_reg = fw->xmt0_dma_reg; |
884 | 928 | iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg); | |
885 | WRT_REG_DWORD(®->iobase_addr, 0xBFE0); | 929 | qla24xx_read_window(reg, 0x7610, 16, iter_reg); |
886 | dmp_reg = ®->iobase_window; | 930 | |
887 | for (cnt = 0; cnt < sizeof(fw->xseq_0_reg) / 4; cnt++) | 931 | iter_reg = fw->xmt1_dma_reg; |
888 | fw->xseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | 932 | iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg); |
889 | 933 | qla24xx_read_window(reg, 0x7630, 16, iter_reg); | |
890 | WRT_REG_DWORD(®->iobase_addr, 0xBFF0); | 934 | |
891 | dmp_reg = ®->iobase_window; | 935 | iter_reg = fw->xmt2_dma_reg; |
892 | for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) | 936 | iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg); |
893 | fw->xseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | 937 | qla24xx_read_window(reg, 0x7650, 16, iter_reg); |
894 | 938 | ||
895 | /* Receive sequence registers. */ | 939 | iter_reg = fw->xmt3_dma_reg; |
896 | iter_reg = fw->rseq_gp_reg; | 940 | iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg); |
897 | WRT_REG_DWORD(®->iobase_addr, 0xFF00); | 941 | qla24xx_read_window(reg, 0x7670, 16, iter_reg); |
898 | dmp_reg = ®->iobase_window; | 942 | |
899 | for (cnt = 0; cnt < 16; cnt++) | 943 | iter_reg = fw->xmt4_dma_reg; |
900 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 944 | iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg); |
901 | 945 | qla24xx_read_window(reg, 0x7690, 16, iter_reg); | |
902 | WRT_REG_DWORD(®->iobase_addr, 0xFF10); | 946 | |
903 | dmp_reg = ®->iobase_window; | 947 | qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg); |
904 | for (cnt = 0; cnt < 16; cnt++) | 948 | |
905 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 949 | /* Receive DMA registers. */ |
906 | 950 | iter_reg = fw->rcvt0_data_dma_reg; | |
907 | WRT_REG_DWORD(®->iobase_addr, 0xFF20); | 951 | iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg); |
908 | dmp_reg = ®->iobase_window; | 952 | qla24xx_read_window(reg, 0x7710, 16, iter_reg); |
909 | for (cnt = 0; cnt < 16; cnt++) | 953 | |
910 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 954 | iter_reg = fw->rcvt1_data_dma_reg; |
911 | 955 | iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg); | |
912 | WRT_REG_DWORD(®->iobase_addr, 0xFF30); | 956 | qla24xx_read_window(reg, 0x7730, 16, iter_reg); |
913 | dmp_reg = ®->iobase_window; | 957 | |
914 | for (cnt = 0; cnt < 16; cnt++) | 958 | /* RISC registers. */ |
915 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 959 | iter_reg = fw->risc_gp_reg; |
916 | 960 | iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg); | |
917 | WRT_REG_DWORD(®->iobase_addr, 0xFF40); | 961 | iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg); |
918 | dmp_reg = ®->iobase_window; | 962 | iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg); |
919 | for (cnt = 0; cnt < 16; cnt++) | 963 | iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg); |
920 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 964 | iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg); |
921 | 965 | iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg); | |
922 | WRT_REG_DWORD(®->iobase_addr, 0xFF50); | 966 | iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg); |
923 | dmp_reg = ®->iobase_window; | 967 | qla24xx_read_window(reg, 0x0F70, 16, iter_reg); |
924 | for (cnt = 0; cnt < 16; cnt++) | 968 | |
925 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 969 | /* Local memory controller registers. */ |
926 | 970 | iter_reg = fw->lmc_reg; | |
927 | WRT_REG_DWORD(®->iobase_addr, 0xFF60); | 971 | iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg); |
928 | dmp_reg = ®->iobase_window; | 972 | iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg); |
929 | for (cnt = 0; cnt < 16; cnt++) | 973 | iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg); |
930 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 974 | iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg); |
931 | 975 | iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg); | |
932 | WRT_REG_DWORD(®->iobase_addr, 0xFF70); | 976 | iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg); |
933 | dmp_reg = ®->iobase_window; | 977 | qla24xx_read_window(reg, 0x3060, 16, iter_reg); |
934 | for (cnt = 0; cnt < 16; cnt++) | 978 | |
935 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 979 | /* Fibre Protocol Module registers. */ |
936 | 980 | iter_reg = fw->fpm_hdw_reg; | |
937 | WRT_REG_DWORD(®->iobase_addr, 0xFFD0); | 981 | iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg); |
938 | dmp_reg = ®->iobase_window; | 982 | iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg); |
939 | for (cnt = 0; cnt < sizeof(fw->rseq_0_reg) / 4; cnt++) | 983 | iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg); |
940 | fw->rseq_0_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | 984 | iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg); |
941 | 985 | iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg); | |
942 | WRT_REG_DWORD(®->iobase_addr, 0xFFE0); | 986 | iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg); |
943 | dmp_reg = ®->iobase_window; | 987 | iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg); |
944 | for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) | 988 | iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg); |
945 | fw->rseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | 989 | iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg); |
946 | 990 | iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg); | |
947 | WRT_REG_DWORD(®->iobase_addr, 0xFFF0); | 991 | iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg); |
948 | dmp_reg = ®->iobase_window; | 992 | qla24xx_read_window(reg, 0x40B0, 16, iter_reg); |
949 | for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) | 993 | |
950 | fw->rseq_2_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | 994 | /* Frame Buffer registers. */ |
951 | 995 | iter_reg = fw->fb_hdw_reg; | |
952 | /* Command DMA registers. */ | 996 | iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg); |
953 | WRT_REG_DWORD(®->iobase_addr, 0x7100); | 997 | iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg); |
954 | dmp_reg = ®->iobase_window; | 998 | iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg); |
955 | for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) | 999 | iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg); |
956 | fw->cmd_dma_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | 1000 | iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg); |
957 | 1001 | iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg); | |
958 | /* Queues. */ | 1002 | iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg); |
959 | iter_reg = fw->req0_dma_reg; | 1003 | iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg); |
960 | WRT_REG_DWORD(®->iobase_addr, 0x7200); | 1004 | iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg); |
961 | dmp_reg = ®->iobase_window; | 1005 | iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg); |
962 | for (cnt = 0; cnt < 8; cnt++) | 1006 | qla24xx_read_window(reg, 0x61B0, 16, iter_reg); |
963 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1007 | |
964 | 1008 | rval = qla24xx_soft_reset(ha); | |
965 | dmp_reg = ®->iobase_q; | 1009 | if (rval != QLA_SUCCESS) |
966 | for (cnt = 0; cnt < 7; cnt++) | 1010 | goto qla24xx_fw_dump_failed_0; |
967 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1011 | |
968 | 1012 | rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), | |
969 | iter_reg = fw->resp0_dma_reg; | 1013 | fw->ext_mem, &nxt); |
970 | WRT_REG_DWORD(®->iobase_addr, 0x7300); | 1014 | if (rval != QLA_SUCCESS) |
971 | dmp_reg = ®->iobase_window; | 1015 | goto qla24xx_fw_dump_failed_0; |
972 | for (cnt = 0; cnt < 8; cnt++) | 1016 | |
973 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1017 | nxt = qla2xxx_copy_queues(ha, nxt); |
974 | 1018 | if (ha->eft) | |
975 | dmp_reg = ®->iobase_q; | 1019 | memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); |
976 | for (cnt = 0; cnt < 7; cnt++) | 1020 | |
977 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1021 | qla24xx_fw_dump_failed_0: |
978 | |||
979 | iter_reg = fw->req1_dma_reg; | ||
980 | WRT_REG_DWORD(®->iobase_addr, 0x7400); | ||
981 | dmp_reg = ®->iobase_window; | ||
982 | for (cnt = 0; cnt < 8; cnt++) | ||
983 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
984 | |||
985 | dmp_reg = ®->iobase_q; | ||
986 | for (cnt = 0; cnt < 7; cnt++) | ||
987 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
988 | |||
989 | /* Transmit DMA registers. */ | ||
990 | iter_reg = fw->xmt0_dma_reg; | ||
991 | WRT_REG_DWORD(®->iobase_addr, 0x7600); | ||
992 | dmp_reg = ®->iobase_window; | ||
993 | for (cnt = 0; cnt < 16; cnt++) | ||
994 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
995 | |||
996 | WRT_REG_DWORD(®->iobase_addr, 0x7610); | ||
997 | dmp_reg = ®->iobase_window; | ||
998 | for (cnt = 0; cnt < 16; cnt++) | ||
999 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1000 | |||
1001 | iter_reg = fw->xmt1_dma_reg; | ||
1002 | WRT_REG_DWORD(®->iobase_addr, 0x7620); | ||
1003 | dmp_reg = ®->iobase_window; | ||
1004 | for (cnt = 0; cnt < 16; cnt++) | ||
1005 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1006 | |||
1007 | WRT_REG_DWORD(®->iobase_addr, 0x7630); | ||
1008 | dmp_reg = ®->iobase_window; | ||
1009 | for (cnt = 0; cnt < 16; cnt++) | ||
1010 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1011 | |||
1012 | iter_reg = fw->xmt2_dma_reg; | ||
1013 | WRT_REG_DWORD(®->iobase_addr, 0x7640); | ||
1014 | dmp_reg = ®->iobase_window; | ||
1015 | for (cnt = 0; cnt < 16; cnt++) | ||
1016 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1017 | |||
1018 | WRT_REG_DWORD(®->iobase_addr, 0x7650); | ||
1019 | dmp_reg = ®->iobase_window; | ||
1020 | for (cnt = 0; cnt < 16; cnt++) | ||
1021 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1022 | |||
1023 | iter_reg = fw->xmt3_dma_reg; | ||
1024 | WRT_REG_DWORD(®->iobase_addr, 0x7660); | ||
1025 | dmp_reg = ®->iobase_window; | ||
1026 | for (cnt = 0; cnt < 16; cnt++) | ||
1027 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1028 | |||
1029 | WRT_REG_DWORD(®->iobase_addr, 0x7670); | ||
1030 | dmp_reg = ®->iobase_window; | ||
1031 | for (cnt = 0; cnt < 16; cnt++) | ||
1032 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1033 | |||
1034 | iter_reg = fw->xmt4_dma_reg; | ||
1035 | WRT_REG_DWORD(®->iobase_addr, 0x7680); | ||
1036 | dmp_reg = ®->iobase_window; | ||
1037 | for (cnt = 0; cnt < 16; cnt++) | ||
1038 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1039 | |||
1040 | WRT_REG_DWORD(®->iobase_addr, 0x7690); | ||
1041 | dmp_reg = ®->iobase_window; | ||
1042 | for (cnt = 0; cnt < 16; cnt++) | ||
1043 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1044 | |||
1045 | WRT_REG_DWORD(®->iobase_addr, 0x76A0); | ||
1046 | dmp_reg = ®->iobase_window; | ||
1047 | for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) | ||
1048 | fw->xmt_data_dma_reg[cnt] = | ||
1049 | htonl(RD_REG_DWORD(dmp_reg++)); | ||
1050 | |||
1051 | /* Receive DMA registers. */ | ||
1052 | iter_reg = fw->rcvt0_data_dma_reg; | ||
1053 | WRT_REG_DWORD(®->iobase_addr, 0x7700); | ||
1054 | dmp_reg = ®->iobase_window; | ||
1055 | for (cnt = 0; cnt < 16; cnt++) | ||
1056 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1057 | |||
1058 | WRT_REG_DWORD(®->iobase_addr, 0x7710); | ||
1059 | dmp_reg = ®->iobase_window; | ||
1060 | for (cnt = 0; cnt < 16; cnt++) | ||
1061 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1062 | |||
1063 | iter_reg = fw->rcvt1_data_dma_reg; | ||
1064 | WRT_REG_DWORD(®->iobase_addr, 0x7720); | ||
1065 | dmp_reg = ®->iobase_window; | ||
1066 | for (cnt = 0; cnt < 16; cnt++) | ||
1067 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1068 | |||
1069 | WRT_REG_DWORD(®->iobase_addr, 0x7730); | ||
1070 | dmp_reg = ®->iobase_window; | ||
1071 | for (cnt = 0; cnt < 16; cnt++) | ||
1072 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1073 | |||
1074 | /* RISC registers. */ | ||
1075 | iter_reg = fw->risc_gp_reg; | ||
1076 | WRT_REG_DWORD(®->iobase_addr, 0x0F00); | ||
1077 | dmp_reg = ®->iobase_window; | ||
1078 | for (cnt = 0; cnt < 16; cnt++) | ||
1079 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1080 | |||
1081 | WRT_REG_DWORD(®->iobase_addr, 0x0F10); | ||
1082 | dmp_reg = ®->iobase_window; | ||
1083 | for (cnt = 0; cnt < 16; cnt++) | ||
1084 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1085 | |||
1086 | WRT_REG_DWORD(®->iobase_addr, 0x0F20); | ||
1087 | dmp_reg = ®->iobase_window; | ||
1088 | for (cnt = 0; cnt < 16; cnt++) | ||
1089 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1090 | |||
1091 | WRT_REG_DWORD(®->iobase_addr, 0x0F30); | ||
1092 | dmp_reg = ®->iobase_window; | ||
1093 | for (cnt = 0; cnt < 16; cnt++) | ||
1094 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1095 | |||
1096 | WRT_REG_DWORD(®->iobase_addr, 0x0F40); | ||
1097 | dmp_reg = ®->iobase_window; | ||
1098 | for (cnt = 0; cnt < 16; cnt++) | ||
1099 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1100 | |||
1101 | WRT_REG_DWORD(®->iobase_addr, 0x0F50); | ||
1102 | dmp_reg = ®->iobase_window; | ||
1103 | for (cnt = 0; cnt < 16; cnt++) | ||
1104 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1105 | |||
1106 | WRT_REG_DWORD(®->iobase_addr, 0x0F60); | ||
1107 | dmp_reg = ®->iobase_window; | ||
1108 | for (cnt = 0; cnt < 16; cnt++) | ||
1109 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1110 | |||
1111 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); | ||
1112 | dmp_reg = ®->iobase_window; | ||
1113 | for (cnt = 0; cnt < 16; cnt++) | ||
1114 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1115 | |||
1116 | /* Local memory controller registers. */ | ||
1117 | iter_reg = fw->lmc_reg; | ||
1118 | WRT_REG_DWORD(®->iobase_addr, 0x3000); | ||
1119 | dmp_reg = ®->iobase_window; | ||
1120 | for (cnt = 0; cnt < 16; cnt++) | ||
1121 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1122 | |||
1123 | WRT_REG_DWORD(®->iobase_addr, 0x3010); | ||
1124 | dmp_reg = ®->iobase_window; | ||
1125 | for (cnt = 0; cnt < 16; cnt++) | ||
1126 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1127 | |||
1128 | WRT_REG_DWORD(®->iobase_addr, 0x3020); | ||
1129 | dmp_reg = ®->iobase_window; | ||
1130 | for (cnt = 0; cnt < 16; cnt++) | ||
1131 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1132 | |||
1133 | WRT_REG_DWORD(®->iobase_addr, 0x3030); | ||
1134 | dmp_reg = ®->iobase_window; | ||
1135 | for (cnt = 0; cnt < 16; cnt++) | ||
1136 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1137 | |||
1138 | WRT_REG_DWORD(®->iobase_addr, 0x3040); | ||
1139 | dmp_reg = ®->iobase_window; | ||
1140 | for (cnt = 0; cnt < 16; cnt++) | ||
1141 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1142 | |||
1143 | WRT_REG_DWORD(®->iobase_addr, 0x3050); | ||
1144 | dmp_reg = ®->iobase_window; | ||
1145 | for (cnt = 0; cnt < 16; cnt++) | ||
1146 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1147 | |||
1148 | WRT_REG_DWORD(®->iobase_addr, 0x3060); | ||
1149 | dmp_reg = ®->iobase_window; | ||
1150 | for (cnt = 0; cnt < 16; cnt++) | ||
1151 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1152 | |||
1153 | /* Fibre Protocol Module registers. */ | ||
1154 | iter_reg = fw->fpm_hdw_reg; | ||
1155 | WRT_REG_DWORD(®->iobase_addr, 0x4000); | ||
1156 | dmp_reg = ®->iobase_window; | ||
1157 | for (cnt = 0; cnt < 16; cnt++) | ||
1158 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1159 | |||
1160 | WRT_REG_DWORD(®->iobase_addr, 0x4010); | ||
1161 | dmp_reg = ®->iobase_window; | ||
1162 | for (cnt = 0; cnt < 16; cnt++) | ||
1163 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1164 | |||
1165 | WRT_REG_DWORD(®->iobase_addr, 0x4020); | ||
1166 | dmp_reg = ®->iobase_window; | ||
1167 | for (cnt = 0; cnt < 16; cnt++) | ||
1168 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1169 | |||
1170 | WRT_REG_DWORD(®->iobase_addr, 0x4030); | ||
1171 | dmp_reg = ®->iobase_window; | ||
1172 | for (cnt = 0; cnt < 16; cnt++) | ||
1173 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1174 | |||
1175 | WRT_REG_DWORD(®->iobase_addr, 0x4040); | ||
1176 | dmp_reg = ®->iobase_window; | ||
1177 | for (cnt = 0; cnt < 16; cnt++) | ||
1178 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1179 | |||
1180 | WRT_REG_DWORD(®->iobase_addr, 0x4050); | ||
1181 | dmp_reg = ®->iobase_window; | ||
1182 | for (cnt = 0; cnt < 16; cnt++) | ||
1183 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1184 | |||
1185 | WRT_REG_DWORD(®->iobase_addr, 0x4060); | ||
1186 | dmp_reg = ®->iobase_window; | ||
1187 | for (cnt = 0; cnt < 16; cnt++) | ||
1188 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1189 | |||
1190 | WRT_REG_DWORD(®->iobase_addr, 0x4070); | ||
1191 | dmp_reg = ®->iobase_window; | ||
1192 | for (cnt = 0; cnt < 16; cnt++) | ||
1193 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1194 | |||
1195 | WRT_REG_DWORD(®->iobase_addr, 0x4080); | ||
1196 | dmp_reg = ®->iobase_window; | ||
1197 | for (cnt = 0; cnt < 16; cnt++) | ||
1198 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1199 | |||
1200 | WRT_REG_DWORD(®->iobase_addr, 0x4090); | ||
1201 | dmp_reg = ®->iobase_window; | ||
1202 | for (cnt = 0; cnt < 16; cnt++) | ||
1203 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1204 | |||
1205 | WRT_REG_DWORD(®->iobase_addr, 0x40A0); | ||
1206 | dmp_reg = ®->iobase_window; | ||
1207 | for (cnt = 0; cnt < 16; cnt++) | ||
1208 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1209 | |||
1210 | WRT_REG_DWORD(®->iobase_addr, 0x40B0); | ||
1211 | dmp_reg = ®->iobase_window; | ||
1212 | for (cnt = 0; cnt < 16; cnt++) | ||
1213 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1214 | |||
1215 | /* Frame Buffer registers. */ | ||
1216 | iter_reg = fw->fb_hdw_reg; | ||
1217 | WRT_REG_DWORD(®->iobase_addr, 0x6000); | ||
1218 | dmp_reg = ®->iobase_window; | ||
1219 | for (cnt = 0; cnt < 16; cnt++) | ||
1220 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1221 | |||
1222 | WRT_REG_DWORD(®->iobase_addr, 0x6010); | ||
1223 | dmp_reg = ®->iobase_window; | ||
1224 | for (cnt = 0; cnt < 16; cnt++) | ||
1225 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1226 | |||
1227 | WRT_REG_DWORD(®->iobase_addr, 0x6020); | ||
1228 | dmp_reg = ®->iobase_window; | ||
1229 | for (cnt = 0; cnt < 16; cnt++) | ||
1230 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1231 | |||
1232 | WRT_REG_DWORD(®->iobase_addr, 0x6030); | ||
1233 | dmp_reg = ®->iobase_window; | ||
1234 | for (cnt = 0; cnt < 16; cnt++) | ||
1235 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1236 | |||
1237 | WRT_REG_DWORD(®->iobase_addr, 0x6040); | ||
1238 | dmp_reg = ®->iobase_window; | ||
1239 | for (cnt = 0; cnt < 16; cnt++) | ||
1240 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1241 | |||
1242 | WRT_REG_DWORD(®->iobase_addr, 0x6100); | ||
1243 | dmp_reg = ®->iobase_window; | ||
1244 | for (cnt = 0; cnt < 16; cnt++) | ||
1245 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1246 | |||
1247 | WRT_REG_DWORD(®->iobase_addr, 0x6130); | ||
1248 | dmp_reg = ®->iobase_window; | ||
1249 | for (cnt = 0; cnt < 16; cnt++) | ||
1250 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1251 | |||
1252 | WRT_REG_DWORD(®->iobase_addr, 0x6150); | ||
1253 | dmp_reg = ®->iobase_window; | ||
1254 | for (cnt = 0; cnt < 16; cnt++) | ||
1255 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1256 | |||
1257 | WRT_REG_DWORD(®->iobase_addr, 0x6170); | ||
1258 | dmp_reg = ®->iobase_window; | ||
1259 | for (cnt = 0; cnt < 16; cnt++) | ||
1260 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1261 | |||
1262 | WRT_REG_DWORD(®->iobase_addr, 0x6190); | ||
1263 | dmp_reg = ®->iobase_window; | ||
1264 | for (cnt = 0; cnt < 16; cnt++) | ||
1265 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1266 | |||
1267 | WRT_REG_DWORD(®->iobase_addr, 0x61B0); | ||
1268 | dmp_reg = ®->iobase_window; | ||
1269 | for (cnt = 0; cnt < 16; cnt++) | ||
1270 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1271 | |||
1272 | /* Reset RISC. */ | ||
1273 | WRT_REG_DWORD(®->ctrl_status, | ||
1274 | CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); | ||
1275 | for (cnt = 0; cnt < 30000; cnt++) { | ||
1276 | if ((RD_REG_DWORD(®->ctrl_status) & | ||
1277 | CSRX_DMA_ACTIVE) == 0) | ||
1278 | break; | ||
1279 | |||
1280 | udelay(10); | ||
1281 | } | ||
1282 | |||
1283 | WRT_REG_DWORD(®->ctrl_status, | ||
1284 | CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); | ||
1285 | pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); | ||
1286 | |||
1287 | udelay(100); | ||
1288 | /* Wait for firmware to complete NVRAM accesses. */ | ||
1289 | mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); | ||
1290 | for (cnt = 10000 ; cnt && mb0; cnt--) { | ||
1291 | udelay(5); | ||
1292 | mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); | ||
1293 | barrier(); | ||
1294 | } | ||
1295 | |||
1296 | /* Wait for soft-reset to complete. */ | ||
1297 | for (cnt = 0; cnt < 30000; cnt++) { | ||
1298 | if ((RD_REG_DWORD(®->ctrl_status) & | ||
1299 | CSRX_ISP_SOFT_RESET) == 0) | ||
1300 | break; | ||
1301 | |||
1302 | udelay(10); | ||
1303 | } | ||
1304 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_RESET); | ||
1305 | RD_REG_DWORD(®->hccr); /* PCI Posting. */ | ||
1306 | } | ||
1307 | |||
1308 | for (cnt = 30000; RD_REG_WORD(®->mailbox0) != 0 && | ||
1309 | rval == QLA_SUCCESS; cnt--) { | ||
1310 | if (cnt) | ||
1311 | udelay(100); | ||
1312 | else | ||
1313 | rval = QLA_FUNCTION_TIMEOUT; | ||
1314 | } | ||
1315 | |||
1316 | if (rval == QLA_SUCCESS) | ||
1317 | rval = qla2xxx_dump_memory(ha, fw->code_ram, | ||
1318 | sizeof(fw->code_ram), fw->ext_mem, &nxt); | ||
1319 | |||
1320 | if (rval == QLA_SUCCESS) { | ||
1321 | nxt = qla2xxx_copy_queues(ha, nxt); | ||
1322 | if (ha->eft) | ||
1323 | memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); | ||
1324 | } | ||
1325 | |||
1326 | if (rval != QLA_SUCCESS) { | 1022 | if (rval != QLA_SUCCESS) { |
1327 | qla_printk(KERN_WARNING, ha, | 1023 | qla_printk(KERN_WARNING, ha, |
1328 | "Failed to dump firmware (%x)!!!\n", rval); | 1024 | "Failed to dump firmware (%x)!!!\n", rval); |
@@ -1346,7 +1042,6 @@ qla25xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
1346 | int rval; | 1042 | int rval; |
1347 | uint32_t cnt; | 1043 | uint32_t cnt; |
1348 | uint32_t risc_address; | 1044 | uint32_t risc_address; |
1349 | uint16_t mb0, wd; | ||
1350 | 1045 | ||
1351 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 1046 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
1352 | uint32_t __iomem *dmp_reg; | 1047 | uint32_t __iomem *dmp_reg; |
@@ -1377,655 +1072,260 @@ qla25xx_fw_dump(scsi_qla_host_t *ha, int hardware_locked) | |||
1377 | } | 1072 | } |
1378 | fw = &ha->fw_dump->isp.isp25; | 1073 | fw = &ha->fw_dump->isp.isp25; |
1379 | qla2xxx_prep_dump(ha, ha->fw_dump); | 1074 | qla2xxx_prep_dump(ha, ha->fw_dump); |
1075 | ha->fw_dump->version = __constant_htonl(2); | ||
1380 | 1076 | ||
1381 | rval = QLA_SUCCESS; | ||
1382 | fw->host_status = htonl(RD_REG_DWORD(®->host_status)); | 1077 | fw->host_status = htonl(RD_REG_DWORD(®->host_status)); |
1383 | 1078 | ||
1384 | /* Pause RISC. */ | 1079 | /* Pause RISC. */ |
1385 | if ((RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0) { | 1080 | rval = qla24xx_pause_risc(reg); |
1386 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_RESET | | 1081 | if (rval != QLA_SUCCESS) |
1387 | HCCRX_CLR_HOST_INT); | 1082 | goto qla25xx_fw_dump_failed_0; |
1388 | RD_REG_DWORD(®->hccr); /* PCI Posting. */ | 1083 | |
1389 | WRT_REG_DWORD(®->hccr, HCCRX_SET_RISC_PAUSE); | 1084 | /* Host/Risc registers. */ |
1390 | for (cnt = 30000; | 1085 | iter_reg = fw->host_risc_reg; |
1391 | (RD_REG_DWORD(®->hccr) & HCCRX_RISC_PAUSE) == 0 && | 1086 | iter_reg = qla24xx_read_window(reg, 0x7000, 16, iter_reg); |
1392 | rval == QLA_SUCCESS; cnt--) { | 1087 | qla24xx_read_window(reg, 0x7010, 16, iter_reg); |
1393 | if (cnt) | 1088 | |
1394 | udelay(100); | 1089 | /* PCIe registers. */ |
1395 | else | 1090 | WRT_REG_DWORD(®->iobase_addr, 0x7C00); |
1396 | rval = QLA_FUNCTION_TIMEOUT; | 1091 | RD_REG_DWORD(®->iobase_addr); |
1397 | } | 1092 | WRT_REG_DWORD(®->iobase_window, 0x01); |
1398 | } | 1093 | dmp_reg = ®->iobase_c4; |
1399 | 1094 | fw->pcie_regs[0] = htonl(RD_REG_DWORD(dmp_reg++)); | |
1400 | if (rval == QLA_SUCCESS) { | 1095 | fw->pcie_regs[1] = htonl(RD_REG_DWORD(dmp_reg++)); |
1401 | /* Host interface registers. */ | 1096 | fw->pcie_regs[2] = htonl(RD_REG_DWORD(dmp_reg)); |
1402 | dmp_reg = (uint32_t __iomem *)(reg + 0); | 1097 | fw->pcie_regs[3] = htonl(RD_REG_DWORD(®->iobase_window)); |
1403 | for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) | 1098 | WRT_REG_DWORD(®->iobase_window, 0x00); |
1404 | fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | 1099 | RD_REG_DWORD(®->iobase_window); |
1405 | 1100 | ||
1406 | /* Disable interrupts. */ | 1101 | /* Host interface registers. */ |
1407 | WRT_REG_DWORD(®->ictrl, 0); | 1102 | dmp_reg = ®->flash_addr; |
1408 | RD_REG_DWORD(®->ictrl); | 1103 | for (cnt = 0; cnt < sizeof(fw->host_reg) / 4; cnt++) |
1409 | 1104 | fw->host_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | |
1410 | /* Shadow registers. */ | 1105 | |
1411 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); | 1106 | /* Disable interrupts. */ |
1412 | RD_REG_DWORD(®->iobase_addr); | 1107 | WRT_REG_DWORD(®->ictrl, 0); |
1413 | WRT_REG_DWORD(®->iobase_select, 0xB0000000); | 1108 | RD_REG_DWORD(®->ictrl); |
1414 | fw->shadow_reg[0] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 1109 | |
1415 | 1110 | /* Shadow registers. */ | |
1416 | WRT_REG_DWORD(®->iobase_select, 0xB0100000); | 1111 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); |
1417 | fw->shadow_reg[1] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 1112 | RD_REG_DWORD(®->iobase_addr); |
1418 | 1113 | WRT_REG_DWORD(®->iobase_select, 0xB0000000); | |
1419 | WRT_REG_DWORD(®->iobase_select, 0xB0200000); | 1114 | fw->shadow_reg[0] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
1420 | fw->shadow_reg[2] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 1115 | |
1421 | 1116 | WRT_REG_DWORD(®->iobase_select, 0xB0100000); | |
1422 | WRT_REG_DWORD(®->iobase_select, 0xB0300000); | 1117 | fw->shadow_reg[1] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
1423 | fw->shadow_reg[3] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 1118 | |
1424 | 1119 | WRT_REG_DWORD(®->iobase_select, 0xB0200000); | |
1425 | WRT_REG_DWORD(®->iobase_select, 0xB0400000); | 1120 | fw->shadow_reg[2] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
1426 | fw->shadow_reg[4] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 1121 | |
1427 | 1122 | WRT_REG_DWORD(®->iobase_select, 0xB0300000); | |
1428 | WRT_REG_DWORD(®->iobase_select, 0xB0500000); | 1123 | fw->shadow_reg[3] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
1429 | fw->shadow_reg[5] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 1124 | |
1430 | 1125 | WRT_REG_DWORD(®->iobase_select, 0xB0400000); | |
1431 | WRT_REG_DWORD(®->iobase_select, 0xB0600000); | 1126 | fw->shadow_reg[4] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
1432 | fw->shadow_reg[6] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 1127 | |
1433 | 1128 | WRT_REG_DWORD(®->iobase_select, 0xB0500000); | |
1434 | WRT_REG_DWORD(®->iobase_select, 0xB0700000); | 1129 | fw->shadow_reg[5] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
1435 | fw->shadow_reg[7] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 1130 | |
1436 | 1131 | WRT_REG_DWORD(®->iobase_select, 0xB0600000); | |
1437 | WRT_REG_DWORD(®->iobase_select, 0xB0800000); | 1132 | fw->shadow_reg[6] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
1438 | fw->shadow_reg[8] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 1133 | |
1439 | 1134 | WRT_REG_DWORD(®->iobase_select, 0xB0700000); | |
1440 | WRT_REG_DWORD(®->iobase_select, 0xB0900000); | 1135 | fw->shadow_reg[7] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
1441 | fw->shadow_reg[9] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 1136 | |
1442 | 1137 | WRT_REG_DWORD(®->iobase_select, 0xB0800000); | |
1443 | WRT_REG_DWORD(®->iobase_select, 0xB0A00000); | 1138 | fw->shadow_reg[8] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
1444 | fw->shadow_reg[10] = htonl(RD_REG_DWORD(®->iobase_sdata)); | 1139 | |
1445 | 1140 | WRT_REG_DWORD(®->iobase_select, 0xB0900000); | |
1446 | /* RISC I/O register. */ | 1141 | fw->shadow_reg[9] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
1447 | WRT_REG_DWORD(®->iobase_addr, 0x0010); | 1142 | |
1448 | RD_REG_DWORD(®->iobase_addr); | 1143 | WRT_REG_DWORD(®->iobase_select, 0xB0A00000); |
1449 | fw->risc_io_reg = htonl(RD_REG_DWORD(®->iobase_window)); | 1144 | fw->shadow_reg[10] = htonl(RD_REG_DWORD(®->iobase_sdata)); |
1450 | 1145 | ||
1451 | /* Mailbox registers. */ | 1146 | /* RISC I/O register. */ |
1452 | mbx_reg = ®->mailbox0; | 1147 | WRT_REG_DWORD(®->iobase_addr, 0x0010); |
1453 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) | 1148 | fw->risc_io_reg = htonl(RD_REG_DWORD(®->iobase_window)); |
1454 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); | 1149 | |
1455 | 1150 | /* Mailbox registers. */ | |
1456 | /* Transfer sequence registers. */ | 1151 | mbx_reg = ®->mailbox0; |
1457 | iter_reg = fw->xseq_gp_reg; | 1152 | for (cnt = 0; cnt < sizeof(fw->mailbox_reg) / 2; cnt++) |
1458 | WRT_REG_DWORD(®->iobase_addr, 0xBF00); | 1153 | fw->mailbox_reg[cnt] = htons(RD_REG_WORD(mbx_reg++)); |
1459 | dmp_reg = ®->iobase_window; | 1154 | |
1460 | for (cnt = 0; cnt < 16; cnt++) | 1155 | /* Transfer sequence registers. */ |
1461 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1156 | iter_reg = fw->xseq_gp_reg; |
1462 | 1157 | iter_reg = qla24xx_read_window(reg, 0xBF00, 16, iter_reg); | |
1463 | WRT_REG_DWORD(®->iobase_addr, 0xBF10); | 1158 | iter_reg = qla24xx_read_window(reg, 0xBF10, 16, iter_reg); |
1464 | dmp_reg = ®->iobase_window; | 1159 | iter_reg = qla24xx_read_window(reg, 0xBF20, 16, iter_reg); |
1465 | for (cnt = 0; cnt < 16; cnt++) | 1160 | iter_reg = qla24xx_read_window(reg, 0xBF30, 16, iter_reg); |
1466 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1161 | iter_reg = qla24xx_read_window(reg, 0xBF40, 16, iter_reg); |
1467 | 1162 | iter_reg = qla24xx_read_window(reg, 0xBF50, 16, iter_reg); | |
1468 | WRT_REG_DWORD(®->iobase_addr, 0xBF20); | 1163 | iter_reg = qla24xx_read_window(reg, 0xBF60, 16, iter_reg); |
1469 | dmp_reg = ®->iobase_window; | 1164 | qla24xx_read_window(reg, 0xBF70, 16, iter_reg); |
1470 | for (cnt = 0; cnt < 16; cnt++) | 1165 | |
1471 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1166 | iter_reg = fw->xseq_0_reg; |
1472 | 1167 | iter_reg = qla24xx_read_window(reg, 0xBFC0, 16, iter_reg); | |
1473 | WRT_REG_DWORD(®->iobase_addr, 0xBF30); | 1168 | iter_reg = qla24xx_read_window(reg, 0xBFD0, 16, iter_reg); |
1474 | dmp_reg = ®->iobase_window; | 1169 | qla24xx_read_window(reg, 0xBFE0, 16, iter_reg); |
1475 | for (cnt = 0; cnt < 16; cnt++) | 1170 | |
1476 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1171 | qla24xx_read_window(reg, 0xBFF0, 16, fw->xseq_1_reg); |
1477 | 1172 | ||
1478 | WRT_REG_DWORD(®->iobase_addr, 0xBF40); | 1173 | /* Receive sequence registers. */ |
1479 | dmp_reg = ®->iobase_window; | 1174 | iter_reg = fw->rseq_gp_reg; |
1480 | for (cnt = 0; cnt < 16; cnt++) | 1175 | iter_reg = qla24xx_read_window(reg, 0xFF00, 16, iter_reg); |
1481 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1176 | iter_reg = qla24xx_read_window(reg, 0xFF10, 16, iter_reg); |
1482 | 1177 | iter_reg = qla24xx_read_window(reg, 0xFF20, 16, iter_reg); | |
1483 | WRT_REG_DWORD(®->iobase_addr, 0xBF50); | 1178 | iter_reg = qla24xx_read_window(reg, 0xFF30, 16, iter_reg); |
1484 | dmp_reg = ®->iobase_window; | 1179 | iter_reg = qla24xx_read_window(reg, 0xFF40, 16, iter_reg); |
1485 | for (cnt = 0; cnt < 16; cnt++) | 1180 | iter_reg = qla24xx_read_window(reg, 0xFF50, 16, iter_reg); |
1486 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1181 | iter_reg = qla24xx_read_window(reg, 0xFF60, 16, iter_reg); |
1487 | 1182 | qla24xx_read_window(reg, 0xFF70, 16, iter_reg); | |
1488 | WRT_REG_DWORD(®->iobase_addr, 0xBF60); | 1183 | |
1489 | dmp_reg = ®->iobase_window; | 1184 | iter_reg = fw->rseq_0_reg; |
1490 | for (cnt = 0; cnt < 16; cnt++) | 1185 | iter_reg = qla24xx_read_window(reg, 0xFFC0, 16, iter_reg); |
1491 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1186 | qla24xx_read_window(reg, 0xFFD0, 16, iter_reg); |
1492 | 1187 | ||
1493 | WRT_REG_DWORD(®->iobase_addr, 0xBF70); | 1188 | qla24xx_read_window(reg, 0xFFE0, 16, fw->rseq_1_reg); |
1494 | dmp_reg = ®->iobase_window; | 1189 | qla24xx_read_window(reg, 0xFFF0, 16, fw->rseq_2_reg); |
1495 | for (cnt = 0; cnt < 16; cnt++) | 1190 | |
1496 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1191 | /* Auxiliary sequence registers. */ |
1497 | 1192 | iter_reg = fw->aseq_gp_reg; | |
1498 | iter_reg = fw->xseq_0_reg; | 1193 | iter_reg = qla24xx_read_window(reg, 0xB000, 16, iter_reg); |
1499 | WRT_REG_DWORD(®->iobase_addr, 0xBFC0); | 1194 | iter_reg = qla24xx_read_window(reg, 0xB010, 16, iter_reg); |
1500 | dmp_reg = ®->iobase_window; | 1195 | iter_reg = qla24xx_read_window(reg, 0xB020, 16, iter_reg); |
1501 | for (cnt = 0; cnt < 16; cnt++) | 1196 | iter_reg = qla24xx_read_window(reg, 0xB030, 16, iter_reg); |
1502 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1197 | iter_reg = qla24xx_read_window(reg, 0xB040, 16, iter_reg); |
1503 | 1198 | iter_reg = qla24xx_read_window(reg, 0xB050, 16, iter_reg); | |
1504 | WRT_REG_DWORD(®->iobase_addr, 0xBFD0); | 1199 | iter_reg = qla24xx_read_window(reg, 0xB060, 16, iter_reg); |
1505 | dmp_reg = ®->iobase_window; | 1200 | qla24xx_read_window(reg, 0xB070, 16, iter_reg); |
1506 | for (cnt = 0; cnt < 16; cnt++) | 1201 | |
1507 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1202 | iter_reg = fw->aseq_0_reg; |
1508 | 1203 | iter_reg = qla24xx_read_window(reg, 0xB0C0, 16, iter_reg); | |
1509 | WRT_REG_DWORD(®->iobase_addr, 0xBFE0); | 1204 | qla24xx_read_window(reg, 0xB0D0, 16, iter_reg); |
1510 | dmp_reg = ®->iobase_window; | 1205 | |
1511 | for (cnt = 0; cnt < 16; cnt++) | 1206 | qla24xx_read_window(reg, 0xB0E0, 16, fw->aseq_1_reg); |
1512 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1207 | qla24xx_read_window(reg, 0xB0F0, 16, fw->aseq_2_reg); |
1513 | 1208 | ||
1514 | WRT_REG_DWORD(®->iobase_addr, 0xBFF0); | 1209 | /* Command DMA registers. */ |
1515 | dmp_reg = ®->iobase_window; | 1210 | qla24xx_read_window(reg, 0x7100, 16, fw->cmd_dma_reg); |
1516 | for (cnt = 0; cnt < sizeof(fw->xseq_1_reg) / 4; cnt++) | 1211 | |
1517 | fw->xseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | 1212 | /* Queues. */ |
1518 | 1213 | iter_reg = fw->req0_dma_reg; | |
1519 | /* Receive sequence registers. */ | 1214 | iter_reg = qla24xx_read_window(reg, 0x7200, 8, iter_reg); |
1520 | iter_reg = fw->rseq_gp_reg; | 1215 | dmp_reg = ®->iobase_q; |
1521 | WRT_REG_DWORD(®->iobase_addr, 0xFF00); | 1216 | for (cnt = 0; cnt < 7; cnt++) |
1522 | dmp_reg = ®->iobase_window; | 1217 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1523 | for (cnt = 0; cnt < 16; cnt++) | 1218 | |
1524 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1219 | iter_reg = fw->resp0_dma_reg; |
1525 | 1220 | iter_reg = qla24xx_read_window(reg, 0x7300, 8, iter_reg); | |
1526 | WRT_REG_DWORD(®->iobase_addr, 0xFF10); | 1221 | dmp_reg = ®->iobase_q; |
1527 | dmp_reg = ®->iobase_window; | 1222 | for (cnt = 0; cnt < 7; cnt++) |
1528 | for (cnt = 0; cnt < 16; cnt++) | 1223 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1529 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1224 | |
1530 | 1225 | iter_reg = fw->req1_dma_reg; | |
1531 | WRT_REG_DWORD(®->iobase_addr, 0xFF20); | 1226 | iter_reg = qla24xx_read_window(reg, 0x7400, 8, iter_reg); |
1532 | dmp_reg = ®->iobase_window; | 1227 | dmp_reg = ®->iobase_q; |
1533 | for (cnt = 0; cnt < 16; cnt++) | 1228 | for (cnt = 0; cnt < 7; cnt++) |
1534 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1229 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); |
1535 | 1230 | ||
1536 | WRT_REG_DWORD(®->iobase_addr, 0xFF30); | 1231 | /* Transmit DMA registers. */ |
1537 | dmp_reg = ®->iobase_window; | 1232 | iter_reg = fw->xmt0_dma_reg; |
1538 | for (cnt = 0; cnt < 16; cnt++) | 1233 | iter_reg = qla24xx_read_window(reg, 0x7600, 16, iter_reg); |
1539 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1234 | qla24xx_read_window(reg, 0x7610, 16, iter_reg); |
1540 | 1235 | ||
1541 | WRT_REG_DWORD(®->iobase_addr, 0xFF40); | 1236 | iter_reg = fw->xmt1_dma_reg; |
1542 | dmp_reg = ®->iobase_window; | 1237 | iter_reg = qla24xx_read_window(reg, 0x7620, 16, iter_reg); |
1543 | for (cnt = 0; cnt < 16; cnt++) | 1238 | qla24xx_read_window(reg, 0x7630, 16, iter_reg); |
1544 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1239 | |
1545 | 1240 | iter_reg = fw->xmt2_dma_reg; | |
1546 | WRT_REG_DWORD(®->iobase_addr, 0xFF50); | 1241 | iter_reg = qla24xx_read_window(reg, 0x7640, 16, iter_reg); |
1547 | dmp_reg = ®->iobase_window; | 1242 | qla24xx_read_window(reg, 0x7650, 16, iter_reg); |
1548 | for (cnt = 0; cnt < 16; cnt++) | 1243 | |
1549 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1244 | iter_reg = fw->xmt3_dma_reg; |
1550 | 1245 | iter_reg = qla24xx_read_window(reg, 0x7660, 16, iter_reg); | |
1551 | WRT_REG_DWORD(®->iobase_addr, 0xFF60); | 1246 | qla24xx_read_window(reg, 0x7670, 16, iter_reg); |
1552 | dmp_reg = ®->iobase_window; | 1247 | |
1553 | for (cnt = 0; cnt < 16; cnt++) | 1248 | iter_reg = fw->xmt4_dma_reg; |
1554 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1249 | iter_reg = qla24xx_read_window(reg, 0x7680, 16, iter_reg); |
1555 | 1250 | qla24xx_read_window(reg, 0x7690, 16, iter_reg); | |
1556 | WRT_REG_DWORD(®->iobase_addr, 0xFF70); | 1251 | |
1557 | dmp_reg = ®->iobase_window; | 1252 | qla24xx_read_window(reg, 0x76A0, 16, fw->xmt_data_dma_reg); |
1558 | for (cnt = 0; cnt < 16; cnt++) | 1253 | |
1559 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1254 | /* Receive DMA registers. */ |
1560 | 1255 | iter_reg = fw->rcvt0_data_dma_reg; | |
1561 | iter_reg = fw->rseq_0_reg; | 1256 | iter_reg = qla24xx_read_window(reg, 0x7700, 16, iter_reg); |
1562 | WRT_REG_DWORD(®->iobase_addr, 0xFFC0); | 1257 | qla24xx_read_window(reg, 0x7710, 16, iter_reg); |
1563 | dmp_reg = ®->iobase_window; | 1258 | |
1564 | for (cnt = 0; cnt < 16; cnt++) | 1259 | iter_reg = fw->rcvt1_data_dma_reg; |
1565 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1260 | iter_reg = qla24xx_read_window(reg, 0x7720, 16, iter_reg); |
1566 | 1261 | qla24xx_read_window(reg, 0x7730, 16, iter_reg); | |
1567 | WRT_REG_DWORD(®->iobase_addr, 0xFFD0); | 1262 | |
1568 | dmp_reg = ®->iobase_window; | 1263 | /* RISC registers. */ |
1569 | for (cnt = 0; cnt < 16; cnt++) | 1264 | iter_reg = fw->risc_gp_reg; |
1570 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1265 | iter_reg = qla24xx_read_window(reg, 0x0F00, 16, iter_reg); |
1571 | 1266 | iter_reg = qla24xx_read_window(reg, 0x0F10, 16, iter_reg); | |
1572 | WRT_REG_DWORD(®->iobase_addr, 0xFFE0); | 1267 | iter_reg = qla24xx_read_window(reg, 0x0F20, 16, iter_reg); |
1573 | dmp_reg = ®->iobase_window; | 1268 | iter_reg = qla24xx_read_window(reg, 0x0F30, 16, iter_reg); |
1574 | for (cnt = 0; cnt < sizeof(fw->rseq_1_reg) / 4; cnt++) | 1269 | iter_reg = qla24xx_read_window(reg, 0x0F40, 16, iter_reg); |
1575 | fw->rseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | 1270 | iter_reg = qla24xx_read_window(reg, 0x0F50, 16, iter_reg); |
1576 | 1271 | iter_reg = qla24xx_read_window(reg, 0x0F60, 16, iter_reg); | |
1577 | WRT_REG_DWORD(®->iobase_addr, 0xFFF0); | 1272 | qla24xx_read_window(reg, 0x0F70, 16, iter_reg); |
1578 | dmp_reg = ®->iobase_window; | 1273 | |
1579 | for (cnt = 0; cnt < sizeof(fw->rseq_2_reg) / 4; cnt++) | 1274 | /* Local memory controller registers. */ |
1580 | fw->rseq_2_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | 1275 | iter_reg = fw->lmc_reg; |
1581 | 1276 | iter_reg = qla24xx_read_window(reg, 0x3000, 16, iter_reg); | |
1582 | /* Auxiliary sequence registers. */ | 1277 | iter_reg = qla24xx_read_window(reg, 0x3010, 16, iter_reg); |
1583 | iter_reg = fw->aseq_gp_reg; | 1278 | iter_reg = qla24xx_read_window(reg, 0x3020, 16, iter_reg); |
1584 | WRT_REG_DWORD(®->iobase_addr, 0xB000); | 1279 | iter_reg = qla24xx_read_window(reg, 0x3030, 16, iter_reg); |
1585 | dmp_reg = ®->iobase_window; | 1280 | iter_reg = qla24xx_read_window(reg, 0x3040, 16, iter_reg); |
1586 | for (cnt = 0; cnt < 16; cnt++) | 1281 | iter_reg = qla24xx_read_window(reg, 0x3050, 16, iter_reg); |
1587 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1282 | iter_reg = qla24xx_read_window(reg, 0x3060, 16, iter_reg); |
1588 | 1283 | qla24xx_read_window(reg, 0x3070, 16, iter_reg); | |
1589 | WRT_REG_DWORD(®->iobase_addr, 0xB010); | 1284 | |
1590 | dmp_reg = ®->iobase_window; | 1285 | /* Fibre Protocol Module registers. */ |
1591 | for (cnt = 0; cnt < 16; cnt++) | 1286 | iter_reg = fw->fpm_hdw_reg; |
1592 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1287 | iter_reg = qla24xx_read_window(reg, 0x4000, 16, iter_reg); |
1593 | 1288 | iter_reg = qla24xx_read_window(reg, 0x4010, 16, iter_reg); | |
1594 | WRT_REG_DWORD(®->iobase_addr, 0xB020); | 1289 | iter_reg = qla24xx_read_window(reg, 0x4020, 16, iter_reg); |
1595 | dmp_reg = ®->iobase_window; | 1290 | iter_reg = qla24xx_read_window(reg, 0x4030, 16, iter_reg); |
1596 | for (cnt = 0; cnt < 16; cnt++) | 1291 | iter_reg = qla24xx_read_window(reg, 0x4040, 16, iter_reg); |
1597 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1292 | iter_reg = qla24xx_read_window(reg, 0x4050, 16, iter_reg); |
1598 | 1293 | iter_reg = qla24xx_read_window(reg, 0x4060, 16, iter_reg); | |
1599 | WRT_REG_DWORD(®->iobase_addr, 0xB030); | 1294 | iter_reg = qla24xx_read_window(reg, 0x4070, 16, iter_reg); |
1600 | dmp_reg = ®->iobase_window; | 1295 | iter_reg = qla24xx_read_window(reg, 0x4080, 16, iter_reg); |
1601 | for (cnt = 0; cnt < 16; cnt++) | 1296 | iter_reg = qla24xx_read_window(reg, 0x4090, 16, iter_reg); |
1602 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1297 | iter_reg = qla24xx_read_window(reg, 0x40A0, 16, iter_reg); |
1603 | 1298 | qla24xx_read_window(reg, 0x40B0, 16, iter_reg); | |
1604 | WRT_REG_DWORD(®->iobase_addr, 0xB040); | 1299 | |
1605 | dmp_reg = ®->iobase_window; | 1300 | /* Frame Buffer registers. */ |
1606 | for (cnt = 0; cnt < 16; cnt++) | 1301 | iter_reg = fw->fb_hdw_reg; |
1607 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1302 | iter_reg = qla24xx_read_window(reg, 0x6000, 16, iter_reg); |
1608 | 1303 | iter_reg = qla24xx_read_window(reg, 0x6010, 16, iter_reg); | |
1609 | WRT_REG_DWORD(®->iobase_addr, 0xB050); | 1304 | iter_reg = qla24xx_read_window(reg, 0x6020, 16, iter_reg); |
1610 | dmp_reg = ®->iobase_window; | 1305 | iter_reg = qla24xx_read_window(reg, 0x6030, 16, iter_reg); |
1611 | for (cnt = 0; cnt < 16; cnt++) | 1306 | iter_reg = qla24xx_read_window(reg, 0x6040, 16, iter_reg); |
1612 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1307 | iter_reg = qla24xx_read_window(reg, 0x6100, 16, iter_reg); |
1613 | 1308 | iter_reg = qla24xx_read_window(reg, 0x6130, 16, iter_reg); | |
1614 | WRT_REG_DWORD(®->iobase_addr, 0xB060); | 1309 | iter_reg = qla24xx_read_window(reg, 0x6150, 16, iter_reg); |
1615 | dmp_reg = ®->iobase_window; | 1310 | iter_reg = qla24xx_read_window(reg, 0x6170, 16, iter_reg); |
1616 | for (cnt = 0; cnt < 16; cnt++) | 1311 | iter_reg = qla24xx_read_window(reg, 0x6190, 16, iter_reg); |
1617 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1312 | iter_reg = qla24xx_read_window(reg, 0x61B0, 16, iter_reg); |
1618 | 1313 | qla24xx_read_window(reg, 0x6F00, 16, iter_reg); | |
1619 | WRT_REG_DWORD(®->iobase_addr, 0xB070); | 1314 | |
1620 | dmp_reg = ®->iobase_window; | 1315 | rval = qla24xx_soft_reset(ha); |
1621 | for (cnt = 0; cnt < 16; cnt++) | 1316 | if (rval != QLA_SUCCESS) |
1622 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1317 | goto qla25xx_fw_dump_failed_0; |
1623 | 1318 | ||
1624 | iter_reg = fw->aseq_0_reg; | 1319 | rval = qla24xx_dump_memory(ha, fw->code_ram, sizeof(fw->code_ram), |
1625 | WRT_REG_DWORD(®->iobase_addr, 0xB0C0); | 1320 | fw->ext_mem, &nxt); |
1626 | dmp_reg = ®->iobase_window; | 1321 | if (rval != QLA_SUCCESS) |
1627 | for (cnt = 0; cnt < 16; cnt++) | 1322 | goto qla25xx_fw_dump_failed_0; |
1628 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1323 | |
1629 | 1324 | nxt = qla2xxx_copy_queues(ha, nxt); | |
1630 | WRT_REG_DWORD(®->iobase_addr, 0xB0D0); | 1325 | if (ha->eft) |
1631 | dmp_reg = ®->iobase_window; | 1326 | memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); |
1632 | for (cnt = 0; cnt < 16; cnt++) | 1327 | |
1633 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | 1328 | qla25xx_fw_dump_failed_0: |
1634 | |||
1635 | WRT_REG_DWORD(®->iobase_addr, 0xB0E0); | ||
1636 | dmp_reg = ®->iobase_window; | ||
1637 | for (cnt = 0; cnt < sizeof(fw->aseq_1_reg) / 4; cnt++) | ||
1638 | fw->aseq_1_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1639 | |||
1640 | WRT_REG_DWORD(®->iobase_addr, 0xB0F0); | ||
1641 | dmp_reg = ®->iobase_window; | ||
1642 | for (cnt = 0; cnt < sizeof(fw->aseq_2_reg) / 4; cnt++) | ||
1643 | fw->aseq_2_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1644 | |||
1645 | /* Command DMA registers. */ | ||
1646 | WRT_REG_DWORD(®->iobase_addr, 0x7100); | ||
1647 | dmp_reg = ®->iobase_window; | ||
1648 | for (cnt = 0; cnt < sizeof(fw->cmd_dma_reg) / 4; cnt++) | ||
1649 | fw->cmd_dma_reg[cnt] = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1650 | |||
1651 | /* Queues. */ | ||
1652 | iter_reg = fw->req0_dma_reg; | ||
1653 | WRT_REG_DWORD(®->iobase_addr, 0x7200); | ||
1654 | dmp_reg = ®->iobase_window; | ||
1655 | for (cnt = 0; cnt < 8; cnt++) | ||
1656 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1657 | |||
1658 | dmp_reg = ®->iobase_q; | ||
1659 | for (cnt = 0; cnt < 7; cnt++) | ||
1660 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1661 | |||
1662 | iter_reg = fw->resp0_dma_reg; | ||
1663 | WRT_REG_DWORD(®->iobase_addr, 0x7300); | ||
1664 | dmp_reg = ®->iobase_window; | ||
1665 | for (cnt = 0; cnt < 8; cnt++) | ||
1666 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1667 | |||
1668 | dmp_reg = ®->iobase_q; | ||
1669 | for (cnt = 0; cnt < 7; cnt++) | ||
1670 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1671 | |||
1672 | iter_reg = fw->req1_dma_reg; | ||
1673 | WRT_REG_DWORD(®->iobase_addr, 0x7400); | ||
1674 | dmp_reg = ®->iobase_window; | ||
1675 | for (cnt = 0; cnt < 8; cnt++) | ||
1676 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1677 | |||
1678 | dmp_reg = ®->iobase_q; | ||
1679 | for (cnt = 0; cnt < 7; cnt++) | ||
1680 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1681 | |||
1682 | /* Transmit DMA registers. */ | ||
1683 | iter_reg = fw->xmt0_dma_reg; | ||
1684 | WRT_REG_DWORD(®->iobase_addr, 0x7600); | ||
1685 | dmp_reg = ®->iobase_window; | ||
1686 | for (cnt = 0; cnt < 16; cnt++) | ||
1687 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1688 | |||
1689 | WRT_REG_DWORD(®->iobase_addr, 0x7610); | ||
1690 | dmp_reg = ®->iobase_window; | ||
1691 | for (cnt = 0; cnt < 16; cnt++) | ||
1692 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1693 | |||
1694 | iter_reg = fw->xmt1_dma_reg; | ||
1695 | WRT_REG_DWORD(®->iobase_addr, 0x7620); | ||
1696 | dmp_reg = ®->iobase_window; | ||
1697 | for (cnt = 0; cnt < 16; cnt++) | ||
1698 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1699 | |||
1700 | WRT_REG_DWORD(®->iobase_addr, 0x7630); | ||
1701 | dmp_reg = ®->iobase_window; | ||
1702 | for (cnt = 0; cnt < 16; cnt++) | ||
1703 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1704 | |||
1705 | iter_reg = fw->xmt2_dma_reg; | ||
1706 | WRT_REG_DWORD(®->iobase_addr, 0x7640); | ||
1707 | dmp_reg = ®->iobase_window; | ||
1708 | for (cnt = 0; cnt < 16; cnt++) | ||
1709 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1710 | |||
1711 | WRT_REG_DWORD(®->iobase_addr, 0x7650); | ||
1712 | dmp_reg = ®->iobase_window; | ||
1713 | for (cnt = 0; cnt < 16; cnt++) | ||
1714 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1715 | |||
1716 | iter_reg = fw->xmt3_dma_reg; | ||
1717 | WRT_REG_DWORD(®->iobase_addr, 0x7660); | ||
1718 | dmp_reg = ®->iobase_window; | ||
1719 | for (cnt = 0; cnt < 16; cnt++) | ||
1720 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1721 | |||
1722 | WRT_REG_DWORD(®->iobase_addr, 0x7670); | ||
1723 | dmp_reg = ®->iobase_window; | ||
1724 | for (cnt = 0; cnt < 16; cnt++) | ||
1725 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1726 | |||
1727 | iter_reg = fw->xmt4_dma_reg; | ||
1728 | WRT_REG_DWORD(®->iobase_addr, 0x7680); | ||
1729 | dmp_reg = ®->iobase_window; | ||
1730 | for (cnt = 0; cnt < 16; cnt++) | ||
1731 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1732 | |||
1733 | WRT_REG_DWORD(®->iobase_addr, 0x7690); | ||
1734 | dmp_reg = ®->iobase_window; | ||
1735 | for (cnt = 0; cnt < 16; cnt++) | ||
1736 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1737 | |||
1738 | WRT_REG_DWORD(®->iobase_addr, 0x76A0); | ||
1739 | dmp_reg = ®->iobase_window; | ||
1740 | for (cnt = 0; cnt < sizeof(fw->xmt_data_dma_reg) / 4; cnt++) | ||
1741 | fw->xmt_data_dma_reg[cnt] = | ||
1742 | htonl(RD_REG_DWORD(dmp_reg++)); | ||
1743 | |||
1744 | /* Receive DMA registers. */ | ||
1745 | iter_reg = fw->rcvt0_data_dma_reg; | ||
1746 | WRT_REG_DWORD(®->iobase_addr, 0x7700); | ||
1747 | dmp_reg = ®->iobase_window; | ||
1748 | for (cnt = 0; cnt < 16; cnt++) | ||
1749 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1750 | |||
1751 | WRT_REG_DWORD(®->iobase_addr, 0x7710); | ||
1752 | dmp_reg = ®->iobase_window; | ||
1753 | for (cnt = 0; cnt < 16; cnt++) | ||
1754 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1755 | |||
1756 | iter_reg = fw->rcvt1_data_dma_reg; | ||
1757 | WRT_REG_DWORD(®->iobase_addr, 0x7720); | ||
1758 | dmp_reg = ®->iobase_window; | ||
1759 | for (cnt = 0; cnt < 16; cnt++) | ||
1760 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1761 | |||
1762 | WRT_REG_DWORD(®->iobase_addr, 0x7730); | ||
1763 | dmp_reg = ®->iobase_window; | ||
1764 | for (cnt = 0; cnt < 16; cnt++) | ||
1765 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1766 | |||
1767 | /* RISC registers. */ | ||
1768 | iter_reg = fw->risc_gp_reg; | ||
1769 | WRT_REG_DWORD(®->iobase_addr, 0x0F00); | ||
1770 | dmp_reg = ®->iobase_window; | ||
1771 | for (cnt = 0; cnt < 16; cnt++) | ||
1772 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1773 | |||
1774 | WRT_REG_DWORD(®->iobase_addr, 0x0F10); | ||
1775 | dmp_reg = ®->iobase_window; | ||
1776 | for (cnt = 0; cnt < 16; cnt++) | ||
1777 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1778 | |||
1779 | WRT_REG_DWORD(®->iobase_addr, 0x0F20); | ||
1780 | dmp_reg = ®->iobase_window; | ||
1781 | for (cnt = 0; cnt < 16; cnt++) | ||
1782 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1783 | |||
1784 | WRT_REG_DWORD(®->iobase_addr, 0x0F30); | ||
1785 | dmp_reg = ®->iobase_window; | ||
1786 | for (cnt = 0; cnt < 16; cnt++) | ||
1787 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1788 | |||
1789 | WRT_REG_DWORD(®->iobase_addr, 0x0F40); | ||
1790 | dmp_reg = ®->iobase_window; | ||
1791 | for (cnt = 0; cnt < 16; cnt++) | ||
1792 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1793 | |||
1794 | WRT_REG_DWORD(®->iobase_addr, 0x0F50); | ||
1795 | dmp_reg = ®->iobase_window; | ||
1796 | for (cnt = 0; cnt < 16; cnt++) | ||
1797 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1798 | |||
1799 | WRT_REG_DWORD(®->iobase_addr, 0x0F60); | ||
1800 | dmp_reg = ®->iobase_window; | ||
1801 | for (cnt = 0; cnt < 16; cnt++) | ||
1802 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1803 | |||
1804 | WRT_REG_DWORD(®->iobase_addr, 0x0F70); | ||
1805 | dmp_reg = ®->iobase_window; | ||
1806 | for (cnt = 0; cnt < 16; cnt++) | ||
1807 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1808 | |||
1809 | /* Local memory controller registers. */ | ||
1810 | iter_reg = fw->lmc_reg; | ||
1811 | WRT_REG_DWORD(®->iobase_addr, 0x3000); | ||
1812 | dmp_reg = ®->iobase_window; | ||
1813 | for (cnt = 0; cnt < 16; cnt++) | ||
1814 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1815 | |||
1816 | WRT_REG_DWORD(®->iobase_addr, 0x3010); | ||
1817 | dmp_reg = ®->iobase_window; | ||
1818 | for (cnt = 0; cnt < 16; cnt++) | ||
1819 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1820 | |||
1821 | WRT_REG_DWORD(®->iobase_addr, 0x3020); | ||
1822 | dmp_reg = ®->iobase_window; | ||
1823 | for (cnt = 0; cnt < 16; cnt++) | ||
1824 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1825 | |||
1826 | WRT_REG_DWORD(®->iobase_addr, 0x3030); | ||
1827 | dmp_reg = ®->iobase_window; | ||
1828 | for (cnt = 0; cnt < 16; cnt++) | ||
1829 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1830 | |||
1831 | WRT_REG_DWORD(®->iobase_addr, 0x3040); | ||
1832 | dmp_reg = ®->iobase_window; | ||
1833 | for (cnt = 0; cnt < 16; cnt++) | ||
1834 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1835 | |||
1836 | WRT_REG_DWORD(®->iobase_addr, 0x3050); | ||
1837 | dmp_reg = ®->iobase_window; | ||
1838 | for (cnt = 0; cnt < 16; cnt++) | ||
1839 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1840 | |||
1841 | WRT_REG_DWORD(®->iobase_addr, 0x3060); | ||
1842 | dmp_reg = ®->iobase_window; | ||
1843 | for (cnt = 0; cnt < 16; cnt++) | ||
1844 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1845 | |||
1846 | WRT_REG_DWORD(®->iobase_addr, 0x3070); | ||
1847 | dmp_reg = ®->iobase_window; | ||
1848 | for (cnt = 0; cnt < 16; cnt++) | ||
1849 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1850 | |||
1851 | /* Fibre Protocol Module registers. */ | ||
1852 | iter_reg = fw->fpm_hdw_reg; | ||
1853 | WRT_REG_DWORD(®->iobase_addr, 0x4000); | ||
1854 | dmp_reg = ®->iobase_window; | ||
1855 | for (cnt = 0; cnt < 16; cnt++) | ||
1856 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1857 | |||
1858 | WRT_REG_DWORD(®->iobase_addr, 0x4010); | ||
1859 | dmp_reg = ®->iobase_window; | ||
1860 | for (cnt = 0; cnt < 16; cnt++) | ||
1861 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1862 | |||
1863 | WRT_REG_DWORD(®->iobase_addr, 0x4020); | ||
1864 | dmp_reg = ®->iobase_window; | ||
1865 | for (cnt = 0; cnt < 16; cnt++) | ||
1866 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1867 | |||
1868 | WRT_REG_DWORD(®->iobase_addr, 0x4030); | ||
1869 | dmp_reg = ®->iobase_window; | ||
1870 | for (cnt = 0; cnt < 16; cnt++) | ||
1871 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1872 | |||
1873 | WRT_REG_DWORD(®->iobase_addr, 0x4040); | ||
1874 | dmp_reg = ®->iobase_window; | ||
1875 | for (cnt = 0; cnt < 16; cnt++) | ||
1876 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1877 | |||
1878 | WRT_REG_DWORD(®->iobase_addr, 0x4050); | ||
1879 | dmp_reg = ®->iobase_window; | ||
1880 | for (cnt = 0; cnt < 16; cnt++) | ||
1881 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1882 | |||
1883 | WRT_REG_DWORD(®->iobase_addr, 0x4060); | ||
1884 | dmp_reg = ®->iobase_window; | ||
1885 | for (cnt = 0; cnt < 16; cnt++) | ||
1886 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1887 | |||
1888 | WRT_REG_DWORD(®->iobase_addr, 0x4070); | ||
1889 | dmp_reg = ®->iobase_window; | ||
1890 | for (cnt = 0; cnt < 16; cnt++) | ||
1891 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1892 | |||
1893 | WRT_REG_DWORD(®->iobase_addr, 0x4080); | ||
1894 | dmp_reg = ®->iobase_window; | ||
1895 | for (cnt = 0; cnt < 16; cnt++) | ||
1896 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1897 | |||
1898 | WRT_REG_DWORD(®->iobase_addr, 0x4090); | ||
1899 | dmp_reg = ®->iobase_window; | ||
1900 | for (cnt = 0; cnt < 16; cnt++) | ||
1901 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1902 | |||
1903 | WRT_REG_DWORD(®->iobase_addr, 0x40A0); | ||
1904 | dmp_reg = ®->iobase_window; | ||
1905 | for (cnt = 0; cnt < 16; cnt++) | ||
1906 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1907 | |||
1908 | WRT_REG_DWORD(®->iobase_addr, 0x40B0); | ||
1909 | dmp_reg = ®->iobase_window; | ||
1910 | for (cnt = 0; cnt < 16; cnt++) | ||
1911 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1912 | |||
1913 | /* Frame Buffer registers. */ | ||
1914 | iter_reg = fw->fb_hdw_reg; | ||
1915 | WRT_REG_DWORD(®->iobase_addr, 0x6000); | ||
1916 | dmp_reg = ®->iobase_window; | ||
1917 | for (cnt = 0; cnt < 16; cnt++) | ||
1918 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1919 | |||
1920 | WRT_REG_DWORD(®->iobase_addr, 0x6010); | ||
1921 | dmp_reg = ®->iobase_window; | ||
1922 | for (cnt = 0; cnt < 16; cnt++) | ||
1923 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1924 | |||
1925 | WRT_REG_DWORD(®->iobase_addr, 0x6020); | ||
1926 | dmp_reg = ®->iobase_window; | ||
1927 | for (cnt = 0; cnt < 16; cnt++) | ||
1928 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1929 | |||
1930 | WRT_REG_DWORD(®->iobase_addr, 0x6030); | ||
1931 | dmp_reg = ®->iobase_window; | ||
1932 | for (cnt = 0; cnt < 16; cnt++) | ||
1933 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1934 | |||
1935 | WRT_REG_DWORD(®->iobase_addr, 0x6040); | ||
1936 | dmp_reg = ®->iobase_window; | ||
1937 | for (cnt = 0; cnt < 16; cnt++) | ||
1938 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1939 | |||
1940 | WRT_REG_DWORD(®->iobase_addr, 0x6100); | ||
1941 | dmp_reg = ®->iobase_window; | ||
1942 | for (cnt = 0; cnt < 16; cnt++) | ||
1943 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1944 | |||
1945 | WRT_REG_DWORD(®->iobase_addr, 0x6130); | ||
1946 | dmp_reg = ®->iobase_window; | ||
1947 | for (cnt = 0; cnt < 16; cnt++) | ||
1948 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1949 | |||
1950 | WRT_REG_DWORD(®->iobase_addr, 0x6150); | ||
1951 | dmp_reg = ®->iobase_window; | ||
1952 | for (cnt = 0; cnt < 16; cnt++) | ||
1953 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1954 | |||
1955 | WRT_REG_DWORD(®->iobase_addr, 0x6170); | ||
1956 | dmp_reg = ®->iobase_window; | ||
1957 | for (cnt = 0; cnt < 16; cnt++) | ||
1958 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1959 | |||
1960 | WRT_REG_DWORD(®->iobase_addr, 0x6190); | ||
1961 | dmp_reg = ®->iobase_window; | ||
1962 | for (cnt = 0; cnt < 16; cnt++) | ||
1963 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1964 | |||
1965 | WRT_REG_DWORD(®->iobase_addr, 0x61B0); | ||
1966 | dmp_reg = ®->iobase_window; | ||
1967 | for (cnt = 0; cnt < 16; cnt++) | ||
1968 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1969 | |||
1970 | WRT_REG_DWORD(®->iobase_addr, 0x6F00); | ||
1971 | dmp_reg = ®->iobase_window; | ||
1972 | for (cnt = 0; cnt < 16; cnt++) | ||
1973 | *iter_reg++ = htonl(RD_REG_DWORD(dmp_reg++)); | ||
1974 | |||
1975 | /* Reset RISC. */ | ||
1976 | WRT_REG_DWORD(®->ctrl_status, | ||
1977 | CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); | ||
1978 | for (cnt = 0; cnt < 30000; cnt++) { | ||
1979 | if ((RD_REG_DWORD(®->ctrl_status) & | ||
1980 | CSRX_DMA_ACTIVE) == 0) | ||
1981 | break; | ||
1982 | |||
1983 | udelay(10); | ||
1984 | } | ||
1985 | |||
1986 | WRT_REG_DWORD(®->ctrl_status, | ||
1987 | CSRX_ISP_SOFT_RESET|CSRX_DMA_SHUTDOWN|MWB_4096_BYTES); | ||
1988 | pci_read_config_word(ha->pdev, PCI_COMMAND, &wd); | ||
1989 | |||
1990 | udelay(100); | ||
1991 | /* Wait for firmware to complete NVRAM accesses. */ | ||
1992 | mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); | ||
1993 | for (cnt = 10000 ; cnt && mb0; cnt--) { | ||
1994 | udelay(5); | ||
1995 | mb0 = (uint32_t) RD_REG_WORD(®->mailbox0); | ||
1996 | barrier(); | ||
1997 | } | ||
1998 | |||
1999 | /* Wait for soft-reset to complete. */ | ||
2000 | for (cnt = 0; cnt < 30000; cnt++) { | ||
2001 | if ((RD_REG_DWORD(®->ctrl_status) & | ||
2002 | CSRX_ISP_SOFT_RESET) == 0) | ||
2003 | break; | ||
2004 | |||
2005 | udelay(10); | ||
2006 | } | ||
2007 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_RESET); | ||
2008 | RD_REG_DWORD(®->hccr); /* PCI Posting. */ | ||
2009 | } | ||
2010 | |||
2011 | for (cnt = 30000; RD_REG_WORD(®->mailbox0) != 0 && | ||
2012 | rval == QLA_SUCCESS; cnt--) { | ||
2013 | if (cnt) | ||
2014 | udelay(100); | ||
2015 | else | ||
2016 | rval = QLA_FUNCTION_TIMEOUT; | ||
2017 | } | ||
2018 | |||
2019 | if (rval == QLA_SUCCESS) | ||
2020 | rval = qla2xxx_dump_memory(ha, fw->code_ram, | ||
2021 | sizeof(fw->code_ram), fw->ext_mem, &nxt); | ||
2022 | |||
2023 | if (rval == QLA_SUCCESS) { | ||
2024 | nxt = qla2xxx_copy_queues(ha, nxt); | ||
2025 | if (ha->eft) | ||
2026 | memcpy(nxt, ha->eft, ntohl(ha->fw_dump->eft_size)); | ||
2027 | } | ||
2028 | |||
2029 | if (rval != QLA_SUCCESS) { | 1329 | if (rval != QLA_SUCCESS) { |
2030 | qla_printk(KERN_WARNING, ha, | 1330 | qla_printk(KERN_WARNING, ha, |
2031 | "Failed to dump firmware (%x)!!!\n", rval); | 1331 | "Failed to dump firmware (%x)!!!\n", rval); |
@@ -2102,7 +1402,7 @@ qla2x00_print_scsi_cmd(struct scsi_cmnd * cmd) | |||
2102 | struct scsi_qla_host *ha; | 1402 | struct scsi_qla_host *ha; |
2103 | srb_t *sp; | 1403 | srb_t *sp; |
2104 | 1404 | ||
2105 | ha = (struct scsi_qla_host *)cmd->device->host->hostdata; | 1405 | ha = shost_priv(cmd->device->host); |
2106 | 1406 | ||
2107 | sp = (srb_t *) cmd->SCp.ptr; | 1407 | sp = (srb_t *) cmd->SCp.ptr; |
2108 | printk("SCSI Command @=0x%p, Handle=0x%p\n", cmd, cmd->host_scribble); | 1408 | printk("SCSI Command @=0x%p, Handle=0x%p\n", cmd, cmd->host_scribble); |
diff --git a/drivers/scsi/qla2xxx/qla_dbg.h b/drivers/scsi/qla2xxx/qla_dbg.h index cca4b0d8253e..a50ecf0b7c84 100644 --- a/drivers/scsi/qla2xxx/qla_dbg.h +++ b/drivers/scsi/qla2xxx/qla_dbg.h | |||
@@ -215,6 +215,8 @@ struct qla24xx_fw_dump { | |||
215 | 215 | ||
216 | struct qla25xx_fw_dump { | 216 | struct qla25xx_fw_dump { |
217 | uint32_t host_status; | 217 | uint32_t host_status; |
218 | uint32_t host_risc_reg[32]; | ||
219 | uint32_t pcie_regs[4]; | ||
218 | uint32_t host_reg[32]; | 220 | uint32_t host_reg[32]; |
219 | uint32_t shadow_reg[11]; | 221 | uint32_t shadow_reg[11]; |
220 | uint32_t risc_io_reg; | 222 | uint32_t risc_io_reg; |
diff --git a/drivers/scsi/qla2xxx/qla_def.h b/drivers/scsi/qla2xxx/qla_def.h index c1964866a423..1900fbf6cd74 100644 --- a/drivers/scsi/qla2xxx/qla_def.h +++ b/drivers/scsi/qla2xxx/qla_def.h | |||
@@ -23,6 +23,7 @@ | |||
23 | #include <linux/interrupt.h> | 23 | #include <linux/interrupt.h> |
24 | #include <linux/workqueue.h> | 24 | #include <linux/workqueue.h> |
25 | #include <linux/firmware.h> | 25 | #include <linux/firmware.h> |
26 | #include <linux/aer.h> | ||
26 | #include <asm/semaphore.h> | 27 | #include <asm/semaphore.h> |
27 | 28 | ||
28 | #include <scsi/scsi.h> | 29 | #include <scsi/scsi.h> |
@@ -184,8 +185,6 @@ | |||
184 | * SCSI Request Block | 185 | * SCSI Request Block |
185 | */ | 186 | */ |
186 | typedef struct srb { | 187 | typedef struct srb { |
187 | struct list_head list; | ||
188 | |||
189 | struct scsi_qla_host *ha; /* HA the SP is queued on */ | 188 | struct scsi_qla_host *ha; /* HA the SP is queued on */ |
190 | struct fc_port *fcport; | 189 | struct fc_port *fcport; |
191 | 190 | ||
@@ -316,7 +315,9 @@ struct device_reg_2xxx { | |||
316 | } u; | 315 | } u; |
317 | 316 | ||
318 | uint16_t fpm_diag_config; | 317 | uint16_t fpm_diag_config; |
319 | uint16_t unused_5[0x6]; /* Gap */ | 318 | uint16_t unused_5[0x4]; /* Gap */ |
319 | uint16_t risc_hw; | ||
320 | uint16_t unused_5_1; /* Gap */ | ||
320 | uint16_t pcr; /* Processor Control Register. */ | 321 | uint16_t pcr; /* Processor Control Register. */ |
321 | uint16_t unused_6[0x5]; /* Gap */ | 322 | uint16_t unused_6[0x5]; /* Gap */ |
322 | uint16_t mctr; /* Memory Configuration and Timing. */ | 323 | uint16_t mctr; /* Memory Configuration and Timing. */ |
@@ -1702,7 +1703,7 @@ struct ct_fdmi_hba_attributes { | |||
1702 | /* | 1703 | /* |
1703 | * Port attribute types. | 1704 | * Port attribute types. |
1704 | */ | 1705 | */ |
1705 | #define FDMI_PORT_ATTR_COUNT 5 | 1706 | #define FDMI_PORT_ATTR_COUNT 6 |
1706 | #define FDMI_PORT_FC4_TYPES 1 | 1707 | #define FDMI_PORT_FC4_TYPES 1 |
1707 | #define FDMI_PORT_SUPPORT_SPEED 2 | 1708 | #define FDMI_PORT_SUPPORT_SPEED 2 |
1708 | #define FDMI_PORT_CURRENT_SPEED 3 | 1709 | #define FDMI_PORT_CURRENT_SPEED 3 |
@@ -2476,6 +2477,8 @@ typedef struct scsi_qla_host { | |||
2476 | #define QLA_SWAITING 0 | 2477 | #define QLA_SWAITING 0 |
2477 | #define QLA_SREADING 1 | 2478 | #define QLA_SREADING 1 |
2478 | #define QLA_SWRITING 2 | 2479 | #define QLA_SWRITING 2 |
2480 | uint32_t optrom_region_start; | ||
2481 | uint32_t optrom_region_size; | ||
2479 | 2482 | ||
2480 | /* PCI expansion ROM image information. */ | 2483 | /* PCI expansion ROM image information. */ |
2481 | #define ROM_CODE_TYPE_BIOS 0 | 2484 | #define ROM_CODE_TYPE_BIOS 0 |
@@ -2529,7 +2532,7 @@ typedef struct scsi_qla_host { | |||
2529 | #define VP_ERR_FAB_NORESOURCES 3 | 2532 | #define VP_ERR_FAB_NORESOURCES 3 |
2530 | #define VP_ERR_FAB_LOGOUT 4 | 2533 | #define VP_ERR_FAB_LOGOUT 4 |
2531 | #define VP_ERR_ADAP_NORESOURCES 5 | 2534 | #define VP_ERR_ADAP_NORESOURCES 5 |
2532 | int max_npiv_vports; /* 63 or 125 per topoloty */ | 2535 | uint16_t max_npiv_vports; /* 63 or 125 per topoloty */ |
2533 | int cur_vport_count; | 2536 | int cur_vport_count; |
2534 | } scsi_qla_host_t; | 2537 | } scsi_qla_host_t; |
2535 | 2538 | ||
@@ -2542,8 +2545,6 @@ typedef struct scsi_qla_host { | |||
2542 | test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \ | 2545 | test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags) || \ |
2543 | atomic_read(&ha->loop_state) == LOOP_DOWN) | 2546 | atomic_read(&ha->loop_state) == LOOP_DOWN) |
2544 | 2547 | ||
2545 | #define to_qla_host(x) ((scsi_qla_host_t *) (x)->hostdata) | ||
2546 | |||
2547 | #define qla_printk(level, ha, format, arg...) \ | 2548 | #define qla_printk(level, ha, format, arg...) \ |
2548 | dev_printk(level , &((ha)->pdev->dev) , format , ## arg) | 2549 | dev_printk(level , &((ha)->pdev->dev) , format , ## arg) |
2549 | 2550 | ||
diff --git a/drivers/scsi/qla2xxx/qla_fw.h b/drivers/scsi/qla2xxx/qla_fw.h index 99fe49618d61..25364b1aaf12 100644 --- a/drivers/scsi/qla2xxx/qla_fw.h +++ b/drivers/scsi/qla2xxx/qla_fw.h | |||
@@ -779,6 +779,8 @@ struct device_reg_24xx { | |||
779 | #define FA_NVRAM_VPD_SIZE 0x200 | 779 | #define FA_NVRAM_VPD_SIZE 0x200 |
780 | #define FA_NVRAM_VPD0_ADDR 0x00 | 780 | #define FA_NVRAM_VPD0_ADDR 0x00 |
781 | #define FA_NVRAM_VPD1_ADDR 0x100 | 781 | #define FA_NVRAM_VPD1_ADDR 0x100 |
782 | |||
783 | #define FA_BOOT_CODE_ADDR 0x00000 | ||
782 | /* | 784 | /* |
783 | * RISC code begins at offset 512KB | 785 | * RISC code begins at offset 512KB |
784 | * within flash. Consisting of two | 786 | * within flash. Consisting of two |
@@ -940,7 +942,9 @@ struct device_reg_24xx { | |||
940 | uint16_t mailbox31; | 942 | uint16_t mailbox31; |
941 | 943 | ||
942 | uint32_t iobase_window; | 944 | uint32_t iobase_window; |
943 | uint32_t unused_4[8]; /* Gap. */ | 945 | uint32_t iobase_c4; |
946 | uint32_t iobase_c8; | ||
947 | uint32_t unused_4_1[6]; /* Gap. */ | ||
944 | uint32_t iobase_q; | 948 | uint32_t iobase_q; |
945 | uint32_t unused_5[2]; /* Gap. */ | 949 | uint32_t unused_5[2]; /* Gap. */ |
946 | uint32_t iobase_select; | 950 | uint32_t iobase_select; |
diff --git a/drivers/scsi/qla2xxx/qla_gbl.h b/drivers/scsi/qla2xxx/qla_gbl.h index aa1e41152283..09cb2a908059 100644 --- a/drivers/scsi/qla2xxx/qla_gbl.h +++ b/drivers/scsi/qla2xxx/qla_gbl.h | |||
@@ -134,6 +134,9 @@ extern int | |||
134 | qla2x00_load_ram(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t); | 134 | qla2x00_load_ram(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t); |
135 | 135 | ||
136 | extern int | 136 | extern int |
137 | qla2x00_dump_ram(scsi_qla_host_t *, dma_addr_t, uint32_t, uint32_t); | ||
138 | |||
139 | extern int | ||
137 | qla2x00_execute_fw(scsi_qla_host_t *, uint32_t); | 140 | qla2x00_execute_fw(scsi_qla_host_t *, uint32_t); |
138 | 141 | ||
139 | extern void | 142 | extern void |
@@ -212,8 +215,8 @@ extern int | |||
212 | qla2x00_get_id_list(scsi_qla_host_t *, void *, dma_addr_t, uint16_t *); | 215 | qla2x00_get_id_list(scsi_qla_host_t *, void *, dma_addr_t, uint16_t *); |
213 | 216 | ||
214 | extern int | 217 | extern int |
215 | qla2x00_get_resource_cnts(scsi_qla_host_t *, uint16_t *, uint16_t *, uint16_t *, | 218 | qla2x00_get_resource_cnts(scsi_qla_host_t *, uint16_t *, uint16_t *, |
216 | uint16_t *); | 219 | uint16_t *, uint16_t *, uint16_t *); |
217 | 220 | ||
218 | extern int | 221 | extern int |
219 | qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map); | 222 | qla2x00_get_fcal_position_map(scsi_qla_host_t *ha, char *pos_map); |
@@ -302,6 +305,8 @@ extern uint8_t *qla24xx_read_optrom_data(struct scsi_qla_host *, uint8_t *, | |||
302 | uint32_t, uint32_t); | 305 | uint32_t, uint32_t); |
303 | extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *, | 306 | extern int qla24xx_write_optrom_data(struct scsi_qla_host *, uint8_t *, |
304 | uint32_t, uint32_t); | 307 | uint32_t, uint32_t); |
308 | extern uint8_t *qla25xx_read_optrom_data(struct scsi_qla_host *, uint8_t *, | ||
309 | uint32_t, uint32_t); | ||
305 | 310 | ||
306 | extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *); | 311 | extern int qla2x00_get_flash_version(scsi_qla_host_t *, void *); |
307 | extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *); | 312 | extern int qla24xx_get_flash_version(scsi_qla_host_t *, void *); |
diff --git a/drivers/scsi/qla2xxx/qla_gs.c b/drivers/scsi/qla2xxx/qla_gs.c index a7e23583f899..eb0784c9ff83 100644 --- a/drivers/scsi/qla2xxx/qla_gs.c +++ b/drivers/scsi/qla2xxx/qla_gs.c | |||
@@ -1517,7 +1517,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha) | |||
1517 | 1517 | ||
1518 | /* Attributes */ | 1518 | /* Attributes */ |
1519 | ct_req->req.rpa.attrs.count = | 1519 | ct_req->req.rpa.attrs.count = |
1520 | __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT); | 1520 | __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT - 1); |
1521 | entries = ct_req->req.rpa.port_name; | 1521 | entries = ct_req->req.rpa.port_name; |
1522 | 1522 | ||
1523 | /* FC4 types. */ | 1523 | /* FC4 types. */ |
@@ -1600,7 +1600,7 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha) | |||
1600 | /* OS device name. */ | 1600 | /* OS device name. */ |
1601 | eiter = (struct ct_fdmi_port_attr *) (entries + size); | 1601 | eiter = (struct ct_fdmi_port_attr *) (entries + size); |
1602 | eiter->type = __constant_cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME); | 1602 | eiter->type = __constant_cpu_to_be16(FDMI_PORT_OS_DEVICE_NAME); |
1603 | sprintf(eiter->a.os_dev_name, "/proc/scsi/qla2xxx/%ld", ha->host_no); | 1603 | strcpy(eiter->a.os_dev_name, QLA2XXX_DRIVER_NAME); |
1604 | alen = strlen(eiter->a.os_dev_name); | 1604 | alen = strlen(eiter->a.os_dev_name); |
1605 | alen += (alen & 3) ? (4 - (alen & 3)) : 4; | 1605 | alen += (alen & 3) ? (4 - (alen & 3)) : 4; |
1606 | eiter->len = cpu_to_be16(4 + alen); | 1606 | eiter->len = cpu_to_be16(4 + alen); |
@@ -1611,6 +1611,8 @@ qla2x00_fdmi_rpa(scsi_qla_host_t *ha) | |||
1611 | 1611 | ||
1612 | /* Hostname. */ | 1612 | /* Hostname. */ |
1613 | if (strlen(fc_host_system_hostname(ha->host))) { | 1613 | if (strlen(fc_host_system_hostname(ha->host))) { |
1614 | ct_req->req.rpa.attrs.count = | ||
1615 | __constant_cpu_to_be32(FDMI_PORT_ATTR_COUNT); | ||
1614 | eiter = (struct ct_fdmi_port_attr *) (entries + size); | 1616 | eiter = (struct ct_fdmi_port_attr *) (entries + size); |
1615 | eiter->type = __constant_cpu_to_be16(FDMI_PORT_HOST_NAME); | 1617 | eiter->type = __constant_cpu_to_be16(FDMI_PORT_HOST_NAME); |
1616 | snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), | 1618 | snprintf(eiter->a.host_name, sizeof(eiter->a.host_name), |
diff --git a/drivers/scsi/qla2xxx/qla_init.c b/drivers/scsi/qla2xxx/qla_init.c index 1a058ec9bd0c..191dafd89be0 100644 --- a/drivers/scsi/qla2xxx/qla_init.c +++ b/drivers/scsi/qla2xxx/qla_init.c | |||
@@ -849,7 +849,8 @@ qla2x00_resize_request_q(scsi_qla_host_t *ha) | |||
849 | return; | 849 | return; |
850 | 850 | ||
851 | /* Retrieve IOCB counts available to the firmware. */ | 851 | /* Retrieve IOCB counts available to the firmware. */ |
852 | rval = qla2x00_get_resource_cnts(ha, NULL, NULL, NULL, &fw_iocb_cnt); | 852 | rval = qla2x00_get_resource_cnts(ha, NULL, NULL, NULL, &fw_iocb_cnt, |
853 | &ha->max_npiv_vports); | ||
853 | if (rval) | 854 | if (rval) |
854 | return; | 855 | return; |
855 | /* No point in continuing if current settings are sufficient. */ | 856 | /* No point in continuing if current settings are sufficient. */ |
@@ -916,9 +917,15 @@ qla2x00_setup_chip(scsi_qla_host_t *ha) | |||
916 | &ha->fw_attributes, &ha->fw_memory_size); | 917 | &ha->fw_attributes, &ha->fw_memory_size); |
917 | qla2x00_resize_request_q(ha); | 918 | qla2x00_resize_request_q(ha); |
918 | ha->flags.npiv_supported = 0; | 919 | ha->flags.npiv_supported = 0; |
919 | if (IS_QLA24XX(ha) && | 920 | if ((IS_QLA24XX(ha) || IS_QLA25XX(ha)) && |
920 | (ha->fw_attributes & BIT_2)) | 921 | (ha->fw_attributes & BIT_2)) { |
921 | ha->flags.npiv_supported = 1; | 922 | ha->flags.npiv_supported = 1; |
923 | if ((!ha->max_npiv_vports) || | ||
924 | ((ha->max_npiv_vports + 1) % | ||
925 | MAX_MULTI_ID_FABRIC)) | ||
926 | ha->max_npiv_vports = | ||
927 | MAX_NUM_VPORT_FABRIC; | ||
928 | } | ||
922 | 929 | ||
923 | if (ql2xallocfwdump) | 930 | if (ql2xallocfwdump) |
924 | qla2x00_alloc_fw_dump(ha); | 931 | qla2x00_alloc_fw_dump(ha); |
@@ -1155,8 +1162,7 @@ qla2x00_init_rings(scsi_qla_host_t *ha) | |||
1155 | 1162 | ||
1156 | DEBUG(printk("scsi(%ld): Issue init firmware.\n", ha->host_no)); | 1163 | DEBUG(printk("scsi(%ld): Issue init firmware.\n", ha->host_no)); |
1157 | 1164 | ||
1158 | mid_init_cb->count = MAX_NUM_VPORT_FABRIC; | 1165 | mid_init_cb->count = ha->max_npiv_vports; |
1159 | ha->max_npiv_vports = MAX_NUM_VPORT_FABRIC; | ||
1160 | 1166 | ||
1161 | rval = qla2x00_init_firmware(ha, ha->init_cb_size); | 1167 | rval = qla2x00_init_firmware(ha, ha->init_cb_size); |
1162 | if (rval) { | 1168 | if (rval) { |
@@ -1786,12 +1792,11 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) | |||
1786 | { | 1792 | { |
1787 | fc_port_t *fcport; | 1793 | fc_port_t *fcport; |
1788 | 1794 | ||
1789 | fcport = kmalloc(sizeof(fc_port_t), flags); | 1795 | fcport = kzalloc(sizeof(fc_port_t), flags); |
1790 | if (fcport == NULL) | 1796 | if (!fcport) |
1791 | return (fcport); | 1797 | return NULL; |
1792 | 1798 | ||
1793 | /* Setup fcport template structure. */ | 1799 | /* Setup fcport template structure. */ |
1794 | memset(fcport, 0, sizeof (fc_port_t)); | ||
1795 | fcport->ha = ha; | 1800 | fcport->ha = ha; |
1796 | fcport->vp_idx = ha->vp_idx; | 1801 | fcport->vp_idx = ha->vp_idx; |
1797 | fcport->port_type = FCT_UNKNOWN; | 1802 | fcport->port_type = FCT_UNKNOWN; |
@@ -1801,7 +1806,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *ha, gfp_t flags) | |||
1801 | fcport->supported_classes = FC_COS_UNSPECIFIED; | 1806 | fcport->supported_classes = FC_COS_UNSPECIFIED; |
1802 | spin_lock_init(&fcport->rport_lock); | 1807 | spin_lock_init(&fcport->rport_lock); |
1803 | 1808 | ||
1804 | return (fcport); | 1809 | return fcport; |
1805 | } | 1810 | } |
1806 | 1811 | ||
1807 | /* | 1812 | /* |
@@ -2127,15 +2132,9 @@ qla2x00_iidma_fcport(scsi_qla_host_t *ha, fc_port_t *fcport) | |||
2127 | if (!IS_IIDMA_CAPABLE(ha)) | 2132 | if (!IS_IIDMA_CAPABLE(ha)) |
2128 | return; | 2133 | return; |
2129 | 2134 | ||
2130 | if (fcport->fp_speed == PORT_SPEED_UNKNOWN) { | 2135 | if (fcport->fp_speed == PORT_SPEED_UNKNOWN || |
2131 | DEBUG2(printk("scsi(%ld): %02x%02x%02x%02x%02x%02x%02x%02x -- " | 2136 | fcport->fp_speed > ha->link_data_rate) |
2132 | "unsupported FM port operating speed.\n", | ||
2133 | ha->host_no, fcport->port_name[0], fcport->port_name[1], | ||
2134 | fcport->port_name[2], fcport->port_name[3], | ||
2135 | fcport->port_name[4], fcport->port_name[5], | ||
2136 | fcport->port_name[6], fcport->port_name[7])); | ||
2137 | return; | 2137 | return; |
2138 | } | ||
2139 | 2138 | ||
2140 | rval = qla2x00_set_idma_speed(ha, fcport->loop_id, fcport->fp_speed, | 2139 | rval = qla2x00_set_idma_speed(ha, fcport->loop_id, fcport->fp_speed, |
2141 | mb); | 2140 | mb); |
@@ -2473,13 +2472,12 @@ qla2x00_find_all_fabric_devs(scsi_qla_host_t *ha, struct list_head *new_fcports) | |||
2473 | rval = QLA_SUCCESS; | 2472 | rval = QLA_SUCCESS; |
2474 | 2473 | ||
2475 | /* Try GID_PT to get device list, else GAN. */ | 2474 | /* Try GID_PT to get device list, else GAN. */ |
2476 | swl = kmalloc(sizeof(sw_info_t) * MAX_FIBRE_DEVICES, GFP_ATOMIC); | 2475 | swl = kcalloc(MAX_FIBRE_DEVICES, sizeof(sw_info_t), GFP_ATOMIC); |
2477 | if (swl == NULL) { | 2476 | if (!swl) { |
2478 | /*EMPTY*/ | 2477 | /*EMPTY*/ |
2479 | DEBUG2(printk("scsi(%ld): GID_PT allocations failed, fallback " | 2478 | DEBUG2(printk("scsi(%ld): GID_PT allocations failed, fallback " |
2480 | "on GA_NXT\n", ha->host_no)); | 2479 | "on GA_NXT\n", ha->host_no)); |
2481 | } else { | 2480 | } else { |
2482 | memset(swl, 0, sizeof(sw_info_t) * MAX_FIBRE_DEVICES); | ||
2483 | if (qla2x00_gid_pt(ha, swl) != QLA_SUCCESS) { | 2481 | if (qla2x00_gid_pt(ha, swl) != QLA_SUCCESS) { |
2484 | kfree(swl); | 2482 | kfree(swl); |
2485 | swl = NULL; | 2483 | swl = NULL; |
diff --git a/drivers/scsi/qla2xxx/qla_iocb.c b/drivers/scsi/qla2xxx/qla_iocb.c index 3a5e78cb6b3f..7f6a89bd94f3 100644 --- a/drivers/scsi/qla2xxx/qla_iocb.c +++ b/drivers/scsi/qla2xxx/qla_iocb.c | |||
@@ -308,7 +308,7 @@ qla2x00_start_scsi(srb_t *sp) | |||
308 | handle++; | 308 | handle++; |
309 | if (handle == MAX_OUTSTANDING_COMMANDS) | 309 | if (handle == MAX_OUTSTANDING_COMMANDS) |
310 | handle = 1; | 310 | handle = 1; |
311 | if (ha->outstanding_cmds[handle] == 0) | 311 | if (!ha->outstanding_cmds[handle]) |
312 | break; | 312 | break; |
313 | } | 313 | } |
314 | if (index == MAX_OUTSTANDING_COMMANDS) | 314 | if (index == MAX_OUTSTANDING_COMMANDS) |
@@ -711,7 +711,7 @@ qla24xx_start_scsi(srb_t *sp) | |||
711 | handle++; | 711 | handle++; |
712 | if (handle == MAX_OUTSTANDING_COMMANDS) | 712 | if (handle == MAX_OUTSTANDING_COMMANDS) |
713 | handle = 1; | 713 | handle = 1; |
714 | if (ha->outstanding_cmds[handle] == 0) | 714 | if (!ha->outstanding_cmds[handle]) |
715 | break; | 715 | break; |
716 | } | 716 | } |
717 | if (index == MAX_OUTSTANDING_COMMANDS) | 717 | if (index == MAX_OUTSTANDING_COMMANDS) |
diff --git a/drivers/scsi/qla2xxx/qla_isr.c b/drivers/scsi/qla2xxx/qla_isr.c index eecae9905ece..c4768c4f3990 100644 --- a/drivers/scsi/qla2xxx/qla_isr.c +++ b/drivers/scsi/qla2xxx/qla_isr.c | |||
@@ -6,6 +6,7 @@ | |||
6 | */ | 6 | */ |
7 | #include "qla_def.h" | 7 | #include "qla_def.h" |
8 | 8 | ||
9 | #include <linux/delay.h> | ||
9 | #include <scsi/scsi_tcq.h> | 10 | #include <scsi/scsi_tcq.h> |
10 | 11 | ||
11 | static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t); | 12 | static void qla2x00_mbx_completion(scsi_qla_host_t *, uint16_t); |
@@ -34,6 +35,7 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
34 | int status; | 35 | int status; |
35 | unsigned long flags; | 36 | unsigned long flags; |
36 | unsigned long iter; | 37 | unsigned long iter; |
38 | uint16_t hccr; | ||
37 | uint16_t mb[4]; | 39 | uint16_t mb[4]; |
38 | 40 | ||
39 | ha = (scsi_qla_host_t *) dev_id; | 41 | ha = (scsi_qla_host_t *) dev_id; |
@@ -48,7 +50,23 @@ qla2100_intr_handler(int irq, void *dev_id) | |||
48 | 50 | ||
49 | spin_lock_irqsave(&ha->hardware_lock, flags); | 51 | spin_lock_irqsave(&ha->hardware_lock, flags); |
50 | for (iter = 50; iter--; ) { | 52 | for (iter = 50; iter--; ) { |
51 | if ((RD_REG_WORD(®->istatus) & ISR_RISC_INT) == 0) | 53 | hccr = RD_REG_WORD(®->hccr); |
54 | if (hccr & HCCR_RISC_PAUSE) { | ||
55 | if (pci_channel_offline(ha->pdev)) | ||
56 | break; | ||
57 | |||
58 | /* | ||
59 | * Issue a "HARD" reset in order for the RISC interrupt | ||
60 | * bit to be cleared. Schedule a big hammmer to get | ||
61 | * out of the RISC PAUSED state. | ||
62 | */ | ||
63 | WRT_REG_WORD(®->hccr, HCCR_RESET_RISC); | ||
64 | RD_REG_WORD(®->hccr); | ||
65 | |||
66 | ha->isp_ops->fw_dump(ha, 1); | ||
67 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | ||
68 | break; | ||
69 | } else if ((RD_REG_WORD(®->istatus) & ISR_RISC_INT) == 0) | ||
52 | break; | 70 | break; |
53 | 71 | ||
54 | if (RD_REG_WORD(®->semaphore) & BIT_0) { | 72 | if (RD_REG_WORD(®->semaphore) & BIT_0) { |
@@ -127,6 +145,9 @@ qla2300_intr_handler(int irq, void *dev_id) | |||
127 | for (iter = 50; iter--; ) { | 145 | for (iter = 50; iter--; ) { |
128 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | 146 | stat = RD_REG_DWORD(®->u.isp2300.host_status); |
129 | if (stat & HSR_RISC_PAUSED) { | 147 | if (stat & HSR_RISC_PAUSED) { |
148 | if (pci_channel_offline(ha->pdev)) | ||
149 | break; | ||
150 | |||
130 | hccr = RD_REG_WORD(®->hccr); | 151 | hccr = RD_REG_WORD(®->hccr); |
131 | if (hccr & (BIT_15 | BIT_13 | BIT_11 | BIT_8)) | 152 | if (hccr & (BIT_15 | BIT_13 | BIT_11 | BIT_8)) |
132 | qla_printk(KERN_INFO, ha, "Parity error -- " | 153 | qla_printk(KERN_INFO, ha, "Parity error -- " |
@@ -1464,6 +1485,52 @@ qla24xx_process_response_queue(struct scsi_qla_host *ha) | |||
1464 | WRT_REG_DWORD(®->rsp_q_out, ha->rsp_ring_index); | 1485 | WRT_REG_DWORD(®->rsp_q_out, ha->rsp_ring_index); |
1465 | } | 1486 | } |
1466 | 1487 | ||
1488 | static void | ||
1489 | qla2xxx_check_risc_status(scsi_qla_host_t *ha) | ||
1490 | { | ||
1491 | int rval; | ||
1492 | uint32_t cnt; | ||
1493 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | ||
1494 | |||
1495 | if (!IS_QLA25XX(ha)) | ||
1496 | return; | ||
1497 | |||
1498 | rval = QLA_SUCCESS; | ||
1499 | WRT_REG_DWORD(®->iobase_addr, 0x7C00); | ||
1500 | RD_REG_DWORD(®->iobase_addr); | ||
1501 | WRT_REG_DWORD(®->iobase_window, 0x0001); | ||
1502 | for (cnt = 10000; (RD_REG_DWORD(®->iobase_window) & BIT_0) == 0 && | ||
1503 | rval == QLA_SUCCESS; cnt--) { | ||
1504 | if (cnt) { | ||
1505 | WRT_REG_DWORD(®->iobase_window, 0x0001); | ||
1506 | udelay(10); | ||
1507 | } else | ||
1508 | rval = QLA_FUNCTION_TIMEOUT; | ||
1509 | } | ||
1510 | if (rval == QLA_SUCCESS) | ||
1511 | goto next_test; | ||
1512 | |||
1513 | WRT_REG_DWORD(®->iobase_window, 0x0003); | ||
1514 | for (cnt = 100; (RD_REG_DWORD(®->iobase_window) & BIT_0) == 0 && | ||
1515 | rval == QLA_SUCCESS; cnt--) { | ||
1516 | if (cnt) { | ||
1517 | WRT_REG_DWORD(®->iobase_window, 0x0003); | ||
1518 | udelay(10); | ||
1519 | } else | ||
1520 | rval = QLA_FUNCTION_TIMEOUT; | ||
1521 | } | ||
1522 | if (rval != QLA_SUCCESS) | ||
1523 | goto done; | ||
1524 | |||
1525 | next_test: | ||
1526 | if (RD_REG_DWORD(®->iobase_c8) & BIT_3) | ||
1527 | qla_printk(KERN_INFO, ha, "Additional code -- 0x55AA.\n"); | ||
1528 | |||
1529 | done: | ||
1530 | WRT_REG_DWORD(®->iobase_window, 0x0000); | ||
1531 | RD_REG_DWORD(®->iobase_window); | ||
1532 | } | ||
1533 | |||
1467 | /** | 1534 | /** |
1468 | * qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx. | 1535 | * qla24xx_intr_handler() - Process interrupts for the ISP23xx and ISP63xx. |
1469 | * @irq: | 1536 | * @irq: |
@@ -1499,10 +1566,16 @@ qla24xx_intr_handler(int irq, void *dev_id) | |||
1499 | for (iter = 50; iter--; ) { | 1566 | for (iter = 50; iter--; ) { |
1500 | stat = RD_REG_DWORD(®->host_status); | 1567 | stat = RD_REG_DWORD(®->host_status); |
1501 | if (stat & HSRX_RISC_PAUSED) { | 1568 | if (stat & HSRX_RISC_PAUSED) { |
1569 | if (pci_channel_offline(ha->pdev)) | ||
1570 | break; | ||
1571 | |||
1502 | hccr = RD_REG_DWORD(®->hccr); | 1572 | hccr = RD_REG_DWORD(®->hccr); |
1503 | 1573 | ||
1504 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " | 1574 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " |
1505 | "Dumping firmware!\n", hccr); | 1575 | "Dumping firmware!\n", hccr); |
1576 | |||
1577 | qla2xxx_check_risc_status(ha); | ||
1578 | |||
1506 | ha->isp_ops->fw_dump(ha, 1); | 1579 | ha->isp_ops->fw_dump(ha, 1); |
1507 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 1580 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
1508 | break; | 1581 | break; |
@@ -1606,7 +1679,6 @@ qla24xx_msix_rsp_q(int irq, void *dev_id) | |||
1606 | qla24xx_process_response_queue(ha); | 1679 | qla24xx_process_response_queue(ha); |
1607 | 1680 | ||
1608 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1681 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1609 | RD_REG_DWORD_RELAXED(®->hccr); | ||
1610 | 1682 | ||
1611 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1683 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1612 | 1684 | ||
@@ -1620,7 +1692,6 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1620 | struct device_reg_24xx __iomem *reg; | 1692 | struct device_reg_24xx __iomem *reg; |
1621 | int status; | 1693 | int status; |
1622 | unsigned long flags; | 1694 | unsigned long flags; |
1623 | unsigned long iter; | ||
1624 | uint32_t stat; | 1695 | uint32_t stat; |
1625 | uint32_t hccr; | 1696 | uint32_t hccr; |
1626 | uint16_t mb[4]; | 1697 | uint16_t mb[4]; |
@@ -1630,13 +1701,19 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1630 | status = 0; | 1701 | status = 0; |
1631 | 1702 | ||
1632 | spin_lock_irqsave(&ha->hardware_lock, flags); | 1703 | spin_lock_irqsave(&ha->hardware_lock, flags); |
1633 | for (iter = 50; iter--; ) { | 1704 | do { |
1634 | stat = RD_REG_DWORD(®->host_status); | 1705 | stat = RD_REG_DWORD(®->host_status); |
1635 | if (stat & HSRX_RISC_PAUSED) { | 1706 | if (stat & HSRX_RISC_PAUSED) { |
1707 | if (pci_channel_offline(ha->pdev)) | ||
1708 | break; | ||
1709 | |||
1636 | hccr = RD_REG_DWORD(®->hccr); | 1710 | hccr = RD_REG_DWORD(®->hccr); |
1637 | 1711 | ||
1638 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " | 1712 | qla_printk(KERN_INFO, ha, "RISC paused -- HCCR=%x, " |
1639 | "Dumping firmware!\n", hccr); | 1713 | "Dumping firmware!\n", hccr); |
1714 | |||
1715 | qla2xxx_check_risc_status(ha); | ||
1716 | |||
1640 | ha->isp_ops->fw_dump(ha, 1); | 1717 | ha->isp_ops->fw_dump(ha, 1); |
1641 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); | 1718 | set_bit(ISP_ABORT_NEEDED, &ha->dpc_flags); |
1642 | break; | 1719 | break; |
@@ -1669,8 +1746,7 @@ qla24xx_msix_default(int irq, void *dev_id) | |||
1669 | break; | 1746 | break; |
1670 | } | 1747 | } |
1671 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); | 1748 | WRT_REG_DWORD(®->hccr, HCCRX_CLR_RISC_INT); |
1672 | RD_REG_DWORD_RELAXED(®->hccr); | 1749 | } while (0); |
1673 | } | ||
1674 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | 1750 | spin_unlock_irqrestore(&ha->hardware_lock, flags); |
1675 | 1751 | ||
1676 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && | 1752 | if (test_bit(MBX_INTR_WAIT, &ha->mbx_cmd_flags) && |
diff --git a/drivers/scsi/qla2xxx/qla_mbx.c b/drivers/scsi/qla2xxx/qla_mbx.c index d3746ec80a85..c53ec67c47f4 100644 --- a/drivers/scsi/qla2xxx/qla_mbx.c +++ b/drivers/scsi/qla2xxx/qla_mbx.c | |||
@@ -391,7 +391,8 @@ qla2x00_execute_fw(scsi_qla_host_t *ha, uint32_t risc_addr) | |||
391 | mcp->mb[1] = MSW(risc_addr); | 391 | mcp->mb[1] = MSW(risc_addr); |
392 | mcp->mb[2] = LSW(risc_addr); | 392 | mcp->mb[2] = LSW(risc_addr); |
393 | mcp->mb[3] = 0; | 393 | mcp->mb[3] = 0; |
394 | mcp->out_mb |= MBX_3|MBX_2|MBX_1; | 394 | mcp->mb[4] = 0; |
395 | mcp->out_mb |= MBX_4|MBX_3|MBX_2|MBX_1; | ||
395 | mcp->in_mb |= MBX_1; | 396 | mcp->in_mb |= MBX_1; |
396 | } else { | 397 | } else { |
397 | mcp->mb[1] = LSW(risc_addr); | 398 | mcp->mb[1] = LSW(risc_addr); |
@@ -1919,7 +1920,8 @@ qla2x00_get_id_list(scsi_qla_host_t *ha, void *id_list, dma_addr_t id_list_dma, | |||
1919 | */ | 1920 | */ |
1920 | int | 1921 | int |
1921 | qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, | 1922 | qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, |
1922 | uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt, uint16_t *orig_iocb_cnt) | 1923 | uint16_t *orig_xchg_cnt, uint16_t *cur_iocb_cnt, |
1924 | uint16_t *orig_iocb_cnt, uint16_t *max_npiv_vports) | ||
1923 | { | 1925 | { |
1924 | int rval; | 1926 | int rval; |
1925 | mbx_cmd_t mc; | 1927 | mbx_cmd_t mc; |
@@ -1929,7 +1931,7 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, | |||
1929 | 1931 | ||
1930 | mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; | 1932 | mcp->mb[0] = MBC_GET_RESOURCE_COUNTS; |
1931 | mcp->out_mb = MBX_0; | 1933 | mcp->out_mb = MBX_0; |
1932 | mcp->in_mb = MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; | 1934 | mcp->in_mb = MBX_11|MBX_10|MBX_7|MBX_6|MBX_3|MBX_2|MBX_1|MBX_0; |
1933 | mcp->tov = 30; | 1935 | mcp->tov = 30; |
1934 | mcp->flags = 0; | 1936 | mcp->flags = 0; |
1935 | rval = qla2x00_mailbox_command(ha, mcp); | 1937 | rval = qla2x00_mailbox_command(ha, mcp); |
@@ -1940,9 +1942,9 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, | |||
1940 | ha->host_no, mcp->mb[0])); | 1942 | ha->host_no, mcp->mb[0])); |
1941 | } else { | 1943 | } else { |
1942 | DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x " | 1944 | DEBUG11(printk("%s(%ld): done. mb1=%x mb2=%x mb3=%x mb6=%x " |
1943 | "mb7=%x mb10=%x.\n", __func__, ha->host_no, | 1945 | "mb7=%x mb10=%x mb11=%x.\n", __func__, ha->host_no, |
1944 | mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[6], mcp->mb[7], | 1946 | mcp->mb[1], mcp->mb[2], mcp->mb[3], mcp->mb[6], mcp->mb[7], |
1945 | mcp->mb[10])); | 1947 | mcp->mb[10], mcp->mb[11])); |
1946 | 1948 | ||
1947 | if (cur_xchg_cnt) | 1949 | if (cur_xchg_cnt) |
1948 | *cur_xchg_cnt = mcp->mb[3]; | 1950 | *cur_xchg_cnt = mcp->mb[3]; |
@@ -1952,6 +1954,8 @@ qla2x00_get_resource_cnts(scsi_qla_host_t *ha, uint16_t *cur_xchg_cnt, | |||
1952 | *cur_iocb_cnt = mcp->mb[7]; | 1954 | *cur_iocb_cnt = mcp->mb[7]; |
1953 | if (orig_iocb_cnt) | 1955 | if (orig_iocb_cnt) |
1954 | *orig_iocb_cnt = mcp->mb[10]; | 1956 | *orig_iocb_cnt = mcp->mb[10]; |
1957 | if (max_npiv_vports) | ||
1958 | *max_npiv_vports = mcp->mb[11]; | ||
1955 | } | 1959 | } |
1956 | 1960 | ||
1957 | return (rval); | 1961 | return (rval); |
@@ -2980,3 +2984,51 @@ qla2x00_send_change_request(scsi_qla_host_t *ha, uint16_t format, | |||
2980 | 2984 | ||
2981 | return rval; | 2985 | return rval; |
2982 | } | 2986 | } |
2987 | |||
2988 | int | ||
2989 | qla2x00_dump_ram(scsi_qla_host_t *ha, dma_addr_t req_dma, uint32_t addr, | ||
2990 | uint32_t size) | ||
2991 | { | ||
2992 | int rval; | ||
2993 | mbx_cmd_t mc; | ||
2994 | mbx_cmd_t *mcp = &mc; | ||
2995 | |||
2996 | DEBUG11(printk("%s(%ld): entered.\n", __func__, ha->host_no)); | ||
2997 | |||
2998 | if (MSW(addr) || IS_FWI2_CAPABLE(ha)) { | ||
2999 | mcp->mb[0] = MBC_DUMP_RISC_RAM_EXTENDED; | ||
3000 | mcp->mb[8] = MSW(addr); | ||
3001 | mcp->out_mb = MBX_8|MBX_0; | ||
3002 | } else { | ||
3003 | mcp->mb[0] = MBC_DUMP_RISC_RAM; | ||
3004 | mcp->out_mb = MBX_0; | ||
3005 | } | ||
3006 | mcp->mb[1] = LSW(addr); | ||
3007 | mcp->mb[2] = MSW(req_dma); | ||
3008 | mcp->mb[3] = LSW(req_dma); | ||
3009 | mcp->mb[6] = MSW(MSD(req_dma)); | ||
3010 | mcp->mb[7] = LSW(MSD(req_dma)); | ||
3011 | mcp->out_mb |= MBX_7|MBX_6|MBX_3|MBX_2|MBX_1; | ||
3012 | if (IS_FWI2_CAPABLE(ha)) { | ||
3013 | mcp->mb[4] = MSW(size); | ||
3014 | mcp->mb[5] = LSW(size); | ||
3015 | mcp->out_mb |= MBX_5|MBX_4; | ||
3016 | } else { | ||
3017 | mcp->mb[4] = LSW(size); | ||
3018 | mcp->out_mb |= MBX_4; | ||
3019 | } | ||
3020 | |||
3021 | mcp->in_mb = MBX_0; | ||
3022 | mcp->tov = 30; | ||
3023 | mcp->flags = 0; | ||
3024 | rval = qla2x00_mailbox_command(ha, mcp); | ||
3025 | |||
3026 | if (rval != QLA_SUCCESS) { | ||
3027 | DEBUG2_3_11(printk("%s(%ld): failed=%x mb[0]=%x.\n", __func__, | ||
3028 | ha->host_no, rval, mcp->mb[0])); | ||
3029 | } else { | ||
3030 | DEBUG11(printk("%s(%ld): done.\n", __func__, ha->host_no)); | ||
3031 | } | ||
3032 | |||
3033 | return rval; | ||
3034 | } | ||
diff --git a/drivers/scsi/qla2xxx/qla_mid.c b/drivers/scsi/qla2xxx/qla_mid.c index 54dc415d8b53..821ee74aadc6 100644 --- a/drivers/scsi/qla2xxx/qla_mid.c +++ b/drivers/scsi/qla2xxx/qla_mid.c | |||
@@ -104,7 +104,7 @@ qla24xx_find_vhost_by_name(scsi_qla_host_t *ha, uint8_t *port_name) | |||
104 | * | 104 | * |
105 | * Context: | 105 | * Context: |
106 | */ | 106 | */ |
107 | void | 107 | static void |
108 | qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha) | 108 | qla2x00_mark_vp_devices_dead(scsi_qla_host_t *vha) |
109 | { | 109 | { |
110 | fc_port_t *fcport; | 110 | fc_port_t *fcport; |
@@ -179,37 +179,7 @@ enable_failed: | |||
179 | return 1; | 179 | return 1; |
180 | } | 180 | } |
181 | 181 | ||
182 | /** | 182 | static void |
183 | * qla24xx_modify_vport() - Modifies the virtual fabric port's configuration | ||
184 | * @ha: HA context | ||
185 | * @vp: pointer to buffer of virtual port parameters. | ||
186 | * @ret_code: return error code: | ||
187 | * | ||
188 | * Returns the virtual port id, or MAX_VSAN_ID, if couldn't create. | ||
189 | */ | ||
190 | uint32_t | ||
191 | qla24xx_modify_vhba(scsi_qla_host_t *ha, vport_params_t *vp, uint32_t *vp_id) | ||
192 | { | ||
193 | scsi_qla_host_t *vha; | ||
194 | |||
195 | vha = qla24xx_find_vhost_by_name(ha, vp->port_name); | ||
196 | if (!vha) { | ||
197 | *vp_id = MAX_NUM_VPORT_LOOP; | ||
198 | return VP_RET_CODE_WWPN; | ||
199 | } | ||
200 | |||
201 | if (qla24xx_enable_vp(vha)) { | ||
202 | scsi_host_put(vha->host); | ||
203 | qla2x00_mem_free(vha); | ||
204 | *vp_id = MAX_NUM_VPORT_LOOP; | ||
205 | return VP_RET_CODE_RESOURCES; | ||
206 | } | ||
207 | |||
208 | *vp_id = vha->vp_idx; | ||
209 | return VP_RET_CODE_OK; | ||
210 | } | ||
211 | |||
212 | void | ||
213 | qla24xx_configure_vp(scsi_qla_host_t *vha) | 183 | qla24xx_configure_vp(scsi_qla_host_t *vha) |
214 | { | 184 | { |
215 | struct fc_vport *fc_vport; | 185 | struct fc_vport *fc_vport; |
@@ -363,7 +333,7 @@ qla2x00_do_dpc_all_vps(scsi_qla_host_t *ha) | |||
363 | int | 333 | int |
364 | qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport) | 334 | qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport) |
365 | { | 335 | { |
366 | scsi_qla_host_t *ha = (scsi_qla_host_t *) fc_vport->shost->hostdata; | 336 | scsi_qla_host_t *ha = shost_priv(fc_vport->shost); |
367 | scsi_qla_host_t *vha; | 337 | scsi_qla_host_t *vha; |
368 | uint8_t port_name[WWN_SIZE]; | 338 | uint8_t port_name[WWN_SIZE]; |
369 | 339 | ||
@@ -397,7 +367,7 @@ qla24xx_vport_create_req_sanity_check(struct fc_vport *fc_vport) | |||
397 | scsi_qla_host_t * | 367 | scsi_qla_host_t * |
398 | qla24xx_create_vhost(struct fc_vport *fc_vport) | 368 | qla24xx_create_vhost(struct fc_vport *fc_vport) |
399 | { | 369 | { |
400 | scsi_qla_host_t *ha = (scsi_qla_host_t *) fc_vport->shost->hostdata; | 370 | scsi_qla_host_t *ha = shost_priv(fc_vport->shost); |
401 | scsi_qla_host_t *vha; | 371 | scsi_qla_host_t *vha; |
402 | struct Scsi_Host *host; | 372 | struct Scsi_Host *host; |
403 | 373 | ||
@@ -409,7 +379,7 @@ qla24xx_create_vhost(struct fc_vport *fc_vport) | |||
409 | return(NULL); | 379 | return(NULL); |
410 | } | 380 | } |
411 | 381 | ||
412 | vha = (scsi_qla_host_t *)host->hostdata; | 382 | vha = shost_priv(host); |
413 | 383 | ||
414 | /* clone the parent hba */ | 384 | /* clone the parent hba */ |
415 | memcpy(vha, ha, sizeof (scsi_qla_host_t)); | 385 | memcpy(vha, ha, sizeof (scsi_qla_host_t)); |
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c index acca898ce0a2..a6bb8d0ecf13 100644 --- a/drivers/scsi/qla2xxx/qla_os.c +++ b/drivers/scsi/qla2xxx/qla_os.c | |||
@@ -379,12 +379,17 @@ qla2x00_get_new_sp(scsi_qla_host_t *ha, fc_port_t *fcport, | |||
379 | static int | 379 | static int |
380 | qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | 380 | qla2x00_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) |
381 | { | 381 | { |
382 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); | 382 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); |
383 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; | 383 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; |
384 | struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device)); | 384 | struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device)); |
385 | srb_t *sp; | 385 | srb_t *sp; |
386 | int rval; | 386 | int rval; |
387 | 387 | ||
388 | if (unlikely(pci_channel_offline(ha->pdev))) { | ||
389 | cmd->result = DID_REQUEUE << 16; | ||
390 | goto qc_fail_command; | ||
391 | } | ||
392 | |||
388 | rval = fc_remote_port_chkready(rport); | 393 | rval = fc_remote_port_chkready(rport); |
389 | if (rval) { | 394 | if (rval) { |
390 | cmd->result = rval; | 395 | cmd->result = rval; |
@@ -440,13 +445,18 @@ qc_fail_command: | |||
440 | static int | 445 | static int |
441 | qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) | 446 | qla24xx_queuecommand(struct scsi_cmnd *cmd, void (*done)(struct scsi_cmnd *)) |
442 | { | 447 | { |
443 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); | 448 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); |
444 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; | 449 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; |
445 | struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device)); | 450 | struct fc_rport *rport = starget_to_rport(scsi_target(cmd->device)); |
446 | srb_t *sp; | 451 | srb_t *sp; |
447 | int rval; | 452 | int rval; |
448 | scsi_qla_host_t *pha = to_qla_parent(ha); | 453 | scsi_qla_host_t *pha = to_qla_parent(ha); |
449 | 454 | ||
455 | if (unlikely(pci_channel_offline(ha->pdev))) { | ||
456 | cmd->result = DID_REQUEUE << 16; | ||
457 | goto qc24_fail_command; | ||
458 | } | ||
459 | |||
450 | rval = fc_remote_port_chkready(rport); | 460 | rval = fc_remote_port_chkready(rport); |
451 | if (rval) { | 461 | if (rval) { |
452 | cmd->result = rval; | 462 | cmd->result = rval; |
@@ -653,7 +663,7 @@ qla2x00_block_error_handler(struct scsi_cmnd *cmnd) | |||
653 | static int | 663 | static int |
654 | qla2xxx_eh_abort(struct scsi_cmnd *cmd) | 664 | qla2xxx_eh_abort(struct scsi_cmnd *cmd) |
655 | { | 665 | { |
656 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); | 666 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); |
657 | srb_t *sp; | 667 | srb_t *sp; |
658 | int ret, i; | 668 | int ret, i; |
659 | unsigned int id, lun; | 669 | unsigned int id, lun; |
@@ -793,7 +803,7 @@ qla2x00_eh_wait_for_pending_target_commands(scsi_qla_host_t *ha, unsigned int t) | |||
793 | static int | 803 | static int |
794 | qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) | 804 | qla2xxx_eh_device_reset(struct scsi_cmnd *cmd) |
795 | { | 805 | { |
796 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); | 806 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); |
797 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; | 807 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; |
798 | int ret = FAILED; | 808 | int ret = FAILED; |
799 | unsigned int id, lun; | 809 | unsigned int id, lun; |
@@ -922,7 +932,7 @@ qla2x00_eh_wait_for_pending_commands(scsi_qla_host_t *ha) | |||
922 | static int | 932 | static int |
923 | qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) | 933 | qla2xxx_eh_bus_reset(struct scsi_cmnd *cmd) |
924 | { | 934 | { |
925 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); | 935 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); |
926 | scsi_qla_host_t *pha = to_qla_parent(ha); | 936 | scsi_qla_host_t *pha = to_qla_parent(ha); |
927 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; | 937 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; |
928 | int ret = FAILED; | 938 | int ret = FAILED; |
@@ -982,7 +992,7 @@ eh_bus_reset_done: | |||
982 | static int | 992 | static int |
983 | qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) | 993 | qla2xxx_eh_host_reset(struct scsi_cmnd *cmd) |
984 | { | 994 | { |
985 | scsi_qla_host_t *ha = to_qla_host(cmd->device->host); | 995 | scsi_qla_host_t *ha = shost_priv(cmd->device->host); |
986 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; | 996 | fc_port_t *fcport = (struct fc_port *) cmd->device->hostdata; |
987 | int ret = FAILED; | 997 | int ret = FAILED; |
988 | unsigned int id, lun; | 998 | unsigned int id, lun; |
@@ -1132,7 +1142,7 @@ qla2xxx_slave_alloc(struct scsi_device *sdev) | |||
1132 | static int | 1142 | static int |
1133 | qla2xxx_slave_configure(struct scsi_device *sdev) | 1143 | qla2xxx_slave_configure(struct scsi_device *sdev) |
1134 | { | 1144 | { |
1135 | scsi_qla_host_t *ha = to_qla_host(sdev->host); | 1145 | scsi_qla_host_t *ha = shost_priv(sdev->host); |
1136 | struct fc_rport *rport = starget_to_rport(sdev->sdev_target); | 1146 | struct fc_rport *rport = starget_to_rport(sdev->sdev_target); |
1137 | 1147 | ||
1138 | if (sdev->tagged_supported) | 1148 | if (sdev->tagged_supported) |
@@ -1384,7 +1394,7 @@ static struct isp_operations qla25xx_isp_ops = { | |||
1384 | .beacon_on = qla24xx_beacon_on, | 1394 | .beacon_on = qla24xx_beacon_on, |
1385 | .beacon_off = qla24xx_beacon_off, | 1395 | .beacon_off = qla24xx_beacon_off, |
1386 | .beacon_blink = qla24xx_beacon_blink, | 1396 | .beacon_blink = qla24xx_beacon_blink, |
1387 | .read_optrom = qla24xx_read_optrom_data, | 1397 | .read_optrom = qla25xx_read_optrom_data, |
1388 | .write_optrom = qla24xx_write_optrom_data, | 1398 | .write_optrom = qla24xx_write_optrom_data, |
1389 | .get_flash_version = qla24xx_get_flash_version, | 1399 | .get_flash_version = qla24xx_get_flash_version, |
1390 | }; | 1400 | }; |
@@ -1533,7 +1543,7 @@ iospace_error_exit: | |||
1533 | static void | 1543 | static void |
1534 | qla2xxx_scan_start(struct Scsi_Host *shost) | 1544 | qla2xxx_scan_start(struct Scsi_Host *shost) |
1535 | { | 1545 | { |
1536 | scsi_qla_host_t *ha = (scsi_qla_host_t *)shost->hostdata; | 1546 | scsi_qla_host_t *ha = shost_priv(shost); |
1537 | 1547 | ||
1538 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); | 1548 | set_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags); |
1539 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); | 1549 | set_bit(LOCAL_LOOP_UPDATE, &ha->dpc_flags); |
@@ -1543,7 +1553,7 @@ qla2xxx_scan_start(struct Scsi_Host *shost) | |||
1543 | static int | 1553 | static int |
1544 | qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time) | 1554 | qla2xxx_scan_finished(struct Scsi_Host *shost, unsigned long time) |
1545 | { | 1555 | { |
1546 | scsi_qla_host_t *ha = (scsi_qla_host_t *)shost->hostdata; | 1556 | scsi_qla_host_t *ha = shost_priv(shost); |
1547 | 1557 | ||
1548 | if (!ha->host) | 1558 | if (!ha->host) |
1549 | return 1; | 1559 | return 1; |
@@ -1571,6 +1581,10 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1571 | if (pci_enable_device(pdev)) | 1581 | if (pci_enable_device(pdev)) |
1572 | goto probe_out; | 1582 | goto probe_out; |
1573 | 1583 | ||
1584 | if (pci_find_aer_capability(pdev)) | ||
1585 | if (pci_enable_pcie_error_reporting(pdev)) | ||
1586 | goto probe_out; | ||
1587 | |||
1574 | sht = &qla2x00_driver_template; | 1588 | sht = &qla2x00_driver_template; |
1575 | if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || | 1589 | if (pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2422 || |
1576 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || | 1590 | pdev->device == PCI_DEVICE_ID_QLOGIC_ISP2432 || |
@@ -1586,7 +1600,7 @@ qla2x00_probe_one(struct pci_dev *pdev, const struct pci_device_id *id) | |||
1586 | } | 1600 | } |
1587 | 1601 | ||
1588 | /* Clear our data area */ | 1602 | /* Clear our data area */ |
1589 | ha = (scsi_qla_host_t *)host->hostdata; | 1603 | ha = shost_priv(host); |
1590 | memset(ha, 0, sizeof(scsi_qla_host_t)); | 1604 | memset(ha, 0, sizeof(scsi_qla_host_t)); |
1591 | 1605 | ||
1592 | ha->pdev = pdev; | 1606 | ha->pdev = pdev; |
@@ -2423,7 +2437,6 @@ qla2x00_do_dpc(void *data) | |||
2423 | if (atomic_read(&fcport->state) != FCS_ONLINE && | 2437 | if (atomic_read(&fcport->state) != FCS_ONLINE && |
2424 | fcport->login_retry) { | 2438 | fcport->login_retry) { |
2425 | 2439 | ||
2426 | fcport->login_retry--; | ||
2427 | if (fcport->flags & FCF_FABRIC_DEVICE) { | 2440 | if (fcport->flags & FCF_FABRIC_DEVICE) { |
2428 | if (fcport->flags & | 2441 | if (fcport->flags & |
2429 | FCF_TAPE_PRESENT) | 2442 | FCF_TAPE_PRESENT) |
@@ -2439,6 +2452,7 @@ qla2x00_do_dpc(void *data) | |||
2439 | qla2x00_local_device_login( | 2452 | qla2x00_local_device_login( |
2440 | ha, fcport); | 2453 | ha, fcport); |
2441 | 2454 | ||
2455 | fcport->login_retry--; | ||
2442 | if (status == QLA_SUCCESS) { | 2456 | if (status == QLA_SUCCESS) { |
2443 | fcport->old_loop_id = fcport->loop_id; | 2457 | fcport->old_loop_id = fcport->loop_id; |
2444 | 2458 | ||
@@ -2456,6 +2470,8 @@ qla2x00_do_dpc(void *data) | |||
2456 | } else { | 2470 | } else { |
2457 | fcport->login_retry = 0; | 2471 | fcport->login_retry = 0; |
2458 | } | 2472 | } |
2473 | if (fcport->login_retry == 0) | ||
2474 | fcport->loop_id = FC_NO_LOOP_ID; | ||
2459 | } | 2475 | } |
2460 | if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) | 2476 | if (test_bit(LOOP_RESYNC_NEEDED, &ha->dpc_flags)) |
2461 | break; | 2477 | break; |
@@ -2814,6 +2830,105 @@ qla2x00_release_firmware(void) | |||
2814 | up(&qla_fw_lock); | 2830 | up(&qla_fw_lock); |
2815 | } | 2831 | } |
2816 | 2832 | ||
2833 | static pci_ers_result_t | ||
2834 | qla2xxx_pci_error_detected(struct pci_dev *pdev, pci_channel_state_t state) | ||
2835 | { | ||
2836 | switch (state) { | ||
2837 | case pci_channel_io_normal: | ||
2838 | return PCI_ERS_RESULT_CAN_RECOVER; | ||
2839 | case pci_channel_io_frozen: | ||
2840 | pci_disable_device(pdev); | ||
2841 | return PCI_ERS_RESULT_NEED_RESET; | ||
2842 | case pci_channel_io_perm_failure: | ||
2843 | qla2x00_remove_one(pdev); | ||
2844 | return PCI_ERS_RESULT_DISCONNECT; | ||
2845 | } | ||
2846 | return PCI_ERS_RESULT_NEED_RESET; | ||
2847 | } | ||
2848 | |||
2849 | static pci_ers_result_t | ||
2850 | qla2xxx_pci_mmio_enabled(struct pci_dev *pdev) | ||
2851 | { | ||
2852 | int risc_paused = 0; | ||
2853 | uint32_t stat; | ||
2854 | unsigned long flags; | ||
2855 | scsi_qla_host_t *ha = pci_get_drvdata(pdev); | ||
2856 | struct device_reg_2xxx __iomem *reg = &ha->iobase->isp; | ||
2857 | struct device_reg_24xx __iomem *reg24 = &ha->iobase->isp24; | ||
2858 | |||
2859 | spin_lock_irqsave(&ha->hardware_lock, flags); | ||
2860 | if (IS_QLA2100(ha) || IS_QLA2200(ha)){ | ||
2861 | stat = RD_REG_DWORD(®->hccr); | ||
2862 | if (stat & HCCR_RISC_PAUSE) | ||
2863 | risc_paused = 1; | ||
2864 | } else if (IS_QLA23XX(ha)) { | ||
2865 | stat = RD_REG_DWORD(®->u.isp2300.host_status); | ||
2866 | if (stat & HSR_RISC_PAUSED) | ||
2867 | risc_paused = 1; | ||
2868 | } else if (IS_FWI2_CAPABLE(ha)) { | ||
2869 | stat = RD_REG_DWORD(®24->host_status); | ||
2870 | if (stat & HSRX_RISC_PAUSED) | ||
2871 | risc_paused = 1; | ||
2872 | } | ||
2873 | spin_unlock_irqrestore(&ha->hardware_lock, flags); | ||
2874 | |||
2875 | if (risc_paused) { | ||
2876 | qla_printk(KERN_INFO, ha, "RISC paused -- mmio_enabled, " | ||
2877 | "Dumping firmware!\n"); | ||
2878 | ha->isp_ops->fw_dump(ha, 0); | ||
2879 | |||
2880 | return PCI_ERS_RESULT_NEED_RESET; | ||
2881 | } else | ||
2882 | return PCI_ERS_RESULT_RECOVERED; | ||
2883 | } | ||
2884 | |||
2885 | static pci_ers_result_t | ||
2886 | qla2xxx_pci_slot_reset(struct pci_dev *pdev) | ||
2887 | { | ||
2888 | pci_ers_result_t ret = PCI_ERS_RESULT_DISCONNECT; | ||
2889 | scsi_qla_host_t *ha = pci_get_drvdata(pdev); | ||
2890 | |||
2891 | if (pci_enable_device(pdev)) { | ||
2892 | qla_printk(KERN_WARNING, ha, | ||
2893 | "Can't re-enable PCI device after reset.\n"); | ||
2894 | |||
2895 | return ret; | ||
2896 | } | ||
2897 | pci_set_master(pdev); | ||
2898 | |||
2899 | if (ha->isp_ops->pci_config(ha)) | ||
2900 | return ret; | ||
2901 | |||
2902 | set_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); | ||
2903 | if (qla2x00_abort_isp(ha)== QLA_SUCCESS) | ||
2904 | ret = PCI_ERS_RESULT_RECOVERED; | ||
2905 | clear_bit(ABORT_ISP_ACTIVE, &ha->dpc_flags); | ||
2906 | |||
2907 | return ret; | ||
2908 | } | ||
2909 | |||
2910 | static void | ||
2911 | qla2xxx_pci_resume(struct pci_dev *pdev) | ||
2912 | { | ||
2913 | scsi_qla_host_t *ha = pci_get_drvdata(pdev); | ||
2914 | int ret; | ||
2915 | |||
2916 | ret = qla2x00_wait_for_hba_online(ha); | ||
2917 | if (ret != QLA_SUCCESS) { | ||
2918 | qla_printk(KERN_ERR, ha, | ||
2919 | "the device failed to resume I/O " | ||
2920 | "from slot/link_reset"); | ||
2921 | } | ||
2922 | pci_cleanup_aer_uncorrect_error_status(pdev); | ||
2923 | } | ||
2924 | |||
2925 | static struct pci_error_handlers qla2xxx_err_handler = { | ||
2926 | .error_detected = qla2xxx_pci_error_detected, | ||
2927 | .mmio_enabled = qla2xxx_pci_mmio_enabled, | ||
2928 | .slot_reset = qla2xxx_pci_slot_reset, | ||
2929 | .resume = qla2xxx_pci_resume, | ||
2930 | }; | ||
2931 | |||
2817 | static struct pci_device_id qla2xxx_pci_tbl[] = { | 2932 | static struct pci_device_id qla2xxx_pci_tbl[] = { |
2818 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100) }, | 2933 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2100) }, |
2819 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200) }, | 2934 | { PCI_DEVICE(PCI_VENDOR_ID_QLOGIC, PCI_DEVICE_ID_QLOGIC_ISP2200) }, |
@@ -2839,6 +2954,7 @@ static struct pci_driver qla2xxx_pci_driver = { | |||
2839 | .id_table = qla2xxx_pci_tbl, | 2954 | .id_table = qla2xxx_pci_tbl, |
2840 | .probe = qla2x00_probe_one, | 2955 | .probe = qla2x00_probe_one, |
2841 | .remove = __devexit_p(qla2x00_remove_one), | 2956 | .remove = __devexit_p(qla2x00_remove_one), |
2957 | .err_handler = &qla2xxx_err_handler, | ||
2842 | }; | 2958 | }; |
2843 | 2959 | ||
2844 | /** | 2960 | /** |
diff --git a/drivers/scsi/qla2xxx/qla_sup.c b/drivers/scsi/qla2xxx/qla_sup.c index a925a3f179f9..40b059fc1981 100644 --- a/drivers/scsi/qla2xxx/qla_sup.c +++ b/drivers/scsi/qla2xxx/qla_sup.c | |||
@@ -425,6 +425,9 @@ qla2x00_set_nvram_protection(scsi_qla_host_t *ha, int stat) | |||
425 | /* Flash Manipulation Routines */ | 425 | /* Flash Manipulation Routines */ |
426 | /*****************************************************************************/ | 426 | /*****************************************************************************/ |
427 | 427 | ||
428 | #define OPTROM_BURST_SIZE 0x1000 | ||
429 | #define OPTROM_BURST_DWORDS (OPTROM_BURST_SIZE / 4) | ||
430 | |||
428 | static inline uint32_t | 431 | static inline uint32_t |
429 | flash_conf_to_access_addr(uint32_t faddr) | 432 | flash_conf_to_access_addr(uint32_t faddr) |
430 | { | 433 | { |
@@ -544,41 +547,59 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | |||
544 | uint32_t dwords) | 547 | uint32_t dwords) |
545 | { | 548 | { |
546 | int ret; | 549 | int ret; |
547 | uint32_t liter; | 550 | uint32_t liter, miter; |
548 | uint32_t sec_mask, rest_addr, conf_addr, sec_end_mask; | 551 | uint32_t sec_mask, rest_addr, conf_addr; |
549 | uint32_t fdata, findex ; | 552 | uint32_t fdata, findex ; |
550 | uint8_t man_id, flash_id; | 553 | uint8_t man_id, flash_id; |
551 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; | 554 | struct device_reg_24xx __iomem *reg = &ha->iobase->isp24; |
555 | dma_addr_t optrom_dma; | ||
556 | void *optrom = NULL; | ||
557 | uint32_t *s, *d; | ||
552 | 558 | ||
553 | ret = QLA_SUCCESS; | 559 | ret = QLA_SUCCESS; |
554 | 560 | ||
561 | /* Prepare burst-capable write on supported ISPs. */ | ||
562 | if (IS_QLA25XX(ha) && !(faddr & 0xfff) && | ||
563 | dwords > OPTROM_BURST_DWORDS) { | ||
564 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, | ||
565 | &optrom_dma, GFP_KERNEL); | ||
566 | if (!optrom) { | ||
567 | qla_printk(KERN_DEBUG, ha, | ||
568 | "Unable to allocate memory for optrom burst write " | ||
569 | "(%x KB).\n", OPTROM_BURST_SIZE / 1024); | ||
570 | } | ||
571 | } | ||
572 | |||
555 | qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id); | 573 | qla24xx_get_flash_manufacturer(ha, &man_id, &flash_id); |
556 | DEBUG9(printk("%s(%ld): Flash man_id=%d flash_id=%d\n", __func__, | 574 | DEBUG9(printk("%s(%ld): Flash man_id=%d flash_id=%d\n", __func__, |
557 | ha->host_no, man_id, flash_id)); | 575 | ha->host_no, man_id, flash_id)); |
558 | 576 | ||
559 | sec_end_mask = 0; | ||
560 | conf_addr = flash_conf_to_access_addr(0x03d8); | 577 | conf_addr = flash_conf_to_access_addr(0x03d8); |
561 | switch (man_id) { | 578 | switch (man_id) { |
562 | case 0xbf: /* STT flash. */ | 579 | case 0xbf: /* STT flash. */ |
563 | rest_addr = 0x1fff; | 580 | if (flash_id == 0x8e) { |
564 | sec_mask = 0x3e000; | 581 | rest_addr = 0x3fff; |
582 | sec_mask = 0x7c000; | ||
583 | } else { | ||
584 | rest_addr = 0x1fff; | ||
585 | sec_mask = 0x7e000; | ||
586 | } | ||
565 | if (flash_id == 0x80) | 587 | if (flash_id == 0x80) |
566 | conf_addr = flash_conf_to_access_addr(0x0352); | 588 | conf_addr = flash_conf_to_access_addr(0x0352); |
567 | break; | 589 | break; |
568 | case 0x13: /* ST M25P80. */ | 590 | case 0x13: /* ST M25P80. */ |
569 | rest_addr = 0x3fff; | 591 | rest_addr = 0x3fff; |
570 | sec_mask = 0x3c000; | 592 | sec_mask = 0x7c000; |
571 | break; | 593 | break; |
572 | case 0x1f: // Atmel 26DF081A | 594 | case 0x1f: // Atmel 26DF081A |
573 | rest_addr = 0x0fff; | 595 | rest_addr = 0x3fff; |
574 | sec_mask = 0xff000; | 596 | sec_mask = 0x7c000; |
575 | sec_end_mask = 0x003ff; | ||
576 | conf_addr = flash_conf_to_access_addr(0x0320); | 597 | conf_addr = flash_conf_to_access_addr(0x0320); |
577 | break; | 598 | break; |
578 | default: | 599 | default: |
579 | /* Default to 64 kb sector size. */ | 600 | /* Default to 64 kb sector size. */ |
580 | rest_addr = 0x3fff; | 601 | rest_addr = 0x3fff; |
581 | sec_mask = 0x3c000; | 602 | sec_mask = 0x7c000; |
582 | break; | 603 | break; |
583 | } | 604 | } |
584 | 605 | ||
@@ -592,56 +613,81 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | |||
592 | /* Some flash parts need an additional zero-write to clear bits.*/ | 613 | /* Some flash parts need an additional zero-write to clear bits.*/ |
593 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); | 614 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0); |
594 | 615 | ||
595 | do { /* Loop once to provide quick error exit. */ | 616 | for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { |
596 | for (liter = 0; liter < dwords; liter++, faddr++, dwptr++) { | 617 | if (man_id == 0x1f) { |
597 | if (man_id == 0x1f) { | 618 | findex = faddr << 2; |
598 | findex = faddr << 2; | 619 | fdata = findex & sec_mask; |
599 | fdata = findex & sec_mask; | 620 | } else { |
600 | } else { | 621 | findex = faddr; |
601 | findex = faddr; | 622 | fdata = (findex & sec_mask) << 2; |
602 | fdata = (findex & sec_mask) << 2; | 623 | } |
603 | } | ||
604 | 624 | ||
605 | /* Are we at the beginning of a sector? */ | 625 | /* Are we at the beginning of a sector? */ |
606 | if ((findex & rest_addr) == 0) { | 626 | if ((findex & rest_addr) == 0) { |
607 | /* | 627 | /* Do sector unprotect at 4K boundry for Atmel part. */ |
608 | * Do sector unprotect at 4K boundry for Atmel | 628 | if (man_id == 0x1f) |
609 | * part. | 629 | qla24xx_write_flash_dword(ha, |
610 | */ | 630 | flash_conf_to_access_addr(0x0339), |
611 | if (man_id == 0x1f) | 631 | (fdata & 0xff00) | ((fdata << 16) & |
612 | qla24xx_write_flash_dword(ha, | ||
613 | flash_conf_to_access_addr(0x0339), | ||
614 | (fdata & 0xff00) | ((fdata << 16) & | ||
615 | 0xff0000) | ((fdata >> 16) & 0xff)); | ||
616 | ret = qla24xx_write_flash_dword(ha, conf_addr, | ||
617 | (fdata & 0xff00) |((fdata << 16) & | ||
618 | 0xff0000) | ((fdata >> 16) & 0xff)); | 632 | 0xff0000) | ((fdata >> 16) & 0xff)); |
619 | if (ret != QLA_SUCCESS) { | 633 | ret = qla24xx_write_flash_dword(ha, conf_addr, |
620 | DEBUG9(printk("%s(%ld) Unable to flash " | 634 | (fdata & 0xff00) |((fdata << 16) & |
621 | "sector: address=%x.\n", __func__, | 635 | 0xff0000) | ((fdata >> 16) & 0xff)); |
622 | ha->host_no, faddr)); | 636 | if (ret != QLA_SUCCESS) { |
623 | break; | 637 | DEBUG9(printk("%s(%ld) Unable to flash " |
624 | } | 638 | "sector: address=%x.\n", __func__, |
639 | ha->host_no, faddr)); | ||
640 | break; | ||
625 | } | 641 | } |
626 | ret = qla24xx_write_flash_dword(ha, | 642 | } |
643 | |||
644 | /* Go with burst-write. */ | ||
645 | if (optrom && (liter + OPTROM_BURST_DWORDS) < dwords) { | ||
646 | /* Copy data to DMA'ble buffer. */ | ||
647 | for (miter = 0, s = optrom, d = dwptr; | ||
648 | miter < OPTROM_BURST_DWORDS; miter++, s++, d++) | ||
649 | *s = cpu_to_le32(*d); | ||
650 | |||
651 | ret = qla2x00_load_ram(ha, optrom_dma, | ||
627 | flash_data_to_access_addr(faddr), | 652 | flash_data_to_access_addr(faddr), |
628 | cpu_to_le32(*dwptr)); | 653 | OPTROM_BURST_DWORDS); |
629 | if (ret != QLA_SUCCESS) { | 654 | if (ret != QLA_SUCCESS) { |
630 | DEBUG9(printk("%s(%ld) Unable to program flash " | 655 | qla_printk(KERN_WARNING, ha, |
631 | "address=%x data=%x.\n", __func__, | 656 | "Unable to burst-write optrom segment " |
632 | ha->host_no, faddr, *dwptr)); | 657 | "(%x/%x/%llx).\n", ret, |
633 | break; | 658 | flash_data_to_access_addr(faddr), |
659 | optrom_dma); | ||
660 | qla_printk(KERN_WARNING, ha, | ||
661 | "Reverting to slow-write.\n"); | ||
662 | |||
663 | dma_free_coherent(&ha->pdev->dev, | ||
664 | OPTROM_BURST_SIZE, optrom, optrom_dma); | ||
665 | optrom = NULL; | ||
666 | } else { | ||
667 | liter += OPTROM_BURST_DWORDS - 1; | ||
668 | faddr += OPTROM_BURST_DWORDS - 1; | ||
669 | dwptr += OPTROM_BURST_DWORDS - 1; | ||
670 | continue; | ||
634 | } | 671 | } |
672 | } | ||
635 | 673 | ||
636 | /* Do sector protect at 4K boundry for Atmel part. */ | 674 | ret = qla24xx_write_flash_dword(ha, |
637 | if (man_id == 0x1f && | 675 | flash_data_to_access_addr(faddr), cpu_to_le32(*dwptr)); |
638 | ((faddr & sec_end_mask) == 0x3ff)) | 676 | if (ret != QLA_SUCCESS) { |
639 | qla24xx_write_flash_dword(ha, | 677 | DEBUG9(printk("%s(%ld) Unable to program flash " |
640 | flash_conf_to_access_addr(0x0336), | 678 | "address=%x data=%x.\n", __func__, |
641 | (fdata & 0xff00) | ((fdata << 16) & | 679 | ha->host_no, faddr, *dwptr)); |
642 | 0xff0000) | ((fdata >> 16) & 0xff)); | 680 | break; |
643 | } | 681 | } |
644 | } while (0); | 682 | |
683 | /* Do sector protect at 4K boundry for Atmel part. */ | ||
684 | if (man_id == 0x1f && | ||
685 | ((faddr & rest_addr) == rest_addr)) | ||
686 | qla24xx_write_flash_dword(ha, | ||
687 | flash_conf_to_access_addr(0x0336), | ||
688 | (fdata & 0xff00) | ((fdata << 16) & | ||
689 | 0xff0000) | ((fdata >> 16) & 0xff)); | ||
690 | } | ||
645 | 691 | ||
646 | /* Enable flash write-protection. */ | 692 | /* Enable flash write-protection. */ |
647 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0x9c); | 693 | qla24xx_write_flash_dword(ha, flash_conf_to_access_addr(0x101), 0x9c); |
@@ -651,6 +697,10 @@ qla24xx_write_flash_data(scsi_qla_host_t *ha, uint32_t *dwptr, uint32_t faddr, | |||
651 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); | 697 | RD_REG_DWORD(®->ctrl_status) & ~CSRX_FLASH_ENABLE); |
652 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ | 698 | RD_REG_DWORD(®->ctrl_status); /* PCI Posting. */ |
653 | 699 | ||
700 | if (optrom) | ||
701 | dma_free_coherent(&ha->pdev->dev, | ||
702 | OPTROM_BURST_SIZE, optrom, optrom_dma); | ||
703 | |||
654 | return ret; | 704 | return ret; |
655 | } | 705 | } |
656 | 706 | ||
@@ -1728,7 +1778,6 @@ qla24xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, | |||
1728 | { | 1778 | { |
1729 | /* Suspend HBA. */ | 1779 | /* Suspend HBA. */ |
1730 | scsi_block_requests(ha->host); | 1780 | scsi_block_requests(ha->host); |
1731 | ha->isp_ops->disable_intrs(ha); | ||
1732 | set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | 1781 | set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); |
1733 | 1782 | ||
1734 | /* Go with read. */ | 1783 | /* Go with read. */ |
@@ -1736,7 +1785,6 @@ qla24xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, | |||
1736 | 1785 | ||
1737 | /* Resume HBA. */ | 1786 | /* Resume HBA. */ |
1738 | clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | 1787 | clear_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); |
1739 | ha->isp_ops->enable_intrs(ha); | ||
1740 | scsi_unblock_requests(ha->host); | 1788 | scsi_unblock_requests(ha->host); |
1741 | 1789 | ||
1742 | return buf; | 1790 | return buf; |
@@ -1750,7 +1798,6 @@ qla24xx_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, | |||
1750 | 1798 | ||
1751 | /* Suspend HBA. */ | 1799 | /* Suspend HBA. */ |
1752 | scsi_block_requests(ha->host); | 1800 | scsi_block_requests(ha->host); |
1753 | ha->isp_ops->disable_intrs(ha); | ||
1754 | set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); | 1801 | set_bit(MBX_UPDATE_FLASH_ACTIVE, &ha->mbx_cmd_flags); |
1755 | 1802 | ||
1756 | /* Go with write. */ | 1803 | /* Go with write. */ |
@@ -1767,6 +1814,70 @@ qla24xx_write_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, | |||
1767 | return rval; | 1814 | return rval; |
1768 | } | 1815 | } |
1769 | 1816 | ||
1817 | uint8_t * | ||
1818 | qla25xx_read_optrom_data(struct scsi_qla_host *ha, uint8_t *buf, | ||
1819 | uint32_t offset, uint32_t length) | ||
1820 | { | ||
1821 | int rval; | ||
1822 | dma_addr_t optrom_dma; | ||
1823 | void *optrom; | ||
1824 | uint8_t *pbuf; | ||
1825 | uint32_t faddr, left, burst; | ||
1826 | |||
1827 | if (offset & 0xfff) | ||
1828 | goto slow_read; | ||
1829 | if (length < OPTROM_BURST_SIZE) | ||
1830 | goto slow_read; | ||
1831 | |||
1832 | optrom = dma_alloc_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, | ||
1833 | &optrom_dma, GFP_KERNEL); | ||
1834 | if (!optrom) { | ||
1835 | qla_printk(KERN_DEBUG, ha, | ||
1836 | "Unable to allocate memory for optrom burst read " | ||
1837 | "(%x KB).\n", OPTROM_BURST_SIZE / 1024); | ||
1838 | |||
1839 | goto slow_read; | ||
1840 | } | ||
1841 | |||
1842 | pbuf = buf; | ||
1843 | faddr = offset >> 2; | ||
1844 | left = length >> 2; | ||
1845 | burst = OPTROM_BURST_DWORDS; | ||
1846 | while (left != 0) { | ||
1847 | if (burst > left) | ||
1848 | burst = left; | ||
1849 | |||
1850 | rval = qla2x00_dump_ram(ha, optrom_dma, | ||
1851 | flash_data_to_access_addr(faddr), burst); | ||
1852 | if (rval) { | ||
1853 | qla_printk(KERN_WARNING, ha, | ||
1854 | "Unable to burst-read optrom segment " | ||
1855 | "(%x/%x/%llx).\n", rval, | ||
1856 | flash_data_to_access_addr(faddr), optrom_dma); | ||
1857 | qla_printk(KERN_WARNING, ha, | ||
1858 | "Reverting to slow-read.\n"); | ||
1859 | |||
1860 | dma_free_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, | ||
1861 | optrom, optrom_dma); | ||
1862 | goto slow_read; | ||
1863 | } | ||
1864 | |||
1865 | memcpy(pbuf, optrom, burst * 4); | ||
1866 | |||
1867 | left -= burst; | ||
1868 | faddr += burst; | ||
1869 | pbuf += burst * 4; | ||
1870 | } | ||
1871 | |||
1872 | dma_free_coherent(&ha->pdev->dev, OPTROM_BURST_SIZE, optrom, | ||
1873 | optrom_dma); | ||
1874 | |||
1875 | return buf; | ||
1876 | |||
1877 | slow_read: | ||
1878 | return qla24xx_read_optrom_data(ha, buf, offset, length); | ||
1879 | } | ||
1880 | |||
1770 | /** | 1881 | /** |
1771 | * qla2x00_get_fcode_version() - Determine an FCODE image's version. | 1882 | * qla2x00_get_fcode_version() - Determine an FCODE image's version. |
1772 | * @ha: HA context | 1883 | * @ha: HA context |
diff --git a/drivers/scsi/qla2xxx/qla_version.h b/drivers/scsi/qla2xxx/qla_version.h index 18095b9b76f4..2d551a3006f6 100644 --- a/drivers/scsi/qla2xxx/qla_version.h +++ b/drivers/scsi/qla2xxx/qla_version.h | |||
@@ -7,7 +7,7 @@ | |||
7 | /* | 7 | /* |
8 | * Driver version | 8 | * Driver version |
9 | */ | 9 | */ |
10 | #define QLA2XXX_VERSION "8.02.00-k3" | 10 | #define QLA2XXX_VERSION "8.02.00-k4" |
11 | 11 | ||
12 | #define QLA_DRIVER_MAJOR_VER 8 | 12 | #define QLA_DRIVER_MAJOR_VER 8 |
13 | #define QLA_DRIVER_MINOR_VER 2 | 13 | #define QLA_DRIVER_MINOR_VER 2 |
diff --git a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c index 94baca840efe..1e874f1fb5c6 100644 --- a/drivers/scsi/qlogicfas.c +++ b/drivers/scsi/qlogicfas.c | |||
@@ -166,6 +166,7 @@ static int qlogicfas_release(struct Scsi_Host *shost) | |||
166 | { | 166 | { |
167 | struct qlogicfas408_priv *priv = get_priv_by_host(shost); | 167 | struct qlogicfas408_priv *priv = get_priv_by_host(shost); |
168 | 168 | ||
169 | scsi_remove_host(shost); | ||
169 | if (shost->irq) { | 170 | if (shost->irq) { |
170 | qlogicfas408_disable_ints(priv); | 171 | qlogicfas408_disable_ints(priv); |
171 | free_irq(shost->irq, shost); | 172 | free_irq(shost->irq, shost); |
@@ -174,7 +175,6 @@ static int qlogicfas_release(struct Scsi_Host *shost) | |||
174 | free_dma(shost->dma_channel); | 175 | free_dma(shost->dma_channel); |
175 | if (shost->io_port && shost->n_io_port) | 176 | if (shost->io_port && shost->n_io_port) |
176 | release_region(shost->io_port, shost->n_io_port); | 177 | release_region(shost->io_port, shost->n_io_port); |
177 | scsi_remove_host(shost); | ||
178 | scsi_host_put(shost); | 178 | scsi_host_put(shost); |
179 | 179 | ||
180 | return 0; | 180 | return 0; |
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c index 594887205b0f..e93f80316a19 100644 --- a/drivers/scsi/qlogicpti.c +++ b/drivers/scsi/qlogicpti.c | |||
@@ -310,8 +310,6 @@ static inline void qlogicpti_set_hostdev_defaults(struct qlogicpti *qpti) | |||
310 | } | 310 | } |
311 | qpti->dev_param[i].device_enable = 1; | 311 | qpti->dev_param[i].device_enable = 1; |
312 | } | 312 | } |
313 | /* this is very important to set! */ | ||
314 | qpti->sbits = 1 << qpti->scsi_id; | ||
315 | } | 313 | } |
316 | 314 | ||
317 | static int qlogicpti_reset_hardware(struct Scsi_Host *host) | 315 | static int qlogicpti_reset_hardware(struct Scsi_Host *host) |
@@ -951,153 +949,35 @@ static inline void update_can_queue(struct Scsi_Host *host, u_int in_ptr, u_int | |||
951 | host->sg_tablesize = QLOGICPTI_MAX_SG(num_free); | 949 | host->sg_tablesize = QLOGICPTI_MAX_SG(num_free); |
952 | } | 950 | } |
953 | 951 | ||
954 | static unsigned int scsi_rbuf_get(struct scsi_cmnd *cmd, unsigned char **buf_out) | 952 | static int qlogicpti_slave_configure(struct scsi_device *sdev) |
955 | { | 953 | { |
956 | unsigned char *buf; | 954 | struct qlogicpti *qpti = shost_priv(sdev->host); |
957 | unsigned int buflen; | 955 | int tgt = sdev->id; |
958 | 956 | u_short param[6]; | |
959 | if (cmd->use_sg) { | ||
960 | struct scatterlist *sg; | ||
961 | 957 | ||
962 | sg = (struct scatterlist *) cmd->request_buffer; | 958 | /* tags handled in midlayer */ |
963 | buf = kmap_atomic(sg->page, KM_IRQ0) + sg->offset; | 959 | /* enable sync mode? */ |
964 | buflen = sg->length; | 960 | if (sdev->sdtr) { |
961 | qpti->dev_param[tgt].device_flags |= 0x10; | ||
965 | } else { | 962 | } else { |
966 | buf = cmd->request_buffer; | 963 | qpti->dev_param[tgt].synchronous_offset = 0; |
967 | buflen = cmd->request_bufflen; | 964 | qpti->dev_param[tgt].synchronous_period = 0; |
968 | } | 965 | } |
969 | 966 | /* are we wide capable? */ | |
970 | *buf_out = buf; | 967 | if (sdev->wdtr) |
971 | return buflen; | 968 | qpti->dev_param[tgt].device_flags |= 0x20; |
972 | } | 969 | |
973 | 970 | param[0] = MBOX_SET_TARGET_PARAMS; | |
974 | static void scsi_rbuf_put(struct scsi_cmnd *cmd, unsigned char *buf) | 971 | param[1] = (tgt << 8); |
975 | { | 972 | param[2] = (qpti->dev_param[tgt].device_flags << 8); |
976 | if (cmd->use_sg) { | 973 | if (qpti->dev_param[tgt].device_flags & 0x10) { |
977 | struct scatterlist *sg; | 974 | param[3] = (qpti->dev_param[tgt].synchronous_offset << 8) | |
978 | 975 | qpti->dev_param[tgt].synchronous_period; | |
979 | sg = (struct scatterlist *) cmd->request_buffer; | 976 | } else { |
980 | kunmap_atomic(buf - sg->offset, KM_IRQ0); | 977 | param[3] = 0; |
981 | } | ||
982 | } | ||
983 | |||
984 | /* | ||
985 | * Until we scan the entire bus with inquiries, go throught this fella... | ||
986 | */ | ||
987 | static void ourdone(struct scsi_cmnd *Cmnd) | ||
988 | { | ||
989 | struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->device->host->hostdata; | ||
990 | int tgt = Cmnd->device->id; | ||
991 | void (*done) (struct scsi_cmnd *); | ||
992 | |||
993 | /* This grot added by DaveM, blame him for ugliness. | ||
994 | * The issue is that in the 2.3.x driver we use the | ||
995 | * host_scribble portion of the scsi command as a | ||
996 | * completion linked list at interrupt service time, | ||
997 | * so we have to store the done function pointer elsewhere. | ||
998 | */ | ||
999 | done = (void (*)(struct scsi_cmnd *)) | ||
1000 | (((unsigned long) Cmnd->SCp.Message) | ||
1001 | #ifdef __sparc_v9__ | ||
1002 | | ((unsigned long) Cmnd->SCp.Status << 32UL) | ||
1003 | #endif | ||
1004 | ); | ||
1005 | |||
1006 | if ((qpti->sbits & (1 << tgt)) == 0) { | ||
1007 | int ok = host_byte(Cmnd->result) == DID_OK; | ||
1008 | if (Cmnd->cmnd[0] == 0x12 && ok) { | ||
1009 | unsigned char *iqd; | ||
1010 | unsigned int iqd_len; | ||
1011 | |||
1012 | iqd_len = scsi_rbuf_get(Cmnd, &iqd); | ||
1013 | |||
1014 | /* tags handled in midlayer */ | ||
1015 | /* enable sync mode? */ | ||
1016 | if (iqd[7] & 0x10) { | ||
1017 | qpti->dev_param[tgt].device_flags |= 0x10; | ||
1018 | } else { | ||
1019 | qpti->dev_param[tgt].synchronous_offset = 0; | ||
1020 | qpti->dev_param[tgt].synchronous_period = 0; | ||
1021 | } | ||
1022 | /* are we wide capable? */ | ||
1023 | if (iqd[7] & 0x20) { | ||
1024 | qpti->dev_param[tgt].device_flags |= 0x20; | ||
1025 | } | ||
1026 | |||
1027 | scsi_rbuf_put(Cmnd, iqd); | ||
1028 | |||
1029 | qpti->sbits |= (1 << tgt); | ||
1030 | } else if (!ok) { | ||
1031 | qpti->sbits |= (1 << tgt); | ||
1032 | } | ||
1033 | } | ||
1034 | done(Cmnd); | ||
1035 | } | ||
1036 | |||
1037 | static int qlogicpti_queuecommand(struct scsi_cmnd *Cmnd, void (*done)(struct scsi_cmnd *)); | ||
1038 | |||
1039 | static int qlogicpti_queuecommand_slow(struct scsi_cmnd *Cmnd, | ||
1040 | void (*done)(struct scsi_cmnd *)) | ||
1041 | { | ||
1042 | struct qlogicpti *qpti = (struct qlogicpti *) Cmnd->device->host->hostdata; | ||
1043 | |||
1044 | /* | ||
1045 | * done checking this host adapter? | ||
1046 | * If not, then rewrite the command | ||
1047 | * to finish through ourdone so we | ||
1048 | * can peek at Inquiry data results. | ||
1049 | */ | ||
1050 | if (qpti->sbits && qpti->sbits != 0xffff) { | ||
1051 | /* See above about in ourdone this ugliness... */ | ||
1052 | Cmnd->SCp.Message = ((unsigned long)done) & 0xffffffff; | ||
1053 | #ifdef CONFIG_SPARC64 | ||
1054 | Cmnd->SCp.Status = ((unsigned long)done >> 32UL) & 0xffffffff; | ||
1055 | #endif | ||
1056 | return qlogicpti_queuecommand(Cmnd, ourdone); | ||
1057 | } | ||
1058 | |||
1059 | /* | ||
1060 | * We've peeked at all targets for this bus- time | ||
1061 | * to set parameters for devices for real now. | ||
1062 | */ | ||
1063 | if (qpti->sbits == 0xffff) { | ||
1064 | int i; | ||
1065 | for(i = 0; i < MAX_TARGETS; i++) { | ||
1066 | u_short param[6]; | ||
1067 | param[0] = MBOX_SET_TARGET_PARAMS; | ||
1068 | param[1] = (i << 8); | ||
1069 | param[2] = (qpti->dev_param[i].device_flags << 8); | ||
1070 | if (qpti->dev_param[i].device_flags & 0x10) { | ||
1071 | param[3] = (qpti->dev_param[i].synchronous_offset << 8) | | ||
1072 | qpti->dev_param[i].synchronous_period; | ||
1073 | } else { | ||
1074 | param[3] = 0; | ||
1075 | } | ||
1076 | (void) qlogicpti_mbox_command(qpti, param, 0); | ||
1077 | } | ||
1078 | /* | ||
1079 | * set to zero so any traverse through ourdone | ||
1080 | * doesn't start the whole process again, | ||
1081 | */ | ||
1082 | qpti->sbits = 0; | ||
1083 | } | ||
1084 | |||
1085 | /* check to see if we're done with all adapters... */ | ||
1086 | for (qpti = qptichain; qpti != NULL; qpti = qpti->next) { | ||
1087 | if (qpti->sbits) { | ||
1088 | break; | ||
1089 | } | ||
1090 | } | 978 | } |
1091 | 979 | qlogicpti_mbox_command(qpti, param, 0); | |
1092 | /* | 980 | return 0; |
1093 | * if we hit the end of the chain w/o finding adapters still | ||
1094 | * capability-configuring, then we're done with all adapters | ||
1095 | * and can rock on.. | ||
1096 | */ | ||
1097 | if (qpti == NULL) | ||
1098 | Cmnd->device->host->hostt->queuecommand = qlogicpti_queuecommand; | ||
1099 | |||
1100 | return qlogicpti_queuecommand(Cmnd, done); | ||
1101 | } | 981 | } |
1102 | 982 | ||
1103 | /* | 983 | /* |
@@ -1390,7 +1270,8 @@ static struct scsi_host_template qpti_template = { | |||
1390 | .module = THIS_MODULE, | 1270 | .module = THIS_MODULE, |
1391 | .name = "qlogicpti", | 1271 | .name = "qlogicpti", |
1392 | .info = qlogicpti_info, | 1272 | .info = qlogicpti_info, |
1393 | .queuecommand = qlogicpti_queuecommand_slow, | 1273 | .queuecommand = qlogicpti_queuecommand, |
1274 | .slave_configure = qlogicpti_slave_configure, | ||
1394 | .eh_abort_handler = qlogicpti_abort, | 1275 | .eh_abort_handler = qlogicpti_abort, |
1395 | .eh_bus_reset_handler = qlogicpti_reset, | 1276 | .eh_bus_reset_handler = qlogicpti_reset, |
1396 | .can_queue = QLOGICPTI_REQ_QUEUE_LEN, | 1277 | .can_queue = QLOGICPTI_REQ_QUEUE_LEN, |
diff --git a/drivers/scsi/qlogicpti.h b/drivers/scsi/qlogicpti.h index 6cd1c0771d29..ef6da2df584b 100644 --- a/drivers/scsi/qlogicpti.h +++ b/drivers/scsi/qlogicpti.h | |||
@@ -380,8 +380,7 @@ struct qlogicpti { | |||
380 | unsigned char swsreg; | 380 | unsigned char swsreg; |
381 | unsigned int | 381 | unsigned int |
382 | gotirq : 1, /* this instance got an irq */ | 382 | gotirq : 1, /* this instance got an irq */ |
383 | is_pti : 1, /* Non-zero if this is a PTI board. */ | 383 | is_pti : 1; /* Non-zero if this is a PTI board. */ |
384 | sbits : 16; /* syncmode known bits */ | ||
385 | }; | 384 | }; |
386 | 385 | ||
387 | /* How to twiddle them bits... */ | 386 | /* How to twiddle them bits... */ |
diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index a5de1a829a76..192948822455 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c | |||
@@ -59,6 +59,7 @@ | |||
59 | #include <scsi/scsi_cmnd.h> | 59 | #include <scsi/scsi_cmnd.h> |
60 | #include <scsi/scsi_dbg.h> | 60 | #include <scsi/scsi_dbg.h> |
61 | #include <scsi/scsi_device.h> | 61 | #include <scsi/scsi_device.h> |
62 | #include <scsi/scsi_driver.h> | ||
62 | #include <scsi/scsi_eh.h> | 63 | #include <scsi/scsi_eh.h> |
63 | #include <scsi/scsi_host.h> | 64 | #include <scsi/scsi_host.h> |
64 | #include <scsi/scsi_tcq.h> | 65 | #include <scsi/scsi_tcq.h> |
@@ -367,9 +368,8 @@ void scsi_log_send(struct scsi_cmnd *cmd) | |||
367 | scsi_print_command(cmd); | 368 | scsi_print_command(cmd); |
368 | if (level > 3) { | 369 | if (level > 3) { |
369 | printk(KERN_INFO "buffer = 0x%p, bufflen = %d," | 370 | printk(KERN_INFO "buffer = 0x%p, bufflen = %d," |
370 | " done = 0x%p, queuecommand 0x%p\n", | 371 | " queuecommand 0x%p\n", |
371 | scsi_sglist(cmd), scsi_bufflen(cmd), | 372 | scsi_sglist(cmd), scsi_bufflen(cmd), |
372 | cmd->done, | ||
373 | cmd->device->host->hostt->queuecommand); | 373 | cmd->device->host->hostt->queuecommand); |
374 | 374 | ||
375 | } | 375 | } |
@@ -442,7 +442,7 @@ void scsi_log_completion(struct scsi_cmnd *cmd, int disposition) | |||
442 | #endif | 442 | #endif |
443 | 443 | ||
444 | /* | 444 | /* |
445 | * Assign a serial number and pid to the request for error recovery | 445 | * Assign a serial number to the request for error recovery |
446 | * and debugging purposes. Protected by the Host_Lock of host. | 446 | * and debugging purposes. Protected by the Host_Lock of host. |
447 | */ | 447 | */ |
448 | static inline void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd) | 448 | static inline void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd *cmd) |
@@ -450,10 +450,6 @@ static inline void scsi_cmd_get_serial(struct Scsi_Host *host, struct scsi_cmnd | |||
450 | cmd->serial_number = host->cmd_serial_number++; | 450 | cmd->serial_number = host->cmd_serial_number++; |
451 | if (cmd->serial_number == 0) | 451 | if (cmd->serial_number == 0) |
452 | cmd->serial_number = host->cmd_serial_number++; | 452 | cmd->serial_number = host->cmd_serial_number++; |
453 | |||
454 | cmd->pid = host->cmd_pid++; | ||
455 | if (cmd->pid == 0) | ||
456 | cmd->pid = host->cmd_pid++; | ||
457 | } | 453 | } |
458 | 454 | ||
459 | /* | 455 | /* |
@@ -658,6 +654,12 @@ void __scsi_done(struct scsi_cmnd *cmd) | |||
658 | blk_complete_request(rq); | 654 | blk_complete_request(rq); |
659 | } | 655 | } |
660 | 656 | ||
657 | /* Move this to a header if it becomes more generally useful */ | ||
658 | static struct scsi_driver *scsi_cmd_to_driver(struct scsi_cmnd *cmd) | ||
659 | { | ||
660 | return *(struct scsi_driver **)cmd->request->rq_disk->private_data; | ||
661 | } | ||
662 | |||
661 | /* | 663 | /* |
662 | * Function: scsi_finish_command | 664 | * Function: scsi_finish_command |
663 | * | 665 | * |
@@ -669,6 +671,8 @@ void scsi_finish_command(struct scsi_cmnd *cmd) | |||
669 | { | 671 | { |
670 | struct scsi_device *sdev = cmd->device; | 672 | struct scsi_device *sdev = cmd->device; |
671 | struct Scsi_Host *shost = sdev->host; | 673 | struct Scsi_Host *shost = sdev->host; |
674 | struct scsi_driver *drv; | ||
675 | unsigned int good_bytes; | ||
672 | 676 | ||
673 | scsi_device_unbusy(sdev); | 677 | scsi_device_unbusy(sdev); |
674 | 678 | ||
@@ -694,7 +698,13 @@ void scsi_finish_command(struct scsi_cmnd *cmd) | |||
694 | "Notifying upper driver of completion " | 698 | "Notifying upper driver of completion " |
695 | "(result %x)\n", cmd->result)); | 699 | "(result %x)\n", cmd->result)); |
696 | 700 | ||
697 | cmd->done(cmd); | 701 | good_bytes = cmd->request_bufflen; |
702 | if (cmd->request->cmd_type != REQ_TYPE_BLOCK_PC) { | ||
703 | drv = scsi_cmd_to_driver(cmd); | ||
704 | if (drv->done) | ||
705 | good_bytes = drv->done(cmd); | ||
706 | } | ||
707 | scsi_io_completion(cmd, good_bytes); | ||
698 | } | 708 | } |
699 | EXPORT_SYMBOL(scsi_finish_command); | 709 | EXPORT_SYMBOL(scsi_finish_command); |
700 | 710 | ||
diff --git a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c index e2ea739e33df..348cc5a6e3cd 100644 --- a/drivers/scsi/scsi_devinfo.c +++ b/drivers/scsi/scsi_devinfo.c | |||
@@ -214,6 +214,7 @@ static struct { | |||
214 | {"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, | 214 | {"PIONEER", "CD-ROM DRM-604X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, |
215 | {"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, | 215 | {"PIONEER", "CD-ROM DRM-624X", NULL, BLIST_FORCELUN | BLIST_SINGLELUN}, |
216 | {"Promise", "", NULL, BLIST_SPARSELUN}, | 216 | {"Promise", "", NULL, BLIST_SPARSELUN}, |
217 | {"QUANTUM", "XP34301", "1071", BLIST_NOTQ}, | ||
217 | {"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN}, | 218 | {"REGAL", "CDC-4X", NULL, BLIST_MAX5LUN | BLIST_SINGLELUN}, |
218 | {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN}, | 219 | {"SanDisk", "ImageMate CF-SD1", NULL, BLIST_FORCELUN}, |
219 | {"SEAGATE", "ST34555N", "0930", BLIST_NOTQ}, /* Chokes on tagged INQUIRY */ | 220 | {"SEAGATE", "ST34555N", "0930", BLIST_NOTQ}, /* Chokes on tagged INQUIRY */ |
diff --git a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c index 8a525abda30f..d29f8464b74f 100644 --- a/drivers/scsi/scsi_error.c +++ b/drivers/scsi/scsi_error.c | |||
@@ -37,6 +37,7 @@ | |||
37 | 37 | ||
38 | #include "scsi_priv.h" | 38 | #include "scsi_priv.h" |
39 | #include "scsi_logging.h" | 39 | #include "scsi_logging.h" |
40 | #include "scsi_transport_api.h" | ||
40 | 41 | ||
41 | #define SENSE_TIMEOUT (10*HZ) | 42 | #define SENSE_TIMEOUT (10*HZ) |
42 | 43 | ||
@@ -589,39 +590,23 @@ static void scsi_abort_eh_cmnd(struct scsi_cmnd *scmd) | |||
589 | } | 590 | } |
590 | 591 | ||
591 | /** | 592 | /** |
592 | * scsi_send_eh_cmnd - submit a scsi command as part of error recory | 593 | * scsi_eh_prep_cmnd - Save a scsi command info as part of error recory |
593 | * @scmd: SCSI command structure to hijack | 594 | * @scmd: SCSI command structure to hijack |
594 | * @cmnd: CDB to send | 595 | * @ses: structure to save restore information |
596 | * @cmnd: CDB to send. Can be NULL if no new cmnd is needed | ||
595 | * @cmnd_size: size in bytes of @cmnd | 597 | * @cmnd_size: size in bytes of @cmnd |
596 | * @timeout: timeout for this request | 598 | * @sense_bytes: size of sense data to copy. or 0 (if != 0 @cmnd is ignored) |
597 | * @copy_sense: request sense data if set to 1 | ||
598 | * | ||
599 | * This function is used to send a scsi command down to a target device | ||
600 | * as part of the error recovery process. If @copy_sense is 0 the command | ||
601 | * sent must be one that does not transfer any data. If @copy_sense is 1 | ||
602 | * the command must be REQUEST_SENSE and this functions copies out the | ||
603 | * sense buffer it got into @scmd->sense_buffer. | ||
604 | * | 599 | * |
605 | * Return value: | 600 | * This function is used to save a scsi command information before re-execution |
606 | * SUCCESS or FAILED or NEEDS_RETRY | 601 | * as part of the error recovery process. If @sense_bytes is 0 the command |
602 | * sent must be one that does not transfer any data. If @sense_bytes != 0 | ||
603 | * @cmnd is ignored and this functions sets up a REQUEST_SENSE command | ||
604 | * and cmnd buffers to read @sense_bytes into @scmd->sense_buffer. | ||
607 | **/ | 605 | **/ |
608 | static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | 606 | void scsi_eh_prep_cmnd(struct scsi_cmnd *scmd, struct scsi_eh_save *ses, |
609 | int cmnd_size, int timeout, int copy_sense) | 607 | unsigned char *cmnd, int cmnd_size, unsigned sense_bytes) |
610 | { | 608 | { |
611 | struct scsi_device *sdev = scmd->device; | 609 | struct scsi_device *sdev = scmd->device; |
612 | struct Scsi_Host *shost = sdev->host; | ||
613 | int old_result = scmd->result; | ||
614 | DECLARE_COMPLETION_ONSTACK(done); | ||
615 | unsigned long timeleft; | ||
616 | unsigned long flags; | ||
617 | struct scatterlist sgl; | ||
618 | unsigned char old_cmnd[MAX_COMMAND_SIZE]; | ||
619 | enum dma_data_direction old_data_direction; | ||
620 | unsigned short old_use_sg; | ||
621 | unsigned char old_cmd_len; | ||
622 | unsigned old_bufflen; | ||
623 | void *old_buffer; | ||
624 | int rtn; | ||
625 | 610 | ||
626 | /* | 611 | /* |
627 | * We need saved copies of a number of fields - this is because | 612 | * We need saved copies of a number of fields - this is because |
@@ -630,35 +615,42 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
630 | * we will need to restore these values prior to running the actual | 615 | * we will need to restore these values prior to running the actual |
631 | * command. | 616 | * command. |
632 | */ | 617 | */ |
633 | old_buffer = scmd->request_buffer; | 618 | ses->cmd_len = scmd->cmd_len; |
634 | old_bufflen = scmd->request_bufflen; | 619 | memcpy(ses->cmnd, scmd->cmnd, sizeof(scmd->cmnd)); |
635 | memcpy(old_cmnd, scmd->cmnd, sizeof(scmd->cmnd)); | 620 | ses->data_direction = scmd->sc_data_direction; |
636 | old_data_direction = scmd->sc_data_direction; | 621 | ses->bufflen = scmd->request_bufflen; |
637 | old_cmd_len = scmd->cmd_len; | 622 | ses->buffer = scmd->request_buffer; |
638 | old_use_sg = scmd->use_sg; | 623 | ses->use_sg = scmd->use_sg; |
639 | 624 | ses->resid = scmd->resid; | |
640 | memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); | 625 | ses->result = scmd->result; |
641 | memcpy(scmd->cmnd, cmnd, cmnd_size); | 626 | |
642 | 627 | if (sense_bytes) { | |
643 | if (copy_sense) { | 628 | scmd->request_bufflen = min_t(unsigned, |
644 | sg_init_one(&sgl, scmd->sense_buffer, | 629 | sizeof(scmd->sense_buffer), sense_bytes); |
645 | sizeof(scmd->sense_buffer)); | 630 | sg_init_one(&ses->sense_sgl, scmd->sense_buffer, |
646 | 631 | scmd->request_bufflen); | |
632 | scmd->request_buffer = &ses->sense_sgl; | ||
647 | scmd->sc_data_direction = DMA_FROM_DEVICE; | 633 | scmd->sc_data_direction = DMA_FROM_DEVICE; |
648 | scmd->request_bufflen = sgl.length; | ||
649 | scmd->request_buffer = &sgl; | ||
650 | scmd->use_sg = 1; | 634 | scmd->use_sg = 1; |
635 | memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); | ||
636 | scmd->cmnd[0] = REQUEST_SENSE; | ||
637 | scmd->cmnd[4] = scmd->request_bufflen; | ||
638 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); | ||
651 | } else { | 639 | } else { |
652 | scmd->request_buffer = NULL; | 640 | scmd->request_buffer = NULL; |
653 | scmd->request_bufflen = 0; | 641 | scmd->request_bufflen = 0; |
654 | scmd->sc_data_direction = DMA_NONE; | 642 | scmd->sc_data_direction = DMA_NONE; |
655 | scmd->use_sg = 0; | 643 | scmd->use_sg = 0; |
644 | if (cmnd) { | ||
645 | memset(scmd->cmnd, 0, sizeof(scmd->cmnd)); | ||
646 | memcpy(scmd->cmnd, cmnd, cmnd_size); | ||
647 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); | ||
648 | } | ||
656 | } | 649 | } |
657 | 650 | ||
658 | scmd->underflow = 0; | 651 | scmd->underflow = 0; |
659 | scmd->cmd_len = COMMAND_SIZE(scmd->cmnd[0]); | ||
660 | 652 | ||
661 | if (sdev->scsi_level <= SCSI_2) | 653 | if (sdev->scsi_level <= SCSI_2 && sdev->scsi_level != SCSI_UNKNOWN) |
662 | scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) | | 654 | scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) | |
663 | (sdev->lun << 5 & 0xe0); | 655 | (sdev->lun << 5 & 0xe0); |
664 | 656 | ||
@@ -667,7 +659,58 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
667 | * untransferred sense data should be interpreted as being zero. | 659 | * untransferred sense data should be interpreted as being zero. |
668 | */ | 660 | */ |
669 | memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); | 661 | memset(scmd->sense_buffer, 0, sizeof(scmd->sense_buffer)); |
662 | } | ||
663 | EXPORT_SYMBOL(scsi_eh_prep_cmnd); | ||
664 | |||
665 | /** | ||
666 | * scsi_eh_restore_cmnd - Restore a scsi command info as part of error recory | ||
667 | * @scmd: SCSI command structure to restore | ||
668 | * @ses: saved information from a coresponding call to scsi_prep_eh_cmnd | ||
669 | * | ||
670 | * Undo any damage done by above scsi_prep_eh_cmnd(). | ||
671 | **/ | ||
672 | void scsi_eh_restore_cmnd(struct scsi_cmnd* scmd, struct scsi_eh_save *ses) | ||
673 | { | ||
674 | /* | ||
675 | * Restore original data | ||
676 | */ | ||
677 | scmd->cmd_len = ses->cmd_len; | ||
678 | memcpy(scmd->cmnd, ses->cmnd, sizeof(scmd->cmnd)); | ||
679 | scmd->sc_data_direction = ses->data_direction; | ||
680 | scmd->request_bufflen = ses->bufflen; | ||
681 | scmd->request_buffer = ses->buffer; | ||
682 | scmd->use_sg = ses->use_sg; | ||
683 | scmd->resid = ses->resid; | ||
684 | scmd->result = ses->result; | ||
685 | } | ||
686 | EXPORT_SYMBOL(scsi_eh_restore_cmnd); | ||
670 | 687 | ||
688 | /** | ||
689 | * scsi_send_eh_cmnd - submit a scsi command as part of error recory | ||
690 | * @scmd: SCSI command structure to hijack | ||
691 | * @cmnd: CDB to send | ||
692 | * @cmnd_size: size in bytes of @cmnd | ||
693 | * @timeout: timeout for this request | ||
694 | * @sense_bytes: size of sense data to copy or 0 | ||
695 | * | ||
696 | * This function is used to send a scsi command down to a target device | ||
697 | * as part of the error recovery process. See also scsi_eh_prep_cmnd() above. | ||
698 | * | ||
699 | * Return value: | ||
700 | * SUCCESS or FAILED or NEEDS_RETRY | ||
701 | **/ | ||
702 | static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | ||
703 | int cmnd_size, int timeout, unsigned sense_bytes) | ||
704 | { | ||
705 | struct scsi_device *sdev = scmd->device; | ||
706 | struct Scsi_Host *shost = sdev->host; | ||
707 | DECLARE_COMPLETION_ONSTACK(done); | ||
708 | unsigned long timeleft; | ||
709 | unsigned long flags; | ||
710 | struct scsi_eh_save ses; | ||
711 | int rtn; | ||
712 | |||
713 | scsi_eh_prep_cmnd(scmd, &ses, cmnd, cmnd_size, sense_bytes); | ||
671 | shost->eh_action = &done; | 714 | shost->eh_action = &done; |
672 | 715 | ||
673 | spin_lock_irqsave(shost->host_lock, flags); | 716 | spin_lock_irqsave(shost->host_lock, flags); |
@@ -711,17 +754,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
711 | rtn = FAILED; | 754 | rtn = FAILED; |
712 | } | 755 | } |
713 | 756 | ||
714 | 757 | scsi_eh_restore_cmnd(scmd, &ses); | |
715 | /* | ||
716 | * Restore original data | ||
717 | */ | ||
718 | scmd->request_buffer = old_buffer; | ||
719 | scmd->request_bufflen = old_bufflen; | ||
720 | memcpy(scmd->cmnd, old_cmnd, sizeof(scmd->cmnd)); | ||
721 | scmd->sc_data_direction = old_data_direction; | ||
722 | scmd->cmd_len = old_cmd_len; | ||
723 | scmd->use_sg = old_use_sg; | ||
724 | scmd->result = old_result; | ||
725 | return rtn; | 758 | return rtn; |
726 | } | 759 | } |
727 | 760 | ||
@@ -736,10 +769,7 @@ static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, unsigned char *cmnd, | |||
736 | **/ | 769 | **/ |
737 | static int scsi_request_sense(struct scsi_cmnd *scmd) | 770 | static int scsi_request_sense(struct scsi_cmnd *scmd) |
738 | { | 771 | { |
739 | static unsigned char generic_sense[6] = | 772 | return scsi_send_eh_cmnd(scmd, NULL, 0, SENSE_TIMEOUT, ~0); |
740 | {REQUEST_SENSE, 0, 0, 0, 252, 0}; | ||
741 | |||
742 | return scsi_send_eh_cmnd(scmd, generic_sense, 6, SENSE_TIMEOUT, 1); | ||
743 | } | 773 | } |
744 | 774 | ||
745 | /** | 775 | /** |
@@ -1136,9 +1166,8 @@ static void scsi_eh_offline_sdevs(struct list_head *work_q, | |||
1136 | struct scsi_cmnd *scmd, *next; | 1166 | struct scsi_cmnd *scmd, *next; |
1137 | 1167 | ||
1138 | list_for_each_entry_safe(scmd, next, work_q, eh_entry) { | 1168 | list_for_each_entry_safe(scmd, next, work_q, eh_entry) { |
1139 | sdev_printk(KERN_INFO, scmd->device, | 1169 | sdev_printk(KERN_INFO, scmd->device, "Device offlined - " |
1140 | "scsi: Device offlined - not" | 1170 | "not ready after error recovery\n"); |
1141 | " ready after error recovery\n"); | ||
1142 | scsi_device_set_state(scmd->device, SDEV_OFFLINE); | 1171 | scsi_device_set_state(scmd->device, SDEV_OFFLINE); |
1143 | if (scmd->eh_eflags & SCSI_EH_CANCEL_CMD) { | 1172 | if (scmd->eh_eflags & SCSI_EH_CANCEL_CMD) { |
1144 | /* | 1173 | /* |
@@ -1671,7 +1700,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag) | |||
1671 | memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd)); | 1700 | memset(&scmd->cmnd, '\0', sizeof(scmd->cmnd)); |
1672 | 1701 | ||
1673 | scmd->scsi_done = scsi_reset_provider_done_command; | 1702 | scmd->scsi_done = scsi_reset_provider_done_command; |
1674 | scmd->done = NULL; | ||
1675 | scmd->request_buffer = NULL; | 1703 | scmd->request_buffer = NULL; |
1676 | scmd->request_bufflen = 0; | 1704 | scmd->request_bufflen = 0; |
1677 | 1705 | ||
@@ -1681,12 +1709,6 @@ scsi_reset_provider(struct scsi_device *dev, int flag) | |||
1681 | 1709 | ||
1682 | init_timer(&scmd->eh_timeout); | 1710 | init_timer(&scmd->eh_timeout); |
1683 | 1711 | ||
1684 | /* | ||
1685 | * Sometimes the command can get back into the timer chain, | ||
1686 | * so use the pid as an identifier. | ||
1687 | */ | ||
1688 | scmd->pid = 0; | ||
1689 | |||
1690 | spin_lock_irqsave(shost->host_lock, flags); | 1712 | spin_lock_irqsave(shost->host_lock, flags); |
1691 | shost->tmf_in_progress = 1; | 1713 | shost->tmf_in_progress = 1; |
1692 | spin_unlock_irqrestore(shost->host_lock, flags); | 1714 | spin_unlock_irqrestore(shost->host_lock, flags); |
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c index 604f4d717933..207f1aa08869 100644 --- a/drivers/scsi/scsi_lib.c +++ b/drivers/scsi/scsi_lib.c | |||
@@ -288,7 +288,7 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl, | |||
288 | { | 288 | { |
289 | struct request_queue *q = rq->q; | 289 | struct request_queue *q = rq->q; |
290 | int nr_pages = (bufflen + sgl[0].offset + PAGE_SIZE - 1) >> PAGE_SHIFT; | 290 | int nr_pages = (bufflen + sgl[0].offset + PAGE_SIZE - 1) >> PAGE_SHIFT; |
291 | unsigned int data_len = 0, len, bytes, off; | 291 | unsigned int data_len = bufflen, len, bytes, off; |
292 | struct page *page; | 292 | struct page *page; |
293 | struct bio *bio = NULL; | 293 | struct bio *bio = NULL; |
294 | int i, err, nr_vecs = 0; | 294 | int i, err, nr_vecs = 0; |
@@ -297,10 +297,15 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl, | |||
297 | page = sgl[i].page; | 297 | page = sgl[i].page; |
298 | off = sgl[i].offset; | 298 | off = sgl[i].offset; |
299 | len = sgl[i].length; | 299 | len = sgl[i].length; |
300 | data_len += len; | ||
301 | 300 | ||
302 | while (len > 0) { | 301 | while (len > 0 && data_len > 0) { |
302 | /* | ||
303 | * sg sends a scatterlist that is larger than | ||
304 | * the data_len it wants transferred for certain | ||
305 | * IO sizes | ||
306 | */ | ||
303 | bytes = min_t(unsigned int, len, PAGE_SIZE - off); | 307 | bytes = min_t(unsigned int, len, PAGE_SIZE - off); |
308 | bytes = min(bytes, data_len); | ||
304 | 309 | ||
305 | if (!bio) { | 310 | if (!bio) { |
306 | nr_vecs = min_t(int, BIO_MAX_PAGES, nr_pages); | 311 | nr_vecs = min_t(int, BIO_MAX_PAGES, nr_pages); |
@@ -332,12 +337,13 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl, | |||
332 | 337 | ||
333 | page++; | 338 | page++; |
334 | len -= bytes; | 339 | len -= bytes; |
340 | data_len -=bytes; | ||
335 | off = 0; | 341 | off = 0; |
336 | } | 342 | } |
337 | } | 343 | } |
338 | 344 | ||
339 | rq->buffer = rq->data = NULL; | 345 | rq->buffer = rq->data = NULL; |
340 | rq->data_len = data_len; | 346 | rq->data_len = bufflen; |
341 | return 0; | 347 | return 0; |
342 | 348 | ||
343 | free_bios: | 349 | free_bios: |
@@ -430,6 +436,7 @@ EXPORT_SYMBOL_GPL(scsi_execute_async); | |||
430 | static void scsi_init_cmd_errh(struct scsi_cmnd *cmd) | 436 | static void scsi_init_cmd_errh(struct scsi_cmnd *cmd) |
431 | { | 437 | { |
432 | cmd->serial_number = 0; | 438 | cmd->serial_number = 0; |
439 | cmd->resid = 0; | ||
433 | memset(cmd->sense_buffer, 0, sizeof cmd->sense_buffer); | 440 | memset(cmd->sense_buffer, 0, sizeof cmd->sense_buffer); |
434 | if (cmd->cmd_len == 0) | 441 | if (cmd->cmd_len == 0) |
435 | cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); | 442 | cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); |
@@ -924,11 +931,11 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
924 | break; | 931 | break; |
925 | } | 932 | } |
926 | } | 933 | } |
927 | if (!(req->cmd_flags & REQ_QUIET)) { | 934 | if (!(req->cmd_flags & REQ_QUIET)) |
928 | scmd_printk(KERN_INFO, cmd, | 935 | scsi_cmd_print_sense_hdr(cmd, |
929 | "Device not ready: "); | 936 | "Device not ready", |
930 | scsi_print_sense_hdr("", &sshdr); | 937 | &sshdr); |
931 | } | 938 | |
932 | scsi_end_request(cmd, 0, this_count, 1); | 939 | scsi_end_request(cmd, 0, this_count, 1); |
933 | return; | 940 | return; |
934 | case VOLUME_OVERFLOW: | 941 | case VOLUME_OVERFLOW: |
@@ -962,7 +969,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes) | |||
962 | } | 969 | } |
963 | scsi_end_request(cmd, 0, this_count, !result); | 970 | scsi_end_request(cmd, 0, this_count, !result); |
964 | } | 971 | } |
965 | EXPORT_SYMBOL(scsi_io_completion); | ||
966 | 972 | ||
967 | /* | 973 | /* |
968 | * Function: scsi_init_io() | 974 | * Function: scsi_init_io() |
@@ -1019,9 +1025,6 @@ static int scsi_init_io(struct scsi_cmnd *cmd) | |||
1019 | printk(KERN_ERR "req nr_sec %lu, cur_nr_sec %u\n", req->nr_sectors, | 1025 | printk(KERN_ERR "req nr_sec %lu, cur_nr_sec %u\n", req->nr_sectors, |
1020 | req->current_nr_sectors); | 1026 | req->current_nr_sectors); |
1021 | 1027 | ||
1022 | /* release the command and kill it */ | ||
1023 | scsi_release_buffers(cmd); | ||
1024 | scsi_put_command(cmd); | ||
1025 | return BLKPREP_KILL; | 1028 | return BLKPREP_KILL; |
1026 | } | 1029 | } |
1027 | 1030 | ||
@@ -1046,21 +1049,13 @@ static struct scsi_cmnd *scsi_get_cmd_from_req(struct scsi_device *sdev, | |||
1046 | return cmd; | 1049 | return cmd; |
1047 | } | 1050 | } |
1048 | 1051 | ||
1049 | static void scsi_blk_pc_done(struct scsi_cmnd *cmd) | 1052 | int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) |
1050 | { | ||
1051 | BUG_ON(!blk_pc_request(cmd->request)); | ||
1052 | /* | ||
1053 | * This will complete the whole command with uptodate=1 so | ||
1054 | * as far as the block layer is concerned the command completed | ||
1055 | * successfully. Since this is a REQ_BLOCK_PC command the | ||
1056 | * caller should check the request's errors value | ||
1057 | */ | ||
1058 | scsi_io_completion(cmd, cmd->request_bufflen); | ||
1059 | } | ||
1060 | |||
1061 | static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) | ||
1062 | { | 1053 | { |
1063 | struct scsi_cmnd *cmd; | 1054 | struct scsi_cmnd *cmd; |
1055 | int ret = scsi_prep_state_check(sdev, req); | ||
1056 | |||
1057 | if (ret != BLKPREP_OK) | ||
1058 | return ret; | ||
1064 | 1059 | ||
1065 | cmd = scsi_get_cmd_from_req(sdev, req); | 1060 | cmd = scsi_get_cmd_from_req(sdev, req); |
1066 | if (unlikely(!cmd)) | 1061 | if (unlikely(!cmd)) |
@@ -1103,21 +1098,22 @@ static int scsi_setup_blk_pc_cmnd(struct scsi_device *sdev, struct request *req) | |||
1103 | cmd->transfersize = req->data_len; | 1098 | cmd->transfersize = req->data_len; |
1104 | cmd->allowed = req->retries; | 1099 | cmd->allowed = req->retries; |
1105 | cmd->timeout_per_command = req->timeout; | 1100 | cmd->timeout_per_command = req->timeout; |
1106 | cmd->done = scsi_blk_pc_done; | ||
1107 | return BLKPREP_OK; | 1101 | return BLKPREP_OK; |
1108 | } | 1102 | } |
1103 | EXPORT_SYMBOL(scsi_setup_blk_pc_cmnd); | ||
1109 | 1104 | ||
1110 | /* | 1105 | /* |
1111 | * Setup a REQ_TYPE_FS command. These are simple read/write request | 1106 | * Setup a REQ_TYPE_FS command. These are simple read/write request |
1112 | * from filesystems that still need to be translated to SCSI CDBs from | 1107 | * from filesystems that still need to be translated to SCSI CDBs from |
1113 | * the ULD. | 1108 | * the ULD. |
1114 | */ | 1109 | */ |
1115 | static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) | 1110 | int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) |
1116 | { | 1111 | { |
1117 | struct scsi_cmnd *cmd; | 1112 | struct scsi_cmnd *cmd; |
1118 | struct scsi_driver *drv; | 1113 | int ret = scsi_prep_state_check(sdev, req); |
1119 | int ret; | ||
1120 | 1114 | ||
1115 | if (ret != BLKPREP_OK) | ||
1116 | return ret; | ||
1121 | /* | 1117 | /* |
1122 | * Filesystem requests must transfer data. | 1118 | * Filesystem requests must transfer data. |
1123 | */ | 1119 | */ |
@@ -1127,26 +1123,12 @@ static int scsi_setup_fs_cmnd(struct scsi_device *sdev, struct request *req) | |||
1127 | if (unlikely(!cmd)) | 1123 | if (unlikely(!cmd)) |
1128 | return BLKPREP_DEFER; | 1124 | return BLKPREP_DEFER; |
1129 | 1125 | ||
1130 | ret = scsi_init_io(cmd); | 1126 | return scsi_init_io(cmd); |
1131 | if (unlikely(ret)) | ||
1132 | return ret; | ||
1133 | |||
1134 | /* | ||
1135 | * Initialize the actual SCSI command for this request. | ||
1136 | */ | ||
1137 | drv = *(struct scsi_driver **)req->rq_disk->private_data; | ||
1138 | if (unlikely(!drv->init_command(cmd))) { | ||
1139 | scsi_release_buffers(cmd); | ||
1140 | scsi_put_command(cmd); | ||
1141 | return BLKPREP_KILL; | ||
1142 | } | ||
1143 | |||
1144 | return BLKPREP_OK; | ||
1145 | } | 1127 | } |
1128 | EXPORT_SYMBOL(scsi_setup_fs_cmnd); | ||
1146 | 1129 | ||
1147 | static int scsi_prep_fn(struct request_queue *q, struct request *req) | 1130 | int scsi_prep_state_check(struct scsi_device *sdev, struct request *req) |
1148 | { | 1131 | { |
1149 | struct scsi_device *sdev = q->queuedata; | ||
1150 | int ret = BLKPREP_OK; | 1132 | int ret = BLKPREP_OK; |
1151 | 1133 | ||
1152 | /* | 1134 | /* |
@@ -1192,35 +1174,25 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) | |||
1192 | ret = BLKPREP_KILL; | 1174 | ret = BLKPREP_KILL; |
1193 | break; | 1175 | break; |
1194 | } | 1176 | } |
1195 | |||
1196 | if (ret != BLKPREP_OK) | ||
1197 | goto out; | ||
1198 | } | 1177 | } |
1178 | return ret; | ||
1179 | } | ||
1180 | EXPORT_SYMBOL(scsi_prep_state_check); | ||
1199 | 1181 | ||
1200 | switch (req->cmd_type) { | 1182 | int scsi_prep_return(struct request_queue *q, struct request *req, int ret) |
1201 | case REQ_TYPE_BLOCK_PC: | 1183 | { |
1202 | ret = scsi_setup_blk_pc_cmnd(sdev, req); | 1184 | struct scsi_device *sdev = q->queuedata; |
1203 | break; | ||
1204 | case REQ_TYPE_FS: | ||
1205 | ret = scsi_setup_fs_cmnd(sdev, req); | ||
1206 | break; | ||
1207 | default: | ||
1208 | /* | ||
1209 | * All other command types are not supported. | ||
1210 | * | ||
1211 | * Note that these days the SCSI subsystem does not use | ||
1212 | * REQ_TYPE_SPECIAL requests anymore. These are only used | ||
1213 | * (directly or via blk_insert_request) by non-SCSI drivers. | ||
1214 | */ | ||
1215 | blk_dump_rq_flags(req, "SCSI bad req"); | ||
1216 | ret = BLKPREP_KILL; | ||
1217 | break; | ||
1218 | } | ||
1219 | 1185 | ||
1220 | out: | ||
1221 | switch (ret) { | 1186 | switch (ret) { |
1222 | case BLKPREP_KILL: | 1187 | case BLKPREP_KILL: |
1223 | req->errors = DID_NO_CONNECT << 16; | 1188 | req->errors = DID_NO_CONNECT << 16; |
1189 | /* release the command and kill it */ | ||
1190 | if (req->special) { | ||
1191 | struct scsi_cmnd *cmd = req->special; | ||
1192 | scsi_release_buffers(cmd); | ||
1193 | scsi_put_command(cmd); | ||
1194 | req->special = NULL; | ||
1195 | } | ||
1224 | break; | 1196 | break; |
1225 | case BLKPREP_DEFER: | 1197 | case BLKPREP_DEFER: |
1226 | /* | 1198 | /* |
@@ -1237,6 +1209,17 @@ static int scsi_prep_fn(struct request_queue *q, struct request *req) | |||
1237 | 1209 | ||
1238 | return ret; | 1210 | return ret; |
1239 | } | 1211 | } |
1212 | EXPORT_SYMBOL(scsi_prep_return); | ||
1213 | |||
1214 | static int scsi_prep_fn(struct request_queue *q, struct request *req) | ||
1215 | { | ||
1216 | struct scsi_device *sdev = q->queuedata; | ||
1217 | int ret = BLKPREP_KILL; | ||
1218 | |||
1219 | if (req->cmd_type == REQ_TYPE_BLOCK_PC) | ||
1220 | ret = scsi_setup_blk_pc_cmnd(sdev, req); | ||
1221 | return scsi_prep_return(q, req, ret); | ||
1222 | } | ||
1240 | 1223 | ||
1241 | /* | 1224 | /* |
1242 | * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else | 1225 | * scsi_dev_queue_ready: if we can send requests to sdev, return 1 else |
diff --git a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h index ee8efe849bf4..eff005951895 100644 --- a/drivers/scsi/scsi_priv.h +++ b/drivers/scsi/scsi_priv.h | |||
@@ -68,6 +68,7 @@ extern int scsi_maybe_unblock_host(struct scsi_device *sdev); | |||
68 | extern void scsi_device_unbusy(struct scsi_device *sdev); | 68 | extern void scsi_device_unbusy(struct scsi_device *sdev); |
69 | extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason); | 69 | extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason); |
70 | extern void scsi_next_command(struct scsi_cmnd *cmd); | 70 | extern void scsi_next_command(struct scsi_cmnd *cmd); |
71 | extern void scsi_io_completion(struct scsi_cmnd *, unsigned int); | ||
71 | extern void scsi_run_host_queues(struct Scsi_Host *shost); | 72 | extern void scsi_run_host_queues(struct Scsi_Host *shost); |
72 | extern struct request_queue *scsi_alloc_queue(struct scsi_device *sdev); | 73 | extern struct request_queue *scsi_alloc_queue(struct scsi_device *sdev); |
73 | extern void scsi_free_queue(struct request_queue *q); | 74 | extern void scsi_free_queue(struct request_queue *q); |
diff --git a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c index a86e62f4b3ba..b53c5f67e372 100644 --- a/drivers/scsi/scsi_scan.c +++ b/drivers/scsi/scsi_scan.c | |||
@@ -85,7 +85,7 @@ static unsigned int max_scsi_luns = MAX_SCSI_LUNS; | |||
85 | static unsigned int max_scsi_luns = 1; | 85 | static unsigned int max_scsi_luns = 1; |
86 | #endif | 86 | #endif |
87 | 87 | ||
88 | module_param_named(max_luns, max_scsi_luns, int, S_IRUGO|S_IWUSR); | 88 | module_param_named(max_luns, max_scsi_luns, uint, S_IRUGO|S_IWUSR); |
89 | MODULE_PARM_DESC(max_luns, | 89 | MODULE_PARM_DESC(max_luns, |
90 | "last scsi LUN (should be between 1 and 2^32-1)"); | 90 | "last scsi LUN (should be between 1 and 2^32-1)"); |
91 | 91 | ||
@@ -109,18 +109,19 @@ MODULE_PARM_DESC(scan, "sync, async or none"); | |||
109 | */ | 109 | */ |
110 | static unsigned int max_scsi_report_luns = 511; | 110 | static unsigned int max_scsi_report_luns = 511; |
111 | 111 | ||
112 | module_param_named(max_report_luns, max_scsi_report_luns, int, S_IRUGO|S_IWUSR); | 112 | module_param_named(max_report_luns, max_scsi_report_luns, uint, S_IRUGO|S_IWUSR); |
113 | MODULE_PARM_DESC(max_report_luns, | 113 | MODULE_PARM_DESC(max_report_luns, |
114 | "REPORT LUNS maximum number of LUNS received (should be" | 114 | "REPORT LUNS maximum number of LUNS received (should be" |
115 | " between 1 and 16384)"); | 115 | " between 1 and 16384)"); |
116 | 116 | ||
117 | static unsigned int scsi_inq_timeout = SCSI_TIMEOUT/HZ+3; | 117 | static unsigned int scsi_inq_timeout = SCSI_TIMEOUT/HZ+3; |
118 | 118 | ||
119 | module_param_named(inq_timeout, scsi_inq_timeout, int, S_IRUGO|S_IWUSR); | 119 | module_param_named(inq_timeout, scsi_inq_timeout, uint, S_IRUGO|S_IWUSR); |
120 | MODULE_PARM_DESC(inq_timeout, | 120 | MODULE_PARM_DESC(inq_timeout, |
121 | "Timeout (in seconds) waiting for devices to answer INQUIRY." | 121 | "Timeout (in seconds) waiting for devices to answer INQUIRY." |
122 | " Default is 5. Some non-compliant devices need more."); | 122 | " Default is 5. Some non-compliant devices need more."); |
123 | 123 | ||
124 | /* This lock protects only this list */ | ||
124 | static DEFINE_SPINLOCK(async_scan_lock); | 125 | static DEFINE_SPINLOCK(async_scan_lock); |
125 | static LIST_HEAD(scanning_hosts); | 126 | static LIST_HEAD(scanning_hosts); |
126 | 127 | ||
@@ -1466,14 +1467,14 @@ struct scsi_device *__scsi_add_device(struct Scsi_Host *shost, uint channel, | |||
1466 | if (strncmp(scsi_scan_type, "none", 4) == 0) | 1467 | if (strncmp(scsi_scan_type, "none", 4) == 0) |
1467 | return ERR_PTR(-ENODEV); | 1468 | return ERR_PTR(-ENODEV); |
1468 | 1469 | ||
1469 | if (!shost->async_scan) | ||
1470 | scsi_complete_async_scans(); | ||
1471 | |||
1472 | starget = scsi_alloc_target(parent, channel, id); | 1470 | starget = scsi_alloc_target(parent, channel, id); |
1473 | if (!starget) | 1471 | if (!starget) |
1474 | return ERR_PTR(-ENOMEM); | 1472 | return ERR_PTR(-ENOMEM); |
1475 | 1473 | ||
1476 | mutex_lock(&shost->scan_mutex); | 1474 | mutex_lock(&shost->scan_mutex); |
1475 | if (!shost->async_scan) | ||
1476 | scsi_complete_async_scans(); | ||
1477 | |||
1477 | if (scsi_host_scan_allowed(shost)) | 1478 | if (scsi_host_scan_allowed(shost)) |
1478 | scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata); | 1479 | scsi_probe_and_add_lun(starget, lun, NULL, &sdev, 1, hostdata); |
1479 | mutex_unlock(&shost->scan_mutex); | 1480 | mutex_unlock(&shost->scan_mutex); |
@@ -1586,10 +1587,10 @@ void scsi_scan_target(struct device *parent, unsigned int channel, | |||
1586 | if (strncmp(scsi_scan_type, "none", 4) == 0) | 1587 | if (strncmp(scsi_scan_type, "none", 4) == 0) |
1587 | return; | 1588 | return; |
1588 | 1589 | ||
1590 | mutex_lock(&shost->scan_mutex); | ||
1589 | if (!shost->async_scan) | 1591 | if (!shost->async_scan) |
1590 | scsi_complete_async_scans(); | 1592 | scsi_complete_async_scans(); |
1591 | 1593 | ||
1592 | mutex_lock(&shost->scan_mutex); | ||
1593 | if (scsi_host_scan_allowed(shost)) | 1594 | if (scsi_host_scan_allowed(shost)) |
1594 | __scsi_scan_target(parent, channel, id, lun, rescan); | 1595 | __scsi_scan_target(parent, channel, id, lun, rescan); |
1595 | mutex_unlock(&shost->scan_mutex); | 1596 | mutex_unlock(&shost->scan_mutex); |
@@ -1634,15 +1635,15 @@ int scsi_scan_host_selected(struct Scsi_Host *shost, unsigned int channel, | |||
1634 | "%s: <%u:%u:%u>\n", | 1635 | "%s: <%u:%u:%u>\n", |
1635 | __FUNCTION__, channel, id, lun)); | 1636 | __FUNCTION__, channel, id, lun)); |
1636 | 1637 | ||
1637 | if (!shost->async_scan) | ||
1638 | scsi_complete_async_scans(); | ||
1639 | |||
1640 | if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || | 1638 | if (((channel != SCAN_WILD_CARD) && (channel > shost->max_channel)) || |
1641 | ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) || | 1639 | ((id != SCAN_WILD_CARD) && (id >= shost->max_id)) || |
1642 | ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun))) | 1640 | ((lun != SCAN_WILD_CARD) && (lun > shost->max_lun))) |
1643 | return -EINVAL; | 1641 | return -EINVAL; |
1644 | 1642 | ||
1645 | mutex_lock(&shost->scan_mutex); | 1643 | mutex_lock(&shost->scan_mutex); |
1644 | if (!shost->async_scan) | ||
1645 | scsi_complete_async_scans(); | ||
1646 | |||
1646 | if (scsi_host_scan_allowed(shost)) { | 1647 | if (scsi_host_scan_allowed(shost)) { |
1647 | if (channel == SCAN_WILD_CARD) | 1648 | if (channel == SCAN_WILD_CARD) |
1648 | for (channel = 0; channel <= shost->max_channel; | 1649 | for (channel = 0; channel <= shost->max_channel; |
@@ -1661,7 +1662,8 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost) | |||
1661 | { | 1662 | { |
1662 | struct scsi_device *sdev; | 1663 | struct scsi_device *sdev; |
1663 | shost_for_each_device(sdev, shost) { | 1664 | shost_for_each_device(sdev, shost) { |
1664 | if (scsi_sysfs_add_sdev(sdev) != 0) | 1665 | if (!scsi_host_scan_allowed(shost) || |
1666 | scsi_sysfs_add_sdev(sdev) != 0) | ||
1665 | scsi_destroy_sdev(sdev); | 1667 | scsi_destroy_sdev(sdev); |
1666 | } | 1668 | } |
1667 | } | 1669 | } |
@@ -1679,6 +1681,7 @@ static void scsi_sysfs_add_devices(struct Scsi_Host *shost) | |||
1679 | static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) | 1681 | static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) |
1680 | { | 1682 | { |
1681 | struct async_scan_data *data; | 1683 | struct async_scan_data *data; |
1684 | unsigned long flags; | ||
1682 | 1685 | ||
1683 | if (strncmp(scsi_scan_type, "sync", 4) == 0) | 1686 | if (strncmp(scsi_scan_type, "sync", 4) == 0) |
1684 | return NULL; | 1687 | return NULL; |
@@ -1698,8 +1701,13 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) | |||
1698 | goto err; | 1701 | goto err; |
1699 | init_completion(&data->prev_finished); | 1702 | init_completion(&data->prev_finished); |
1700 | 1703 | ||
1701 | spin_lock(&async_scan_lock); | 1704 | mutex_lock(&shost->scan_mutex); |
1705 | spin_lock_irqsave(shost->host_lock, flags); | ||
1702 | shost->async_scan = 1; | 1706 | shost->async_scan = 1; |
1707 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1708 | mutex_unlock(&shost->scan_mutex); | ||
1709 | |||
1710 | spin_lock(&async_scan_lock); | ||
1703 | if (list_empty(&scanning_hosts)) | 1711 | if (list_empty(&scanning_hosts)) |
1704 | complete(&data->prev_finished); | 1712 | complete(&data->prev_finished); |
1705 | list_add_tail(&data->list, &scanning_hosts); | 1713 | list_add_tail(&data->list, &scanning_hosts); |
@@ -1723,11 +1731,15 @@ static struct async_scan_data *scsi_prep_async_scan(struct Scsi_Host *shost) | |||
1723 | static void scsi_finish_async_scan(struct async_scan_data *data) | 1731 | static void scsi_finish_async_scan(struct async_scan_data *data) |
1724 | { | 1732 | { |
1725 | struct Scsi_Host *shost; | 1733 | struct Scsi_Host *shost; |
1734 | unsigned long flags; | ||
1726 | 1735 | ||
1727 | if (!data) | 1736 | if (!data) |
1728 | return; | 1737 | return; |
1729 | 1738 | ||
1730 | shost = data->shost; | 1739 | shost = data->shost; |
1740 | |||
1741 | mutex_lock(&shost->scan_mutex); | ||
1742 | |||
1731 | if (!shost->async_scan) { | 1743 | if (!shost->async_scan) { |
1732 | printk("%s called twice for host %d", __FUNCTION__, | 1744 | printk("%s called twice for host %d", __FUNCTION__, |
1733 | shost->host_no); | 1745 | shost->host_no); |
@@ -1739,8 +1751,13 @@ static void scsi_finish_async_scan(struct async_scan_data *data) | |||
1739 | 1751 | ||
1740 | scsi_sysfs_add_devices(shost); | 1752 | scsi_sysfs_add_devices(shost); |
1741 | 1753 | ||
1742 | spin_lock(&async_scan_lock); | 1754 | spin_lock_irqsave(shost->host_lock, flags); |
1743 | shost->async_scan = 0; | 1755 | shost->async_scan = 0; |
1756 | spin_unlock_irqrestore(shost->host_lock, flags); | ||
1757 | |||
1758 | mutex_unlock(&shost->scan_mutex); | ||
1759 | |||
1760 | spin_lock(&async_scan_lock); | ||
1744 | list_del(&data->list); | 1761 | list_del(&data->list); |
1745 | if (!list_empty(&scanning_hosts)) { | 1762 | if (!list_empty(&scanning_hosts)) { |
1746 | struct async_scan_data *next = list_entry(scanning_hosts.next, | 1763 | struct async_scan_data *next = list_entry(scanning_hosts.next, |
@@ -1782,6 +1799,7 @@ static int do_scan_async(void *_data) | |||
1782 | **/ | 1799 | **/ |
1783 | void scsi_scan_host(struct Scsi_Host *shost) | 1800 | void scsi_scan_host(struct Scsi_Host *shost) |
1784 | { | 1801 | { |
1802 | struct task_struct *p; | ||
1785 | struct async_scan_data *data; | 1803 | struct async_scan_data *data; |
1786 | 1804 | ||
1787 | if (strncmp(scsi_scan_type, "none", 4) == 0) | 1805 | if (strncmp(scsi_scan_type, "none", 4) == 0) |
@@ -1793,7 +1811,9 @@ void scsi_scan_host(struct Scsi_Host *shost) | |||
1793 | return; | 1811 | return; |
1794 | } | 1812 | } |
1795 | 1813 | ||
1796 | kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no); | 1814 | p = kthread_run(do_scan_async, data, "scsi_scan_%d", shost->host_no); |
1815 | if (unlikely(IS_ERR(p))) | ||
1816 | do_scan_async(data); | ||
1797 | } | 1817 | } |
1798 | EXPORT_SYMBOL(scsi_scan_host); | 1818 | EXPORT_SYMBOL(scsi_scan_host); |
1799 | 1819 | ||
diff --git a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c index ede9986d349a..daed37df00b1 100644 --- a/drivers/scsi/scsi_sysfs.c +++ b/drivers/scsi/scsi_sysfs.c | |||
@@ -190,6 +190,46 @@ show_shost_state(struct class_device *class_dev, char *buf) | |||
190 | 190 | ||
191 | static CLASS_DEVICE_ATTR(state, S_IRUGO | S_IWUSR, show_shost_state, store_shost_state); | 191 | static CLASS_DEVICE_ATTR(state, S_IRUGO | S_IWUSR, show_shost_state, store_shost_state); |
192 | 192 | ||
193 | static ssize_t | ||
194 | show_shost_mode(unsigned int mode, char *buf) | ||
195 | { | ||
196 | ssize_t len = 0; | ||
197 | |||
198 | if (mode & MODE_INITIATOR) | ||
199 | len = sprintf(buf, "%s", "Initiator"); | ||
200 | |||
201 | if (mode & MODE_TARGET) | ||
202 | len += sprintf(buf + len, "%s%s", len ? ", " : "", "Target"); | ||
203 | |||
204 | len += sprintf(buf + len, "\n"); | ||
205 | |||
206 | return len; | ||
207 | } | ||
208 | |||
209 | static ssize_t show_shost_supported_mode(struct class_device *class_dev, char *buf) | ||
210 | { | ||
211 | struct Scsi_Host *shost = class_to_shost(class_dev); | ||
212 | |||
213 | if (shost->hostt->supported_mode == MODE_UNKNOWN) | ||
214 | return snprintf(buf, 20, "unknown\n"); | ||
215 | else | ||
216 | return show_shost_mode(shost->hostt->supported_mode, buf); | ||
217 | } | ||
218 | |||
219 | static CLASS_DEVICE_ATTR(supported_mode, S_IRUGO | S_IWUSR, show_shost_supported_mode, NULL); | ||
220 | |||
221 | static ssize_t show_shost_active_mode(struct class_device *class_dev, char *buf) | ||
222 | { | ||
223 | struct Scsi_Host *shost = class_to_shost(class_dev); | ||
224 | |||
225 | if (shost->active_mode == MODE_UNKNOWN) | ||
226 | return snprintf(buf, 20, "unknown\n"); | ||
227 | else | ||
228 | return show_shost_mode(shost->active_mode, buf); | ||
229 | } | ||
230 | |||
231 | static CLASS_DEVICE_ATTR(active_mode, S_IRUGO | S_IWUSR, show_shost_active_mode, NULL); | ||
232 | |||
193 | shost_rd_attr(unique_id, "%u\n"); | 233 | shost_rd_attr(unique_id, "%u\n"); |
194 | shost_rd_attr(host_busy, "%hu\n"); | 234 | shost_rd_attr(host_busy, "%hu\n"); |
195 | shost_rd_attr(cmd_per_lun, "%hd\n"); | 235 | shost_rd_attr(cmd_per_lun, "%hd\n"); |
@@ -208,6 +248,8 @@ static struct class_device_attribute *scsi_sysfs_shost_attrs[] = { | |||
208 | &class_device_attr_proc_name, | 248 | &class_device_attr_proc_name, |
209 | &class_device_attr_scan, | 249 | &class_device_attr_scan, |
210 | &class_device_attr_state, | 250 | &class_device_attr_state, |
251 | &class_device_attr_supported_mode, | ||
252 | &class_device_attr_active_mode, | ||
211 | NULL | 253 | NULL |
212 | }; | 254 | }; |
213 | 255 | ||
@@ -571,24 +613,31 @@ sdev_show_modalias(struct device *dev, struct device_attribute *attr, char *buf) | |||
571 | static DEVICE_ATTR(modalias, S_IRUGO, sdev_show_modalias, NULL); | 613 | static DEVICE_ATTR(modalias, S_IRUGO, sdev_show_modalias, NULL); |
572 | 614 | ||
573 | /* Default template for device attributes. May NOT be modified */ | 615 | /* Default template for device attributes. May NOT be modified */ |
574 | static struct device_attribute *scsi_sysfs_sdev_attrs[] = { | 616 | static struct attribute *scsi_sdev_attrs[] = { |
575 | &dev_attr_device_blocked, | 617 | &dev_attr_device_blocked.attr, |
576 | &dev_attr_queue_depth, | 618 | &dev_attr_type.attr, |
577 | &dev_attr_queue_type, | 619 | &dev_attr_scsi_level.attr, |
578 | &dev_attr_type, | 620 | &dev_attr_vendor.attr, |
579 | &dev_attr_scsi_level, | 621 | &dev_attr_model.attr, |
580 | &dev_attr_vendor, | 622 | &dev_attr_rev.attr, |
581 | &dev_attr_model, | 623 | &dev_attr_rescan.attr, |
582 | &dev_attr_rev, | 624 | &dev_attr_delete.attr, |
583 | &dev_attr_rescan, | 625 | &dev_attr_state.attr, |
584 | &dev_attr_delete, | 626 | &dev_attr_timeout.attr, |
585 | &dev_attr_state, | 627 | &dev_attr_iocounterbits.attr, |
586 | &dev_attr_timeout, | 628 | &dev_attr_iorequest_cnt.attr, |
587 | &dev_attr_iocounterbits, | 629 | &dev_attr_iodone_cnt.attr, |
588 | &dev_attr_iorequest_cnt, | 630 | &dev_attr_ioerr_cnt.attr, |
589 | &dev_attr_iodone_cnt, | 631 | &dev_attr_modalias.attr, |
590 | &dev_attr_ioerr_cnt, | 632 | NULL |
591 | &dev_attr_modalias, | 633 | }; |
634 | |||
635 | static struct attribute_group scsi_sdev_attr_group = { | ||
636 | .attrs = scsi_sdev_attrs, | ||
637 | }; | ||
638 | |||
639 | static struct attribute_group *scsi_sdev_attr_groups[] = { | ||
640 | &scsi_sdev_attr_group, | ||
592 | NULL | 641 | NULL |
593 | }; | 642 | }; |
594 | 643 | ||
@@ -650,56 +699,6 @@ static struct device_attribute sdev_attr_queue_type_rw = | |||
650 | __ATTR(queue_type, S_IRUGO | S_IWUSR, show_queue_type_field, | 699 | __ATTR(queue_type, S_IRUGO | S_IWUSR, show_queue_type_field, |
651 | sdev_store_queue_type_rw); | 700 | sdev_store_queue_type_rw); |
652 | 701 | ||
653 | static struct device_attribute *attr_changed_internally( | ||
654 | struct Scsi_Host *shost, | ||
655 | struct device_attribute * attr) | ||
656 | { | ||
657 | if (!strcmp("queue_depth", attr->attr.name) | ||
658 | && shost->hostt->change_queue_depth) | ||
659 | return &sdev_attr_queue_depth_rw; | ||
660 | else if (!strcmp("queue_type", attr->attr.name) | ||
661 | && shost->hostt->change_queue_type) | ||
662 | return &sdev_attr_queue_type_rw; | ||
663 | return attr; | ||
664 | } | ||
665 | |||
666 | |||
667 | static struct device_attribute *attr_overridden( | ||
668 | struct device_attribute **attrs, | ||
669 | struct device_attribute *attr) | ||
670 | { | ||
671 | int i; | ||
672 | |||
673 | if (!attrs) | ||
674 | return NULL; | ||
675 | for (i = 0; attrs[i]; i++) | ||
676 | if (!strcmp(attrs[i]->attr.name, attr->attr.name)) | ||
677 | return attrs[i]; | ||
678 | return NULL; | ||
679 | } | ||
680 | |||
681 | static int attr_add(struct device *dev, struct device_attribute *attr) | ||
682 | { | ||
683 | struct device_attribute *base_attr; | ||
684 | |||
685 | /* | ||
686 | * Spare the caller from having to copy things it's not interested in. | ||
687 | */ | ||
688 | base_attr = attr_overridden(scsi_sysfs_sdev_attrs, attr); | ||
689 | if (base_attr) { | ||
690 | /* extend permissions */ | ||
691 | attr->attr.mode |= base_attr->attr.mode; | ||
692 | |||
693 | /* override null show/store with default */ | ||
694 | if (!attr->show) | ||
695 | attr->show = base_attr->show; | ||
696 | if (!attr->store) | ||
697 | attr->store = base_attr->store; | ||
698 | } | ||
699 | |||
700 | return device_create_file(dev, attr); | ||
701 | } | ||
702 | |||
703 | /** | 702 | /** |
704 | * scsi_sysfs_add_sdev - add scsi device to sysfs | 703 | * scsi_sysfs_add_sdev - add scsi device to sysfs |
705 | * @sdev: scsi_device to add | 704 | * @sdev: scsi_device to add |
@@ -731,6 +730,24 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) | |||
731 | * released by the sdev_class .release */ | 730 | * released by the sdev_class .release */ |
732 | get_device(&sdev->sdev_gendev); | 731 | get_device(&sdev->sdev_gendev); |
733 | 732 | ||
733 | /* create queue files, which may be writable, depending on the host */ | ||
734 | if (sdev->host->hostt->change_queue_depth) | ||
735 | error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_depth_rw); | ||
736 | else | ||
737 | error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_depth); | ||
738 | if (error) { | ||
739 | __scsi_remove_device(sdev); | ||
740 | goto out; | ||
741 | } | ||
742 | if (sdev->host->hostt->change_queue_type) | ||
743 | error = device_create_file(&sdev->sdev_gendev, &sdev_attr_queue_type_rw); | ||
744 | else | ||
745 | error = device_create_file(&sdev->sdev_gendev, &dev_attr_queue_type); | ||
746 | if (error) { | ||
747 | __scsi_remove_device(sdev); | ||
748 | goto out; | ||
749 | } | ||
750 | |||
734 | error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL); | 751 | error = bsg_register_queue(rq, &sdev->sdev_gendev, NULL); |
735 | 752 | ||
736 | if (error) | 753 | if (error) |
@@ -741,9 +758,10 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) | |||
741 | * nothing went wrong */ | 758 | * nothing went wrong */ |
742 | error = 0; | 759 | error = 0; |
743 | 760 | ||
761 | /* add additional host specific attributes */ | ||
744 | if (sdev->host->hostt->sdev_attrs) { | 762 | if (sdev->host->hostt->sdev_attrs) { |
745 | for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) { | 763 | for (i = 0; sdev->host->hostt->sdev_attrs[i]; i++) { |
746 | error = attr_add(&sdev->sdev_gendev, | 764 | error = device_create_file(&sdev->sdev_gendev, |
747 | sdev->host->hostt->sdev_attrs[i]); | 765 | sdev->host->hostt->sdev_attrs[i]); |
748 | if (error) { | 766 | if (error) { |
749 | __scsi_remove_device(sdev); | 767 | __scsi_remove_device(sdev); |
@@ -751,20 +769,6 @@ int scsi_sysfs_add_sdev(struct scsi_device *sdev) | |||
751 | } | 769 | } |
752 | } | 770 | } |
753 | } | 771 | } |
754 | |||
755 | for (i = 0; scsi_sysfs_sdev_attrs[i]; i++) { | ||
756 | if (!attr_overridden(sdev->host->hostt->sdev_attrs, | ||
757 | scsi_sysfs_sdev_attrs[i])) { | ||
758 | struct device_attribute * attr = | ||
759 | attr_changed_internally(sdev->host, | ||
760 | scsi_sysfs_sdev_attrs[i]); | ||
761 | error = device_create_file(&sdev->sdev_gendev, attr); | ||
762 | if (error) { | ||
763 | __scsi_remove_device(sdev); | ||
764 | goto out; | ||
765 | } | ||
766 | } | ||
767 | } | ||
768 | 772 | ||
769 | transport_add_device(&sdev->sdev_gendev); | 773 | transport_add_device(&sdev->sdev_gendev); |
770 | out: | 774 | out: |
@@ -951,6 +955,12 @@ int scsi_sysfs_add_host(struct Scsi_Host *shost) | |||
951 | return 0; | 955 | return 0; |
952 | } | 956 | } |
953 | 957 | ||
958 | static struct device_type scsi_dev_type = { | ||
959 | .name = "scsi_device", | ||
960 | .release = scsi_device_dev_release, | ||
961 | .groups = scsi_sdev_attr_groups, | ||
962 | }; | ||
963 | |||
954 | void scsi_sysfs_device_initialize(struct scsi_device *sdev) | 964 | void scsi_sysfs_device_initialize(struct scsi_device *sdev) |
955 | { | 965 | { |
956 | unsigned long flags; | 966 | unsigned long flags; |
@@ -959,7 +969,7 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev) | |||
959 | 969 | ||
960 | device_initialize(&sdev->sdev_gendev); | 970 | device_initialize(&sdev->sdev_gendev); |
961 | sdev->sdev_gendev.bus = &scsi_bus_type; | 971 | sdev->sdev_gendev.bus = &scsi_bus_type; |
962 | sdev->sdev_gendev.release = scsi_device_dev_release; | 972 | sdev->sdev_gendev.type = &scsi_dev_type; |
963 | sprintf(sdev->sdev_gendev.bus_id,"%d:%d:%d:%d", | 973 | sprintf(sdev->sdev_gendev.bus_id,"%d:%d:%d:%d", |
964 | sdev->host->host_no, sdev->channel, sdev->id, | 974 | sdev->host->host_no, sdev->channel, sdev->id, |
965 | sdev->lun); | 975 | sdev->lun); |
@@ -980,7 +990,7 @@ void scsi_sysfs_device_initialize(struct scsi_device *sdev) | |||
980 | 990 | ||
981 | int scsi_is_sdev_device(const struct device *dev) | 991 | int scsi_is_sdev_device(const struct device *dev) |
982 | { | 992 | { |
983 | return dev->release == scsi_device_dev_release; | 993 | return dev->type == &scsi_dev_type; |
984 | } | 994 | } |
985 | EXPORT_SYMBOL(scsi_is_sdev_device); | 995 | EXPORT_SYMBOL(scsi_is_sdev_device); |
986 | 996 | ||
diff --git a/drivers/scsi/scsi_tgt_if.c b/drivers/scsi/scsi_tgt_if.c index ca22ddf81746..9815a1a2db24 100644 --- a/drivers/scsi/scsi_tgt_if.c +++ b/drivers/scsi/scsi_tgt_if.c | |||
@@ -102,7 +102,8 @@ static int tgt_uspace_send_event(u32 type, struct tgt_event *p) | |||
102 | return 0; | 102 | return 0; |
103 | } | 103 | } |
104 | 104 | ||
105 | int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, struct scsi_lun *lun, u64 tag) | 105 | int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, u64 itn_id, |
106 | struct scsi_lun *lun, u64 tag) | ||
106 | { | 107 | { |
107 | struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd); | 108 | struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd); |
108 | struct tgt_event ev; | 109 | struct tgt_event ev; |
@@ -110,6 +111,7 @@ int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, struct scsi_lun *lun, u64 ta | |||
110 | 111 | ||
111 | memset(&ev, 0, sizeof(ev)); | 112 | memset(&ev, 0, sizeof(ev)); |
112 | ev.p.cmd_req.host_no = shost->host_no; | 113 | ev.p.cmd_req.host_no = shost->host_no; |
114 | ev.p.cmd_req.itn_id = itn_id; | ||
113 | ev.p.cmd_req.data_len = cmd->request_bufflen; | 115 | ev.p.cmd_req.data_len = cmd->request_bufflen; |
114 | memcpy(ev.p.cmd_req.scb, cmd->cmnd, sizeof(ev.p.cmd_req.scb)); | 116 | memcpy(ev.p.cmd_req.scb, cmd->cmnd, sizeof(ev.p.cmd_req.scb)); |
115 | memcpy(ev.p.cmd_req.lun, lun, sizeof(ev.p.cmd_req.lun)); | 117 | memcpy(ev.p.cmd_req.lun, lun, sizeof(ev.p.cmd_req.lun)); |
@@ -127,7 +129,7 @@ int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, struct scsi_lun *lun, u64 ta | |||
127 | return err; | 129 | return err; |
128 | } | 130 | } |
129 | 131 | ||
130 | int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 tag) | 132 | int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 itn_id, u64 tag) |
131 | { | 133 | { |
132 | struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd); | 134 | struct Scsi_Host *shost = scsi_tgt_cmd_to_host(cmd); |
133 | struct tgt_event ev; | 135 | struct tgt_event ev; |
@@ -135,6 +137,7 @@ int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 tag) | |||
135 | 137 | ||
136 | memset(&ev, 0, sizeof(ev)); | 138 | memset(&ev, 0, sizeof(ev)); |
137 | ev.p.cmd_done.host_no = shost->host_no; | 139 | ev.p.cmd_done.host_no = shost->host_no; |
140 | ev.p.cmd_done.itn_id = itn_id; | ||
138 | ev.p.cmd_done.tag = tag; | 141 | ev.p.cmd_done.tag = tag; |
139 | ev.p.cmd_done.result = cmd->result; | 142 | ev.p.cmd_done.result = cmd->result; |
140 | 143 | ||
@@ -149,14 +152,15 @@ int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 tag) | |||
149 | return err; | 152 | return err; |
150 | } | 153 | } |
151 | 154 | ||
152 | int scsi_tgt_uspace_send_tsk_mgmt(int host_no, int function, u64 tag, | 155 | int scsi_tgt_uspace_send_tsk_mgmt(int host_no, u64 itn_id, int function, |
153 | struct scsi_lun *scsilun, void *data) | 156 | u64 tag, struct scsi_lun *scsilun, void *data) |
154 | { | 157 | { |
155 | struct tgt_event ev; | 158 | struct tgt_event ev; |
156 | int err; | 159 | int err; |
157 | 160 | ||
158 | memset(&ev, 0, sizeof(ev)); | 161 | memset(&ev, 0, sizeof(ev)); |
159 | ev.p.tsk_mgmt_req.host_no = host_no; | 162 | ev.p.tsk_mgmt_req.host_no = host_no; |
163 | ev.p.tsk_mgmt_req.itn_id = itn_id; | ||
160 | ev.p.tsk_mgmt_req.function = function; | 164 | ev.p.tsk_mgmt_req.function = function; |
161 | ev.p.tsk_mgmt_req.tag = tag; | 165 | ev.p.tsk_mgmt_req.tag = tag; |
162 | memcpy(ev.p.tsk_mgmt_req.lun, scsilun, sizeof(ev.p.tsk_mgmt_req.lun)); | 166 | memcpy(ev.p.tsk_mgmt_req.lun, scsilun, sizeof(ev.p.tsk_mgmt_req.lun)); |
@@ -172,6 +176,29 @@ int scsi_tgt_uspace_send_tsk_mgmt(int host_no, int function, u64 tag, | |||
172 | return err; | 176 | return err; |
173 | } | 177 | } |
174 | 178 | ||
179 | int scsi_tgt_uspace_send_it_nexus_request(int host_no, u64 itn_id, | ||
180 | int function, char *initiator_id) | ||
181 | { | ||
182 | struct tgt_event ev; | ||
183 | int err; | ||
184 | |||
185 | memset(&ev, 0, sizeof(ev)); | ||
186 | ev.p.it_nexus_req.host_no = host_no; | ||
187 | ev.p.it_nexus_req.function = function; | ||
188 | ev.p.it_nexus_req.itn_id = itn_id; | ||
189 | if (initiator_id) | ||
190 | strncpy(ev.p.it_nexus_req.initiator_id, initiator_id, | ||
191 | sizeof(ev.p.it_nexus_req.initiator_id)); | ||
192 | |||
193 | dprintk("%d %x %llx\n", host_no, function, (unsigned long long)itn_id); | ||
194 | |||
195 | err = tgt_uspace_send_event(TGT_KEVENT_IT_NEXUS_REQ, &ev); | ||
196 | if (err) | ||
197 | eprintk("tx buf is full, could not send\n"); | ||
198 | |||
199 | return err; | ||
200 | } | ||
201 | |||
175 | static int event_recv_msg(struct tgt_event *ev) | 202 | static int event_recv_msg(struct tgt_event *ev) |
176 | { | 203 | { |
177 | int err = 0; | 204 | int err = 0; |
@@ -179,6 +206,7 @@ static int event_recv_msg(struct tgt_event *ev) | |||
179 | switch (ev->hdr.type) { | 206 | switch (ev->hdr.type) { |
180 | case TGT_UEVENT_CMD_RSP: | 207 | case TGT_UEVENT_CMD_RSP: |
181 | err = scsi_tgt_kspace_exec(ev->p.cmd_rsp.host_no, | 208 | err = scsi_tgt_kspace_exec(ev->p.cmd_rsp.host_no, |
209 | ev->p.cmd_rsp.itn_id, | ||
182 | ev->p.cmd_rsp.result, | 210 | ev->p.cmd_rsp.result, |
183 | ev->p.cmd_rsp.tag, | 211 | ev->p.cmd_rsp.tag, |
184 | ev->p.cmd_rsp.uaddr, | 212 | ev->p.cmd_rsp.uaddr, |
@@ -189,9 +217,15 @@ static int event_recv_msg(struct tgt_event *ev) | |||
189 | break; | 217 | break; |
190 | case TGT_UEVENT_TSK_MGMT_RSP: | 218 | case TGT_UEVENT_TSK_MGMT_RSP: |
191 | err = scsi_tgt_kspace_tsk_mgmt(ev->p.tsk_mgmt_rsp.host_no, | 219 | err = scsi_tgt_kspace_tsk_mgmt(ev->p.tsk_mgmt_rsp.host_no, |
220 | ev->p.tsk_mgmt_rsp.itn_id, | ||
192 | ev->p.tsk_mgmt_rsp.mid, | 221 | ev->p.tsk_mgmt_rsp.mid, |
193 | ev->p.tsk_mgmt_rsp.result); | 222 | ev->p.tsk_mgmt_rsp.result); |
194 | break; | 223 | break; |
224 | case TGT_UEVENT_IT_NEXUS_RSP: | ||
225 | err = scsi_tgt_kspace_it_nexus_rsp(ev->p.it_nexus_rsp.host_no, | ||
226 | ev->p.it_nexus_rsp.itn_id, | ||
227 | ev->p.it_nexus_rsp.result); | ||
228 | break; | ||
195 | default: | 229 | default: |
196 | eprintk("unknown type %d\n", ev->hdr.type); | 230 | eprintk("unknown type %d\n", ev->hdr.type); |
197 | err = -EINVAL; | 231 | err = -EINVAL; |
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c index 371b69c110bc..66c692ffa305 100644 --- a/drivers/scsi/scsi_tgt_lib.c +++ b/drivers/scsi/scsi_tgt_lib.c | |||
@@ -27,6 +27,7 @@ | |||
27 | #include <scsi/scsi_cmnd.h> | 27 | #include <scsi/scsi_cmnd.h> |
28 | #include <scsi/scsi_device.h> | 28 | #include <scsi/scsi_device.h> |
29 | #include <scsi/scsi_host.h> | 29 | #include <scsi/scsi_host.h> |
30 | #include <scsi/scsi_transport.h> | ||
30 | #include <scsi/scsi_tgt.h> | 31 | #include <scsi/scsi_tgt.h> |
31 | 32 | ||
32 | #include "scsi_tgt_priv.h" | 33 | #include "scsi_tgt_priv.h" |
@@ -46,6 +47,7 @@ struct scsi_tgt_cmd { | |||
46 | 47 | ||
47 | struct list_head hash_list; | 48 | struct list_head hash_list; |
48 | struct request *rq; | 49 | struct request *rq; |
50 | u64 itn_id; | ||
49 | u64 tag; | 51 | u64 tag; |
50 | }; | 52 | }; |
51 | 53 | ||
@@ -185,12 +187,13 @@ static void scsi_tgt_cmd_destroy(struct work_struct *work) | |||
185 | } | 187 | } |
186 | 188 | ||
187 | static void init_scsi_tgt_cmd(struct request *rq, struct scsi_tgt_cmd *tcmd, | 189 | static void init_scsi_tgt_cmd(struct request *rq, struct scsi_tgt_cmd *tcmd, |
188 | u64 tag) | 190 | u64 itn_id, u64 tag) |
189 | { | 191 | { |
190 | struct scsi_tgt_queuedata *qdata = rq->q->queuedata; | 192 | struct scsi_tgt_queuedata *qdata = rq->q->queuedata; |
191 | unsigned long flags; | 193 | unsigned long flags; |
192 | struct list_head *head; | 194 | struct list_head *head; |
193 | 195 | ||
196 | tcmd->itn_id = itn_id; | ||
194 | tcmd->tag = tag; | 197 | tcmd->tag = tag; |
195 | tcmd->bio = NULL; | 198 | tcmd->bio = NULL; |
196 | INIT_WORK(&tcmd->work, scsi_tgt_cmd_destroy); | 199 | INIT_WORK(&tcmd->work, scsi_tgt_cmd_destroy); |
@@ -234,7 +237,7 @@ int scsi_tgt_alloc_queue(struct Scsi_Host *shost) | |||
234 | * command as is recvd to userspace. uspace can then make | 237 | * command as is recvd to userspace. uspace can then make |
235 | * sure we do not overload the HBA | 238 | * sure we do not overload the HBA |
236 | */ | 239 | */ |
237 | q->nr_requests = shost->hostt->can_queue; | 240 | q->nr_requests = shost->can_queue; |
238 | /* | 241 | /* |
239 | * We currently only support software LLDs so this does | 242 | * We currently only support software LLDs so this does |
240 | * not matter for now. Do we need this for the cards we support? | 243 | * not matter for now. Do we need this for the cards we support? |
@@ -301,14 +304,14 @@ EXPORT_SYMBOL_GPL(scsi_tgt_cmd_to_host); | |||
301 | * @scsilun: scsi lun | 304 | * @scsilun: scsi lun |
302 | * @tag: unique value to identify this command for tmf | 305 | * @tag: unique value to identify this command for tmf |
303 | */ | 306 | */ |
304 | int scsi_tgt_queue_command(struct scsi_cmnd *cmd, struct scsi_lun *scsilun, | 307 | int scsi_tgt_queue_command(struct scsi_cmnd *cmd, u64 itn_id, |
305 | u64 tag) | 308 | struct scsi_lun *scsilun, u64 tag) |
306 | { | 309 | { |
307 | struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; | 310 | struct scsi_tgt_cmd *tcmd = cmd->request->end_io_data; |
308 | int err; | 311 | int err; |
309 | 312 | ||
310 | init_scsi_tgt_cmd(cmd->request, tcmd, tag); | 313 | init_scsi_tgt_cmd(cmd->request, tcmd, itn_id, tag); |
311 | err = scsi_tgt_uspace_send_cmd(cmd, scsilun, tag); | 314 | err = scsi_tgt_uspace_send_cmd(cmd, itn_id, scsilun, tag); |
312 | if (err) | 315 | if (err) |
313 | cmd_hashlist_del(cmd); | 316 | cmd_hashlist_del(cmd); |
314 | 317 | ||
@@ -326,7 +329,7 @@ static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd) | |||
326 | 329 | ||
327 | dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request)); | 330 | dprintk("cmd %p %lu\n", cmd, rq_data_dir(cmd->request)); |
328 | 331 | ||
329 | scsi_tgt_uspace_send_status(cmd, tcmd->tag); | 332 | scsi_tgt_uspace_send_status(cmd, tcmd->itn_id, tcmd->tag); |
330 | 333 | ||
331 | if (cmd->request_buffer) | 334 | if (cmd->request_buffer) |
332 | scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); | 335 | scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); |
@@ -459,7 +462,7 @@ static struct request *tgt_cmd_hash_lookup(struct request_queue *q, u64 tag) | |||
459 | return rq; | 462 | return rq; |
460 | } | 463 | } |
461 | 464 | ||
462 | int scsi_tgt_kspace_exec(int host_no, int result, u64 tag, | 465 | int scsi_tgt_kspace_exec(int host_no, u64 itn_id, int result, u64 tag, |
463 | unsigned long uaddr, u32 len, unsigned long sense_uaddr, | 466 | unsigned long uaddr, u32 len, unsigned long sense_uaddr, |
464 | u32 sense_len, u8 rw) | 467 | u32 sense_len, u8 rw) |
465 | { | 468 | { |
@@ -541,21 +544,22 @@ done: | |||
541 | return err; | 544 | return err; |
542 | } | 545 | } |
543 | 546 | ||
544 | int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *shost, int function, u64 tag, | 547 | int scsi_tgt_tsk_mgmt_request(struct Scsi_Host *shost, u64 itn_id, |
545 | struct scsi_lun *scsilun, void *data) | 548 | int function, u64 tag, struct scsi_lun *scsilun, |
549 | void *data) | ||
546 | { | 550 | { |
547 | int err; | 551 | int err; |
548 | 552 | ||
549 | /* TODO: need to retry if this fails. */ | 553 | /* TODO: need to retry if this fails. */ |
550 | err = scsi_tgt_uspace_send_tsk_mgmt(shost->host_no, function, | 554 | err = scsi_tgt_uspace_send_tsk_mgmt(shost->host_no, itn_id, |
551 | tag, scsilun, data); | 555 | function, tag, scsilun, data); |
552 | if (err < 0) | 556 | if (err < 0) |
553 | eprintk("The task management request lost!\n"); | 557 | eprintk("The task management request lost!\n"); |
554 | return err; | 558 | return err; |
555 | } | 559 | } |
556 | EXPORT_SYMBOL_GPL(scsi_tgt_tsk_mgmt_request); | 560 | EXPORT_SYMBOL_GPL(scsi_tgt_tsk_mgmt_request); |
557 | 561 | ||
558 | int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result) | 562 | int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 itn_id, u64 mid, int result) |
559 | { | 563 | { |
560 | struct Scsi_Host *shost; | 564 | struct Scsi_Host *shost; |
561 | int err = -EINVAL; | 565 | int err = -EINVAL; |
@@ -573,7 +577,60 @@ int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result) | |||
573 | goto done; | 577 | goto done; |
574 | } | 578 | } |
575 | 579 | ||
576 | err = shost->hostt->tsk_mgmt_response(mid, result); | 580 | err = shost->transportt->tsk_mgmt_response(shost, itn_id, mid, result); |
581 | done: | ||
582 | scsi_host_put(shost); | ||
583 | return err; | ||
584 | } | ||
585 | |||
586 | int scsi_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id, | ||
587 | char *initiator) | ||
588 | { | ||
589 | int err; | ||
590 | |||
591 | /* TODO: need to retry if this fails. */ | ||
592 | err = scsi_tgt_uspace_send_it_nexus_request(shost->host_no, itn_id, 0, | ||
593 | initiator); | ||
594 | if (err < 0) | ||
595 | eprintk("The i_t_neuxs request lost, %d %llx!\n", | ||
596 | shost->host_no, (unsigned long long)itn_id); | ||
597 | return err; | ||
598 | } | ||
599 | EXPORT_SYMBOL_GPL(scsi_tgt_it_nexus_create); | ||
600 | |||
601 | int scsi_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id) | ||
602 | { | ||
603 | int err; | ||
604 | |||
605 | /* TODO: need to retry if this fails. */ | ||
606 | err = scsi_tgt_uspace_send_it_nexus_request(shost->host_no, | ||
607 | itn_id, 1, NULL); | ||
608 | if (err < 0) | ||
609 | eprintk("The i_t_neuxs request lost, %d %llx!\n", | ||
610 | shost->host_no, (unsigned long long)itn_id); | ||
611 | return err; | ||
612 | } | ||
613 | EXPORT_SYMBOL_GPL(scsi_tgt_it_nexus_destroy); | ||
614 | |||
615 | int scsi_tgt_kspace_it_nexus_rsp(int host_no, u64 itn_id, int result) | ||
616 | { | ||
617 | struct Scsi_Host *shost; | ||
618 | int err = -EINVAL; | ||
619 | |||
620 | dprintk("%d %d %llx\n", host_no, result, (unsigned long long) mid); | ||
621 | |||
622 | shost = scsi_host_lookup(host_no); | ||
623 | if (IS_ERR(shost)) { | ||
624 | printk(KERN_ERR "Could not find host no %d\n", host_no); | ||
625 | return err; | ||
626 | } | ||
627 | |||
628 | if (!shost->uspace_req_q) { | ||
629 | printk(KERN_ERR "Not target scsi host %d\n", host_no); | ||
630 | goto done; | ||
631 | } | ||
632 | |||
633 | err = shost->transportt->it_nexus_response(shost, itn_id, result); | ||
577 | done: | 634 | done: |
578 | scsi_host_put(shost); | 635 | scsi_host_put(shost); |
579 | return err; | 636 | return err; |
diff --git a/drivers/scsi/scsi_tgt_priv.h b/drivers/scsi/scsi_tgt_priv.h index e9e6db1c417f..cb92888948f9 100644 --- a/drivers/scsi/scsi_tgt_priv.h +++ b/drivers/scsi/scsi_tgt_priv.h | |||
@@ -15,12 +15,18 @@ do { \ | |||
15 | extern void scsi_tgt_if_exit(void); | 15 | extern void scsi_tgt_if_exit(void); |
16 | extern int scsi_tgt_if_init(void); | 16 | extern int scsi_tgt_if_init(void); |
17 | 17 | ||
18 | extern int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, struct scsi_lun *lun, | 18 | extern int scsi_tgt_uspace_send_cmd(struct scsi_cmnd *cmd, u64 it_nexus_id, |
19 | u64 tag); | 19 | struct scsi_lun *lun, u64 tag); |
20 | extern int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 tag); | 20 | extern int scsi_tgt_uspace_send_status(struct scsi_cmnd *cmd, u64 it_nexus_id, |
21 | extern int scsi_tgt_kspace_exec(int host_no, int result, u64 tag, | 21 | u64 tag); |
22 | unsigned long uaddr, u32 len, unsigned long sense_uaddr, | 22 | extern int scsi_tgt_kspace_exec(int host_no, u64 it_nexus_id, int result, u64 tag, |
23 | u32 sense_len, u8 rw); | 23 | unsigned long uaddr, u32 len, |
24 | extern int scsi_tgt_uspace_send_tsk_mgmt(int host_no, int function, u64 tag, | 24 | unsigned long sense_uaddr, u32 sense_len, u8 rw); |
25 | extern int scsi_tgt_uspace_send_tsk_mgmt(int host_no, u64 it_nexus_id, | ||
26 | int function, u64 tag, | ||
25 | struct scsi_lun *scsilun, void *data); | 27 | struct scsi_lun *scsilun, void *data); |
26 | extern int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 mid, int result); | 28 | extern int scsi_tgt_kspace_tsk_mgmt(int host_no, u64 it_nexus_id, |
29 | u64 mid, int result); | ||
30 | extern int scsi_tgt_uspace_send_it_nexus_request(int host_no, u64 it_nexus_id, | ||
31 | int function, char *initiator); | ||
32 | extern int scsi_tgt_kspace_it_nexus_rsp(int host_no, u64 it_nexus_id, int result); | ||
diff --git a/drivers/scsi/scsi_transport_fc.c b/drivers/scsi/scsi_transport_fc.c index 47057254850d..7a7cfe583b2a 100644 --- a/drivers/scsi/scsi_transport_fc.c +++ b/drivers/scsi/scsi_transport_fc.c | |||
@@ -36,6 +36,7 @@ | |||
36 | #include <net/netlink.h> | 36 | #include <net/netlink.h> |
37 | #include <scsi/scsi_netlink_fc.h> | 37 | #include <scsi/scsi_netlink_fc.h> |
38 | #include "scsi_priv.h" | 38 | #include "scsi_priv.h" |
39 | #include "scsi_transport_fc_internal.h" | ||
39 | 40 | ||
40 | static int fc_queue_work(struct Scsi_Host *, struct work_struct *); | 41 | static int fc_queue_work(struct Scsi_Host *, struct work_struct *); |
41 | static void fc_vport_sched_delete(struct work_struct *work); | 42 | static void fc_vport_sched_delete(struct work_struct *work); |
@@ -473,7 +474,7 @@ static DECLARE_TRANSPORT_CLASS(fc_vport_class, | |||
473 | */ | 474 | */ |
474 | static unsigned int fc_dev_loss_tmo = 60; /* seconds */ | 475 | static unsigned int fc_dev_loss_tmo = 60; /* seconds */ |
475 | 476 | ||
476 | module_param_named(dev_loss_tmo, fc_dev_loss_tmo, int, S_IRUGO|S_IWUSR); | 477 | module_param_named(dev_loss_tmo, fc_dev_loss_tmo, uint, S_IRUGO|S_IWUSR); |
477 | MODULE_PARM_DESC(dev_loss_tmo, | 478 | MODULE_PARM_DESC(dev_loss_tmo, |
478 | "Maximum number of seconds that the FC transport should" | 479 | "Maximum number of seconds that the FC transport should" |
479 | " insulate the loss of a remote port. Once this value is" | 480 | " insulate the loss of a remote port. Once this value is" |
@@ -1956,6 +1957,19 @@ static int fc_user_scan(struct Scsi_Host *shost, uint channel, | |||
1956 | return 0; | 1957 | return 0; |
1957 | } | 1958 | } |
1958 | 1959 | ||
1960 | static int fc_tsk_mgmt_response(struct Scsi_Host *shost, u64 nexus, u64 tm_id, | ||
1961 | int result) | ||
1962 | { | ||
1963 | struct fc_internal *i = to_fc_internal(shost->transportt); | ||
1964 | return i->f->tsk_mgmt_response(shost, nexus, tm_id, result); | ||
1965 | } | ||
1966 | |||
1967 | static int fc_it_nexus_response(struct Scsi_Host *shost, u64 nexus, int result) | ||
1968 | { | ||
1969 | struct fc_internal *i = to_fc_internal(shost->transportt); | ||
1970 | return i->f->it_nexus_response(shost, nexus, result); | ||
1971 | } | ||
1972 | |||
1959 | struct scsi_transport_template * | 1973 | struct scsi_transport_template * |
1960 | fc_attach_transport(struct fc_function_template *ft) | 1974 | fc_attach_transport(struct fc_function_template *ft) |
1961 | { | 1975 | { |
@@ -1999,6 +2013,10 @@ fc_attach_transport(struct fc_function_template *ft) | |||
1999 | 2013 | ||
2000 | i->t.user_scan = fc_user_scan; | 2014 | i->t.user_scan = fc_user_scan; |
2001 | 2015 | ||
2016 | /* target-mode drivers' functions */ | ||
2017 | i->t.tsk_mgmt_response = fc_tsk_mgmt_response; | ||
2018 | i->t.it_nexus_response = fc_it_nexus_response; | ||
2019 | |||
2002 | /* | 2020 | /* |
2003 | * Setup SCSI Target Attributes. | 2021 | * Setup SCSI Target Attributes. |
2004 | */ | 2022 | */ |
@@ -2756,6 +2774,10 @@ fc_remote_port_delete(struct fc_rport *rport) | |||
2756 | 2774 | ||
2757 | spin_unlock_irqrestore(shost->host_lock, flags); | 2775 | spin_unlock_irqrestore(shost->host_lock, flags); |
2758 | 2776 | ||
2777 | if (rport->roles & FC_PORT_ROLE_FCP_INITIATOR && | ||
2778 | shost->active_mode & MODE_TARGET) | ||
2779 | fc_tgt_it_nexus_destroy(shost, (unsigned long)rport); | ||
2780 | |||
2759 | scsi_target_block(&rport->dev); | 2781 | scsi_target_block(&rport->dev); |
2760 | 2782 | ||
2761 | /* see if we need to kill io faster than waiting for device loss */ | 2783 | /* see if we need to kill io faster than waiting for device loss */ |
@@ -2796,6 +2818,7 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) | |||
2796 | struct fc_host_attrs *fc_host = shost_to_fc_host(shost); | 2818 | struct fc_host_attrs *fc_host = shost_to_fc_host(shost); |
2797 | unsigned long flags; | 2819 | unsigned long flags; |
2798 | int create = 0; | 2820 | int create = 0; |
2821 | int ret; | ||
2799 | 2822 | ||
2800 | spin_lock_irqsave(shost->host_lock, flags); | 2823 | spin_lock_irqsave(shost->host_lock, flags); |
2801 | if (roles & FC_PORT_ROLE_FCP_TARGET) { | 2824 | if (roles & FC_PORT_ROLE_FCP_TARGET) { |
@@ -2804,6 +2827,12 @@ fc_remote_port_rolechg(struct fc_rport *rport, u32 roles) | |||
2804 | create = 1; | 2827 | create = 1; |
2805 | } else if (!(rport->roles & FC_PORT_ROLE_FCP_TARGET)) | 2828 | } else if (!(rport->roles & FC_PORT_ROLE_FCP_TARGET)) |
2806 | create = 1; | 2829 | create = 1; |
2830 | } else if (shost->active_mode & MODE_TARGET) { | ||
2831 | ret = fc_tgt_it_nexus_create(shost, (unsigned long)rport, | ||
2832 | (char *)&rport->node_name); | ||
2833 | if (ret) | ||
2834 | printk(KERN_ERR "FC Remore Port tgt nexus failed %d\n", | ||
2835 | ret); | ||
2807 | } | 2836 | } |
2808 | 2837 | ||
2809 | rport->roles = roles; | 2838 | rport->roles = roles; |
@@ -2988,10 +3017,12 @@ fc_scsi_scan_rport(struct work_struct *work) | |||
2988 | struct fc_rport *rport = | 3017 | struct fc_rport *rport = |
2989 | container_of(work, struct fc_rport, scan_work); | 3018 | container_of(work, struct fc_rport, scan_work); |
2990 | struct Scsi_Host *shost = rport_to_shost(rport); | 3019 | struct Scsi_Host *shost = rport_to_shost(rport); |
3020 | struct fc_internal *i = to_fc_internal(shost->transportt); | ||
2991 | unsigned long flags; | 3021 | unsigned long flags; |
2992 | 3022 | ||
2993 | if ((rport->port_state == FC_PORTSTATE_ONLINE) && | 3023 | if ((rport->port_state == FC_PORTSTATE_ONLINE) && |
2994 | (rport->roles & FC_PORT_ROLE_FCP_TARGET)) { | 3024 | (rport->roles & FC_PORT_ROLE_FCP_TARGET) && |
3025 | !(i->f->disable_target_scan)) { | ||
2995 | scsi_scan_target(&rport->dev, rport->channel, | 3026 | scsi_scan_target(&rport->dev, rport->channel, |
2996 | rport->scsi_target_id, SCAN_WILD_CARD, 1); | 3027 | rport->scsi_target_id, SCAN_WILD_CARD, 1); |
2997 | } | 3028 | } |
diff --git a/drivers/scsi/scsi_transport_fc_internal.h b/drivers/scsi/scsi_transport_fc_internal.h new file mode 100644 index 000000000000..e7bfbe751c1f --- /dev/null +++ b/drivers/scsi/scsi_transport_fc_internal.h | |||
@@ -0,0 +1,26 @@ | |||
1 | #include <scsi/scsi_tgt.h> | ||
2 | |||
3 | #ifdef CONFIG_SCSI_FC_TGT_ATTRS | ||
4 | static inline int fc_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id, | ||
5 | char *initiator) | ||
6 | { | ||
7 | return scsi_tgt_it_nexus_create(shost, itn_id, initiator); | ||
8 | } | ||
9 | |||
10 | static inline int fc_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id) | ||
11 | { | ||
12 | return scsi_tgt_it_nexus_destroy(shost, itn_id); | ||
13 | } | ||
14 | #else | ||
15 | static inline int fc_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id, | ||
16 | char *initiator) | ||
17 | { | ||
18 | return 0; | ||
19 | } | ||
20 | |||
21 | static inline int fc_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id) | ||
22 | { | ||
23 | return 0; | ||
24 | } | ||
25 | |||
26 | #endif | ||
diff --git a/drivers/scsi/scsi_transport_srp.c b/drivers/scsi/scsi_transport_srp.c new file mode 100644 index 000000000000..44a340bd937b --- /dev/null +++ b/drivers/scsi/scsi_transport_srp.c | |||
@@ -0,0 +1,381 @@ | |||
1 | /* | ||
2 | * SCSI RDMA (SRP) transport class | ||
3 | * | ||
4 | * Copyright (C) 2007 FUJITA Tomonori <tomof@acm.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License as | ||
8 | * published by the Free Software Foundation, version 2 of the | ||
9 | * License. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, but | ||
12 | * WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
14 | * General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA | ||
19 | * 02110-1301 USA | ||
20 | */ | ||
21 | #include <linux/init.h> | ||
22 | #include <linux/module.h> | ||
23 | #include <linux/jiffies.h> | ||
24 | #include <linux/err.h> | ||
25 | #include <linux/slab.h> | ||
26 | #include <linux/string.h> | ||
27 | |||
28 | #include <scsi/scsi.h> | ||
29 | #include <scsi/scsi_device.h> | ||
30 | #include <scsi/scsi_host.h> | ||
31 | #include <scsi/scsi_transport.h> | ||
32 | #include <scsi/scsi_transport_srp.h> | ||
33 | #include "scsi_transport_srp_internal.h" | ||
34 | |||
35 | struct srp_host_attrs { | ||
36 | atomic_t next_port_id; | ||
37 | }; | ||
38 | #define to_srp_host_attrs(host) ((struct srp_host_attrs *)(host)->shost_data) | ||
39 | |||
40 | #define SRP_HOST_ATTRS 0 | ||
41 | #define SRP_RPORT_ATTRS 2 | ||
42 | |||
43 | struct srp_internal { | ||
44 | struct scsi_transport_template t; | ||
45 | struct srp_function_template *f; | ||
46 | |||
47 | struct class_device_attribute *host_attrs[SRP_HOST_ATTRS + 1]; | ||
48 | |||
49 | struct class_device_attribute *rport_attrs[SRP_RPORT_ATTRS + 1]; | ||
50 | struct class_device_attribute private_rport_attrs[SRP_RPORT_ATTRS]; | ||
51 | struct transport_container rport_attr_cont; | ||
52 | }; | ||
53 | |||
54 | #define to_srp_internal(tmpl) container_of(tmpl, struct srp_internal, t) | ||
55 | |||
56 | #define dev_to_rport(d) container_of(d, struct srp_rport, dev) | ||
57 | #define transport_class_to_srp_rport(cdev) dev_to_rport((cdev)->dev) | ||
58 | |||
59 | static int srp_host_setup(struct transport_container *tc, struct device *dev, | ||
60 | struct class_device *cdev) | ||
61 | { | ||
62 | struct Scsi_Host *shost = dev_to_shost(dev); | ||
63 | struct srp_host_attrs *srp_host = to_srp_host_attrs(shost); | ||
64 | |||
65 | atomic_set(&srp_host->next_port_id, 0); | ||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | static DECLARE_TRANSPORT_CLASS(srp_host_class, "srp_host", srp_host_setup, | ||
70 | NULL, NULL); | ||
71 | |||
72 | static DECLARE_TRANSPORT_CLASS(srp_rport_class, "srp_remote_ports", | ||
73 | NULL, NULL, NULL); | ||
74 | |||
75 | #define SETUP_TEMPLATE(attrb, field, perm, test, ro_test, ro_perm) \ | ||
76 | i->private_##attrb[count] = class_device_attr_##field; \ | ||
77 | i->private_##attrb[count].attr.mode = perm; \ | ||
78 | if (ro_test) { \ | ||
79 | i->private_##attrb[count].attr.mode = ro_perm; \ | ||
80 | i->private_##attrb[count].store = NULL; \ | ||
81 | } \ | ||
82 | i->attrb[count] = &i->private_##attrb[count]; \ | ||
83 | if (test) \ | ||
84 | count++ | ||
85 | |||
86 | #define SETUP_RPORT_ATTRIBUTE_RD(field) \ | ||
87 | SETUP_TEMPLATE(rport_attrs, field, S_IRUGO, 1, 0, 0) | ||
88 | |||
89 | #define SETUP_RPORT_ATTRIBUTE_RW(field) \ | ||
90 | SETUP_TEMPLATE(rport_attrs, field, S_IRUGO | S_IWUSR, \ | ||
91 | 1, 1, S_IRUGO) | ||
92 | |||
93 | #define SRP_PID(p) \ | ||
94 | (p)->port_id[0], (p)->port_id[1], (p)->port_id[2], (p)->port_id[3], \ | ||
95 | (p)->port_id[4], (p)->port_id[5], (p)->port_id[6], (p)->port_id[7], \ | ||
96 | (p)->port_id[8], (p)->port_id[9], (p)->port_id[10], (p)->port_id[11], \ | ||
97 | (p)->port_id[12], (p)->port_id[13], (p)->port_id[14], (p)->port_id[15] | ||
98 | |||
99 | #define SRP_PID_FMT "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x:" \ | ||
100 | "%02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x" | ||
101 | |||
102 | static ssize_t | ||
103 | show_srp_rport_id(struct class_device *cdev, char *buf) | ||
104 | { | ||
105 | struct srp_rport *rport = transport_class_to_srp_rport(cdev); | ||
106 | return sprintf(buf, SRP_PID_FMT "\n", SRP_PID(rport)); | ||
107 | } | ||
108 | |||
109 | static CLASS_DEVICE_ATTR(port_id, S_IRUGO, show_srp_rport_id, NULL); | ||
110 | |||
111 | static const struct { | ||
112 | u32 value; | ||
113 | char *name; | ||
114 | } srp_rport_role_names[] = { | ||
115 | {SRP_RPORT_ROLE_INITIATOR, "SRP Initiator"}, | ||
116 | {SRP_RPORT_ROLE_TARGET, "SRP Target"}, | ||
117 | }; | ||
118 | |||
119 | static ssize_t | ||
120 | show_srp_rport_roles(struct class_device *cdev, char *buf) | ||
121 | { | ||
122 | struct srp_rport *rport = transport_class_to_srp_rport(cdev); | ||
123 | int i; | ||
124 | char *name = NULL; | ||
125 | |||
126 | for (i = 0; i < ARRAY_SIZE(srp_rport_role_names); i++) | ||
127 | if (srp_rport_role_names[i].value == rport->roles) { | ||
128 | name = srp_rport_role_names[i].name; | ||
129 | break; | ||
130 | } | ||
131 | return sprintf(buf, "%s\n", name ? : "unknown"); | ||
132 | } | ||
133 | |||
134 | static CLASS_DEVICE_ATTR(roles, S_IRUGO, show_srp_rport_roles, NULL); | ||
135 | |||
136 | static void srp_rport_release(struct device *dev) | ||
137 | { | ||
138 | struct srp_rport *rport = dev_to_rport(dev); | ||
139 | |||
140 | put_device(dev->parent); | ||
141 | kfree(rport); | ||
142 | } | ||
143 | |||
144 | static int scsi_is_srp_rport(const struct device *dev) | ||
145 | { | ||
146 | return dev->release == srp_rport_release; | ||
147 | } | ||
148 | |||
149 | static int srp_rport_match(struct attribute_container *cont, | ||
150 | struct device *dev) | ||
151 | { | ||
152 | struct Scsi_Host *shost; | ||
153 | struct srp_internal *i; | ||
154 | |||
155 | if (!scsi_is_srp_rport(dev)) | ||
156 | return 0; | ||
157 | |||
158 | shost = dev_to_shost(dev->parent); | ||
159 | if (!shost->transportt) | ||
160 | return 0; | ||
161 | if (shost->transportt->host_attrs.ac.class != &srp_host_class.class) | ||
162 | return 0; | ||
163 | |||
164 | i = to_srp_internal(shost->transportt); | ||
165 | return &i->rport_attr_cont.ac == cont; | ||
166 | } | ||
167 | |||
168 | static int srp_host_match(struct attribute_container *cont, struct device *dev) | ||
169 | { | ||
170 | struct Scsi_Host *shost; | ||
171 | struct srp_internal *i; | ||
172 | |||
173 | if (!scsi_is_host_device(dev)) | ||
174 | return 0; | ||
175 | |||
176 | shost = dev_to_shost(dev); | ||
177 | if (!shost->transportt) | ||
178 | return 0; | ||
179 | if (shost->transportt->host_attrs.ac.class != &srp_host_class.class) | ||
180 | return 0; | ||
181 | |||
182 | i = to_srp_internal(shost->transportt); | ||
183 | return &i->t.host_attrs.ac == cont; | ||
184 | } | ||
185 | |||
186 | /** | ||
187 | * srp_rport_add - add a SRP remote port to the device hierarchy | ||
188 | * | ||
189 | * @shost: scsi host the remote port is connected to. | ||
190 | * @ids: The port id for the remote port. | ||
191 | * | ||
192 | * publishes a port to the rest of the system | ||
193 | */ | ||
194 | struct srp_rport *srp_rport_add(struct Scsi_Host *shost, | ||
195 | struct srp_rport_identifiers *ids) | ||
196 | { | ||
197 | struct srp_rport *rport; | ||
198 | struct device *parent = &shost->shost_gendev; | ||
199 | int id, ret; | ||
200 | |||
201 | rport = kzalloc(sizeof(*rport), GFP_KERNEL); | ||
202 | if (!rport) | ||
203 | return ERR_PTR(-ENOMEM); | ||
204 | |||
205 | device_initialize(&rport->dev); | ||
206 | |||
207 | rport->dev.parent = get_device(parent); | ||
208 | rport->dev.release = srp_rport_release; | ||
209 | |||
210 | memcpy(rport->port_id, ids->port_id, sizeof(rport->port_id)); | ||
211 | rport->roles = ids->roles; | ||
212 | |||
213 | id = atomic_inc_return(&to_srp_host_attrs(shost)->next_port_id); | ||
214 | sprintf(rport->dev.bus_id, "port-%d:%d", shost->host_no, id); | ||
215 | |||
216 | transport_setup_device(&rport->dev); | ||
217 | |||
218 | ret = device_add(&rport->dev); | ||
219 | if (ret) { | ||
220 | transport_destroy_device(&rport->dev); | ||
221 | put_device(&rport->dev); | ||
222 | return ERR_PTR(ret); | ||
223 | } | ||
224 | |||
225 | if (shost->active_mode & MODE_TARGET && | ||
226 | ids->roles == SRP_RPORT_ROLE_INITIATOR) { | ||
227 | ret = srp_tgt_it_nexus_create(shost, (unsigned long)rport, | ||
228 | rport->port_id); | ||
229 | if (ret) { | ||
230 | device_del(&rport->dev); | ||
231 | transport_destroy_device(&rport->dev); | ||
232 | put_device(&rport->dev); | ||
233 | return ERR_PTR(ret); | ||
234 | } | ||
235 | } | ||
236 | |||
237 | transport_add_device(&rport->dev); | ||
238 | transport_configure_device(&rport->dev); | ||
239 | |||
240 | return rport; | ||
241 | } | ||
242 | EXPORT_SYMBOL_GPL(srp_rport_add); | ||
243 | |||
244 | /** | ||
245 | * srp_rport_del -- remove a SRP remote port | ||
246 | * @port: SRP remote port to remove | ||
247 | * | ||
248 | * Removes the specified SRP remote port. | ||
249 | */ | ||
250 | void srp_rport_del(struct srp_rport *rport) | ||
251 | { | ||
252 | struct device *dev = &rport->dev; | ||
253 | struct Scsi_Host *shost = dev_to_shost(dev->parent); | ||
254 | |||
255 | if (shost->active_mode & MODE_TARGET && | ||
256 | rport->roles == SRP_RPORT_ROLE_INITIATOR) | ||
257 | srp_tgt_it_nexus_destroy(shost, (unsigned long)rport); | ||
258 | |||
259 | transport_remove_device(dev); | ||
260 | device_del(dev); | ||
261 | transport_destroy_device(dev); | ||
262 | put_device(dev); | ||
263 | } | ||
264 | EXPORT_SYMBOL_GPL(srp_rport_del); | ||
265 | |||
266 | static int do_srp_rport_del(struct device *dev, void *data) | ||
267 | { | ||
268 | srp_rport_del(dev_to_rport(dev)); | ||
269 | return 0; | ||
270 | } | ||
271 | |||
272 | /** | ||
273 | * srp_remove_host -- tear down a Scsi_Host's SRP data structures | ||
274 | * @shost: Scsi Host that is torn down | ||
275 | * | ||
276 | * Removes all SRP remote ports for a given Scsi_Host. | ||
277 | * Must be called just before scsi_remove_host for SRP HBAs. | ||
278 | */ | ||
279 | void srp_remove_host(struct Scsi_Host *shost) | ||
280 | { | ||
281 | device_for_each_child(&shost->shost_gendev, NULL, do_srp_rport_del); | ||
282 | } | ||
283 | EXPORT_SYMBOL_GPL(srp_remove_host); | ||
284 | |||
285 | static int srp_tsk_mgmt_response(struct Scsi_Host *shost, u64 nexus, u64 tm_id, | ||
286 | int result) | ||
287 | { | ||
288 | struct srp_internal *i = to_srp_internal(shost->transportt); | ||
289 | return i->f->tsk_mgmt_response(shost, nexus, tm_id, result); | ||
290 | } | ||
291 | |||
292 | static int srp_it_nexus_response(struct Scsi_Host *shost, u64 nexus, int result) | ||
293 | { | ||
294 | struct srp_internal *i = to_srp_internal(shost->transportt); | ||
295 | return i->f->it_nexus_response(shost, nexus, result); | ||
296 | } | ||
297 | |||
298 | /** | ||
299 | * srp_attach_transport -- instantiate SRP transport template | ||
300 | * @ft: SRP transport class function template | ||
301 | */ | ||
302 | struct scsi_transport_template * | ||
303 | srp_attach_transport(struct srp_function_template *ft) | ||
304 | { | ||
305 | int count; | ||
306 | struct srp_internal *i; | ||
307 | |||
308 | i = kzalloc(sizeof(*i), GFP_KERNEL); | ||
309 | if (!i) | ||
310 | return NULL; | ||
311 | |||
312 | i->t.tsk_mgmt_response = srp_tsk_mgmt_response; | ||
313 | i->t.it_nexus_response = srp_it_nexus_response; | ||
314 | |||
315 | i->t.host_size = sizeof(struct srp_host_attrs); | ||
316 | i->t.host_attrs.ac.attrs = &i->host_attrs[0]; | ||
317 | i->t.host_attrs.ac.class = &srp_host_class.class; | ||
318 | i->t.host_attrs.ac.match = srp_host_match; | ||
319 | i->host_attrs[0] = NULL; | ||
320 | transport_container_register(&i->t.host_attrs); | ||
321 | |||
322 | i->rport_attr_cont.ac.attrs = &i->rport_attrs[0]; | ||
323 | i->rport_attr_cont.ac.class = &srp_rport_class.class; | ||
324 | i->rport_attr_cont.ac.match = srp_rport_match; | ||
325 | transport_container_register(&i->rport_attr_cont); | ||
326 | |||
327 | count = 0; | ||
328 | SETUP_RPORT_ATTRIBUTE_RD(port_id); | ||
329 | SETUP_RPORT_ATTRIBUTE_RD(roles); | ||
330 | i->rport_attrs[count] = NULL; | ||
331 | |||
332 | i->f = ft; | ||
333 | |||
334 | return &i->t; | ||
335 | } | ||
336 | EXPORT_SYMBOL_GPL(srp_attach_transport); | ||
337 | |||
338 | /** | ||
339 | * srp_release_transport -- release SRP transport template instance | ||
340 | * @t: transport template instance | ||
341 | */ | ||
342 | void srp_release_transport(struct scsi_transport_template *t) | ||
343 | { | ||
344 | struct srp_internal *i = to_srp_internal(t); | ||
345 | |||
346 | transport_container_unregister(&i->t.host_attrs); | ||
347 | transport_container_unregister(&i->rport_attr_cont); | ||
348 | |||
349 | kfree(i); | ||
350 | } | ||
351 | EXPORT_SYMBOL_GPL(srp_release_transport); | ||
352 | |||
353 | static __init int srp_transport_init(void) | ||
354 | { | ||
355 | int ret; | ||
356 | |||
357 | ret = transport_class_register(&srp_host_class); | ||
358 | if (ret) | ||
359 | return ret; | ||
360 | ret = transport_class_register(&srp_rport_class); | ||
361 | if (ret) | ||
362 | goto unregister_host_class; | ||
363 | |||
364 | return 0; | ||
365 | unregister_host_class: | ||
366 | transport_class_unregister(&srp_host_class); | ||
367 | return ret; | ||
368 | } | ||
369 | |||
370 | static void __exit srp_transport_exit(void) | ||
371 | { | ||
372 | transport_class_unregister(&srp_host_class); | ||
373 | transport_class_unregister(&srp_rport_class); | ||
374 | } | ||
375 | |||
376 | MODULE_AUTHOR("FUJITA Tomonori"); | ||
377 | MODULE_DESCRIPTION("SRP Transport Attributes"); | ||
378 | MODULE_LICENSE("GPL"); | ||
379 | |||
380 | module_init(srp_transport_init); | ||
381 | module_exit(srp_transport_exit); | ||
diff --git a/drivers/scsi/scsi_transport_srp_internal.h b/drivers/scsi/scsi_transport_srp_internal.h new file mode 100644 index 000000000000..8a79747f9f3d --- /dev/null +++ b/drivers/scsi/scsi_transport_srp_internal.h | |||
@@ -0,0 +1,25 @@ | |||
1 | #include <scsi/scsi_tgt.h> | ||
2 | |||
3 | #ifdef CONFIG_SCSI_SRP_TGT_ATTRS | ||
4 | static inline int srp_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id, | ||
5 | char *initiator) | ||
6 | { | ||
7 | return scsi_tgt_it_nexus_create(shost, itn_id, initiator); | ||
8 | } | ||
9 | |||
10 | static inline int srp_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id) | ||
11 | { | ||
12 | return scsi_tgt_it_nexus_destroy(shost, itn_id); | ||
13 | } | ||
14 | |||
15 | #else | ||
16 | static inline int srp_tgt_it_nexus_create(struct Scsi_Host *shost, u64 itn_id, | ||
17 | char *initiator) | ||
18 | { | ||
19 | return 0; | ||
20 | } | ||
21 | static inline int srp_tgt_it_nexus_destroy(struct Scsi_Host *shost, u64 itn_id) | ||
22 | { | ||
23 | return 0; | ||
24 | } | ||
25 | #endif | ||
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index 2c6116fd4578..0a3a528212c2 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c | |||
@@ -86,6 +86,19 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_DISK); | |||
86 | MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); | 86 | MODULE_ALIAS_SCSI_DEVICE(TYPE_MOD); |
87 | MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); | 87 | MODULE_ALIAS_SCSI_DEVICE(TYPE_RBC); |
88 | 88 | ||
89 | static int sd_revalidate_disk(struct gendisk *); | ||
90 | static int sd_probe(struct device *); | ||
91 | static int sd_remove(struct device *); | ||
92 | static void sd_shutdown(struct device *); | ||
93 | static int sd_suspend(struct device *, pm_message_t state); | ||
94 | static int sd_resume(struct device *); | ||
95 | static void sd_rescan(struct device *); | ||
96 | static int sd_done(struct scsi_cmnd *); | ||
97 | static void sd_read_capacity(struct scsi_disk *sdkp, unsigned char *buffer); | ||
98 | static void scsi_disk_release(struct class_device *cdev); | ||
99 | static void sd_print_sense_hdr(struct scsi_disk *, struct scsi_sense_hdr *); | ||
100 | static void sd_print_result(struct scsi_disk *, int); | ||
101 | |||
89 | static DEFINE_IDR(sd_index_idr); | 102 | static DEFINE_IDR(sd_index_idr); |
90 | static DEFINE_SPINLOCK(sd_index_lock); | 103 | static DEFINE_SPINLOCK(sd_index_lock); |
91 | 104 | ||
@@ -240,7 +253,7 @@ static struct scsi_driver sd_template = { | |||
240 | .shutdown = sd_shutdown, | 253 | .shutdown = sd_shutdown, |
241 | }, | 254 | }, |
242 | .rescan = sd_rescan, | 255 | .rescan = sd_rescan, |
243 | .init_command = sd_init_command, | 256 | .done = sd_done, |
244 | }; | 257 | }; |
245 | 258 | ||
246 | /* | 259 | /* |
@@ -331,14 +344,31 @@ static void scsi_disk_put(struct scsi_disk *sdkp) | |||
331 | * | 344 | * |
332 | * Returns 1 if successful and 0 if error (or cannot be done now). | 345 | * Returns 1 if successful and 0 if error (or cannot be done now). |
333 | **/ | 346 | **/ |
334 | static int sd_init_command(struct scsi_cmnd * SCpnt) | 347 | static int sd_prep_fn(struct request_queue *q, struct request *rq) |
335 | { | 348 | { |
336 | struct scsi_device *sdp = SCpnt->device; | 349 | struct scsi_cmnd *SCpnt; |
337 | struct request *rq = SCpnt->request; | 350 | struct scsi_device *sdp = q->queuedata; |
338 | struct gendisk *disk = rq->rq_disk; | 351 | struct gendisk *disk = rq->rq_disk; |
339 | sector_t block = rq->sector; | 352 | sector_t block = rq->sector; |
340 | unsigned int this_count = SCpnt->request_bufflen >> 9; | 353 | unsigned int this_count = rq->nr_sectors; |
341 | unsigned int timeout = sdp->timeout; | 354 | unsigned int timeout = sdp->timeout; |
355 | int ret; | ||
356 | |||
357 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { | ||
358 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); | ||
359 | goto out; | ||
360 | } else if (rq->cmd_type != REQ_TYPE_FS) { | ||
361 | ret = BLKPREP_KILL; | ||
362 | goto out; | ||
363 | } | ||
364 | ret = scsi_setup_fs_cmnd(sdp, rq); | ||
365 | if (ret != BLKPREP_OK) | ||
366 | goto out; | ||
367 | SCpnt = rq->special; | ||
368 | |||
369 | /* from here on until we're complete, any goto out | ||
370 | * is used for a killable error condition */ | ||
371 | ret = BLKPREP_KILL; | ||
342 | 372 | ||
343 | SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt, | 373 | SCSI_LOG_HLQUEUE(1, scmd_printk(KERN_INFO, SCpnt, |
344 | "sd_init_command: block=%llu, " | 374 | "sd_init_command: block=%llu, " |
@@ -353,7 +383,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
353 | rq->nr_sectors)); | 383 | rq->nr_sectors)); |
354 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, | 384 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, |
355 | "Retry with 0x%p\n", SCpnt)); | 385 | "Retry with 0x%p\n", SCpnt)); |
356 | return 0; | 386 | goto out; |
357 | } | 387 | } |
358 | 388 | ||
359 | if (sdp->changed) { | 389 | if (sdp->changed) { |
@@ -362,8 +392,9 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
362 | * the changed bit has been reset | 392 | * the changed bit has been reset |
363 | */ | 393 | */ |
364 | /* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */ | 394 | /* printk("SCSI disk has been changed. Prohibiting further I/O.\n"); */ |
365 | return 0; | 395 | goto out; |
366 | } | 396 | } |
397 | |||
367 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", | 398 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, "block=%llu\n", |
368 | (unsigned long long)block)); | 399 | (unsigned long long)block)); |
369 | 400 | ||
@@ -382,7 +413,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
382 | if ((block & 1) || (rq->nr_sectors & 1)) { | 413 | if ((block & 1) || (rq->nr_sectors & 1)) { |
383 | scmd_printk(KERN_ERR, SCpnt, | 414 | scmd_printk(KERN_ERR, SCpnt, |
384 | "Bad block number requested\n"); | 415 | "Bad block number requested\n"); |
385 | return 0; | 416 | goto out; |
386 | } else { | 417 | } else { |
387 | block = block >> 1; | 418 | block = block >> 1; |
388 | this_count = this_count >> 1; | 419 | this_count = this_count >> 1; |
@@ -392,7 +423,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
392 | if ((block & 3) || (rq->nr_sectors & 3)) { | 423 | if ((block & 3) || (rq->nr_sectors & 3)) { |
393 | scmd_printk(KERN_ERR, SCpnt, | 424 | scmd_printk(KERN_ERR, SCpnt, |
394 | "Bad block number requested\n"); | 425 | "Bad block number requested\n"); |
395 | return 0; | 426 | goto out; |
396 | } else { | 427 | } else { |
397 | block = block >> 2; | 428 | block = block >> 2; |
398 | this_count = this_count >> 2; | 429 | this_count = this_count >> 2; |
@@ -402,7 +433,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
402 | if ((block & 7) || (rq->nr_sectors & 7)) { | 433 | if ((block & 7) || (rq->nr_sectors & 7)) { |
403 | scmd_printk(KERN_ERR, SCpnt, | 434 | scmd_printk(KERN_ERR, SCpnt, |
404 | "Bad block number requested\n"); | 435 | "Bad block number requested\n"); |
405 | return 0; | 436 | goto out; |
406 | } else { | 437 | } else { |
407 | block = block >> 3; | 438 | block = block >> 3; |
408 | this_count = this_count >> 3; | 439 | this_count = this_count >> 3; |
@@ -410,7 +441,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
410 | } | 441 | } |
411 | if (rq_data_dir(rq) == WRITE) { | 442 | if (rq_data_dir(rq) == WRITE) { |
412 | if (!sdp->writeable) { | 443 | if (!sdp->writeable) { |
413 | return 0; | 444 | goto out; |
414 | } | 445 | } |
415 | SCpnt->cmnd[0] = WRITE_6; | 446 | SCpnt->cmnd[0] = WRITE_6; |
416 | SCpnt->sc_data_direction = DMA_TO_DEVICE; | 447 | SCpnt->sc_data_direction = DMA_TO_DEVICE; |
@@ -419,7 +450,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
419 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; | 450 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; |
420 | } else { | 451 | } else { |
421 | scmd_printk(KERN_ERR, SCpnt, "Unknown command %x\n", rq->cmd_flags); | 452 | scmd_printk(KERN_ERR, SCpnt, "Unknown command %x\n", rq->cmd_flags); |
422 | return 0; | 453 | goto out; |
423 | } | 454 | } |
424 | 455 | ||
425 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, | 456 | SCSI_LOG_HLQUEUE(2, scmd_printk(KERN_INFO, SCpnt, |
@@ -470,7 +501,7 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
470 | */ | 501 | */ |
471 | scmd_printk(KERN_ERR, SCpnt, | 502 | scmd_printk(KERN_ERR, SCpnt, |
472 | "FUA write on READ/WRITE(6) drive\n"); | 503 | "FUA write on READ/WRITE(6) drive\n"); |
473 | return 0; | 504 | goto out; |
474 | } | 505 | } |
475 | 506 | ||
476 | SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f); | 507 | SCpnt->cmnd[1] |= (unsigned char) ((block >> 16) & 0x1f); |
@@ -492,16 +523,12 @@ static int sd_init_command(struct scsi_cmnd * SCpnt) | |||
492 | SCpnt->timeout_per_command = timeout; | 523 | SCpnt->timeout_per_command = timeout; |
493 | 524 | ||
494 | /* | 525 | /* |
495 | * This is the completion routine we use. This is matched in terms | ||
496 | * of capability to this function. | ||
497 | */ | ||
498 | SCpnt->done = sd_rw_intr; | ||
499 | |||
500 | /* | ||
501 | * This indicates that the command is ready from our end to be | 526 | * This indicates that the command is ready from our end to be |
502 | * queued. | 527 | * queued. |
503 | */ | 528 | */ |
504 | return 1; | 529 | ret = BLKPREP_OK; |
530 | out: | ||
531 | return scsi_prep_return(q, rq, ret); | ||
505 | } | 532 | } |
506 | 533 | ||
507 | /** | 534 | /** |
@@ -889,13 +916,13 @@ static struct block_device_operations sd_fops = { | |||
889 | }; | 916 | }; |
890 | 917 | ||
891 | /** | 918 | /** |
892 | * sd_rw_intr - bottom half handler: called when the lower level | 919 | * sd_done - bottom half handler: called when the lower level |
893 | * driver has completed (successfully or otherwise) a scsi command. | 920 | * driver has completed (successfully or otherwise) a scsi command. |
894 | * @SCpnt: mid-level's per command structure. | 921 | * @SCpnt: mid-level's per command structure. |
895 | * | 922 | * |
896 | * Note: potentially run from within an ISR. Must not block. | 923 | * Note: potentially run from within an ISR. Must not block. |
897 | **/ | 924 | **/ |
898 | static void sd_rw_intr(struct scsi_cmnd * SCpnt) | 925 | static int sd_done(struct scsi_cmnd *SCpnt) |
899 | { | 926 | { |
900 | int result = SCpnt->result; | 927 | int result = SCpnt->result; |
901 | unsigned int xfer_size = SCpnt->request_bufflen; | 928 | unsigned int xfer_size = SCpnt->request_bufflen; |
@@ -916,7 +943,7 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) | |||
916 | SCSI_LOG_HLCOMPLETE(1, scsi_print_result(SCpnt)); | 943 | SCSI_LOG_HLCOMPLETE(1, scsi_print_result(SCpnt)); |
917 | if (sense_valid) { | 944 | if (sense_valid) { |
918 | SCSI_LOG_HLCOMPLETE(1, scmd_printk(KERN_INFO, SCpnt, | 945 | SCSI_LOG_HLCOMPLETE(1, scmd_printk(KERN_INFO, SCpnt, |
919 | "sd_rw_intr: sb[respc,sk,asc," | 946 | "sd_done: sb[respc,sk,asc," |
920 | "ascq]=%x,%x,%x,%x\n", | 947 | "ascq]=%x,%x,%x,%x\n", |
921 | sshdr.response_code, | 948 | sshdr.response_code, |
922 | sshdr.sense_key, sshdr.asc, | 949 | sshdr.sense_key, sshdr.asc, |
@@ -988,7 +1015,7 @@ static void sd_rw_intr(struct scsi_cmnd * SCpnt) | |||
988 | break; | 1015 | break; |
989 | } | 1016 | } |
990 | out: | 1017 | out: |
991 | scsi_io_completion(SCpnt, good_bytes); | 1018 | return good_bytes; |
992 | } | 1019 | } |
993 | 1020 | ||
994 | static int media_not_present(struct scsi_disk *sdkp, | 1021 | static int media_not_present(struct scsi_disk *sdkp, |
@@ -1669,6 +1696,7 @@ static int sd_probe(struct device *dev) | |||
1669 | 1696 | ||
1670 | sd_revalidate_disk(gd); | 1697 | sd_revalidate_disk(gd); |
1671 | 1698 | ||
1699 | blk_queue_prep_rq(sdp->request_queue, sd_prep_fn); | ||
1672 | blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush); | 1700 | blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush); |
1673 | 1701 | ||
1674 | gd->driverfs_dev = &sdp->sdev_gendev; | 1702 | gd->driverfs_dev = &sdp->sdev_gendev; |
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c index 85d38940a6c9..f6f5fc7d0cee 100644 --- a/drivers/scsi/sg.c +++ b/drivers/scsi/sg.c | |||
@@ -43,6 +43,7 @@ static int sg_version_num = 30534; /* 2 digits for each component */ | |||
43 | #include <linux/poll.h> | 43 | #include <linux/poll.h> |
44 | #include <linux/moduleparam.h> | 44 | #include <linux/moduleparam.h> |
45 | #include <linux/cdev.h> | 45 | #include <linux/cdev.h> |
46 | #include <linux/idr.h> | ||
46 | #include <linux/seq_file.h> | 47 | #include <linux/seq_file.h> |
47 | #include <linux/blkdev.h> | 48 | #include <linux/blkdev.h> |
48 | #include <linux/delay.h> | 49 | #include <linux/delay.h> |
@@ -99,12 +100,11 @@ static int scatter_elem_sz_prev = SG_SCATTER_SZ; | |||
99 | #define SG_SECTOR_SZ 512 | 100 | #define SG_SECTOR_SZ 512 |
100 | #define SG_SECTOR_MSK (SG_SECTOR_SZ - 1) | 101 | #define SG_SECTOR_MSK (SG_SECTOR_SZ - 1) |
101 | 102 | ||
102 | #define SG_DEV_ARR_LUMP 32 /* amount to over allocate sg_dev_arr by */ | ||
103 | |||
104 | static int sg_add(struct class_device *, struct class_interface *); | 103 | static int sg_add(struct class_device *, struct class_interface *); |
105 | static void sg_remove(struct class_device *, struct class_interface *); | 104 | static void sg_remove(struct class_device *, struct class_interface *); |
106 | 105 | ||
107 | static DEFINE_RWLOCK(sg_dev_arr_lock); /* Also used to lock | 106 | static DEFINE_IDR(sg_index_idr); |
107 | static DEFINE_RWLOCK(sg_index_lock); /* Also used to lock | ||
108 | file descriptor list for device */ | 108 | file descriptor list for device */ |
109 | 109 | ||
110 | static struct class_interface sg_interface = { | 110 | static struct class_interface sg_interface = { |
@@ -114,7 +114,7 @@ static struct class_interface sg_interface = { | |||
114 | 114 | ||
115 | typedef struct sg_scatter_hold { /* holding area for scsi scatter gather info */ | 115 | typedef struct sg_scatter_hold { /* holding area for scsi scatter gather info */ |
116 | unsigned short k_use_sg; /* Count of kernel scatter-gather pieces */ | 116 | unsigned short k_use_sg; /* Count of kernel scatter-gather pieces */ |
117 | unsigned short sglist_len; /* size of malloc'd scatter-gather list ++ */ | 117 | unsigned sglist_len; /* size of malloc'd scatter-gather list ++ */ |
118 | unsigned bufflen; /* Size of (aggregate) data buffer */ | 118 | unsigned bufflen; /* Size of (aggregate) data buffer */ |
119 | unsigned b_malloc_len; /* actual len malloc'ed in buffer */ | 119 | unsigned b_malloc_len; /* actual len malloc'ed in buffer */ |
120 | struct scatterlist *buffer;/* scatter list */ | 120 | struct scatterlist *buffer;/* scatter list */ |
@@ -162,6 +162,7 @@ typedef struct sg_device { /* holds the state of each scsi generic device */ | |||
162 | struct scsi_device *device; | 162 | struct scsi_device *device; |
163 | wait_queue_head_t o_excl_wait; /* queue open() when O_EXCL in use */ | 163 | wait_queue_head_t o_excl_wait; /* queue open() when O_EXCL in use */ |
164 | int sg_tablesize; /* adapter's max scatter-gather table size */ | 164 | int sg_tablesize; /* adapter's max scatter-gather table size */ |
165 | u32 index; /* device index number */ | ||
165 | Sg_fd *headfp; /* first open fd belonging to this device */ | 166 | Sg_fd *headfp; /* first open fd belonging to this device */ |
166 | volatile char detached; /* 0->attached, 1->detached pending removal */ | 167 | volatile char detached; /* 0->attached, 1->detached pending removal */ |
167 | volatile char exclude; /* opened for exclusive access */ | 168 | volatile char exclude; /* opened for exclusive access */ |
@@ -209,10 +210,6 @@ static Sg_device *sg_get_dev(int dev); | |||
209 | static int sg_last_dev(void); | 210 | static int sg_last_dev(void); |
210 | #endif | 211 | #endif |
211 | 212 | ||
212 | static Sg_device **sg_dev_arr = NULL; | ||
213 | static int sg_dev_max; | ||
214 | static int sg_nr_dev; | ||
215 | |||
216 | #define SZ_SG_HEADER sizeof(struct sg_header) | 213 | #define SZ_SG_HEADER sizeof(struct sg_header) |
217 | #define SZ_SG_IO_HDR sizeof(sg_io_hdr_t) | 214 | #define SZ_SG_IO_HDR sizeof(sg_io_hdr_t) |
218 | #define SZ_SG_IOVEC sizeof(sg_iovec_t) | 215 | #define SZ_SG_IOVEC sizeof(sg_iovec_t) |
@@ -1331,40 +1328,35 @@ static struct class *sg_sysfs_class; | |||
1331 | 1328 | ||
1332 | static int sg_sysfs_valid = 0; | 1329 | static int sg_sysfs_valid = 0; |
1333 | 1330 | ||
1334 | static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) | 1331 | static Sg_device *sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) |
1335 | { | 1332 | { |
1336 | struct request_queue *q = scsidp->request_queue; | 1333 | struct request_queue *q = scsidp->request_queue; |
1337 | Sg_device *sdp; | 1334 | Sg_device *sdp; |
1338 | unsigned long iflags; | 1335 | unsigned long iflags; |
1339 | void *old_sg_dev_arr = NULL; | 1336 | int error; |
1340 | int k, error; | 1337 | u32 k; |
1341 | 1338 | ||
1342 | sdp = kzalloc(sizeof(Sg_device), GFP_KERNEL); | 1339 | sdp = kzalloc(sizeof(Sg_device), GFP_KERNEL); |
1343 | if (!sdp) { | 1340 | if (!sdp) { |
1344 | printk(KERN_WARNING "kmalloc Sg_device failure\n"); | 1341 | printk(KERN_WARNING "kmalloc Sg_device failure\n"); |
1345 | return -ENOMEM; | 1342 | return ERR_PTR(-ENOMEM); |
1343 | } | ||
1344 | error = -ENOMEM; | ||
1345 | if (!idr_pre_get(&sg_index_idr, GFP_KERNEL)) { | ||
1346 | printk(KERN_WARNING "idr expansion Sg_device failure\n"); | ||
1347 | goto out; | ||
1346 | } | 1348 | } |
1347 | 1349 | ||
1348 | write_lock_irqsave(&sg_dev_arr_lock, iflags); | 1350 | write_lock_irqsave(&sg_index_lock, iflags); |
1349 | if (unlikely(sg_nr_dev >= sg_dev_max)) { /* try to resize */ | 1351 | error = idr_get_new(&sg_index_idr, sdp, &k); |
1350 | Sg_device **tmp_da; | 1352 | write_unlock_irqrestore(&sg_index_lock, iflags); |
1351 | int tmp_dev_max = sg_nr_dev + SG_DEV_ARR_LUMP; | ||
1352 | write_unlock_irqrestore(&sg_dev_arr_lock, iflags); | ||
1353 | |||
1354 | tmp_da = kzalloc(tmp_dev_max * sizeof(Sg_device *), GFP_KERNEL); | ||
1355 | if (unlikely(!tmp_da)) | ||
1356 | goto expand_failed; | ||
1357 | 1353 | ||
1358 | write_lock_irqsave(&sg_dev_arr_lock, iflags); | 1354 | if (error) { |
1359 | memcpy(tmp_da, sg_dev_arr, sg_dev_max * sizeof(Sg_device *)); | 1355 | printk(KERN_WARNING "idr allocation Sg_device failure: %d\n", |
1360 | old_sg_dev_arr = sg_dev_arr; | 1356 | error); |
1361 | sg_dev_arr = tmp_da; | 1357 | goto out; |
1362 | sg_dev_max = tmp_dev_max; | ||
1363 | } | 1358 | } |
1364 | 1359 | ||
1365 | for (k = 0; k < sg_dev_max; k++) | ||
1366 | if (!sg_dev_arr[k]) | ||
1367 | break; | ||
1368 | if (unlikely(k >= SG_MAX_DEVS)) | 1360 | if (unlikely(k >= SG_MAX_DEVS)) |
1369 | goto overflow; | 1361 | goto overflow; |
1370 | 1362 | ||
@@ -1375,25 +1367,17 @@ static int sg_alloc(struct gendisk *disk, struct scsi_device *scsidp) | |||
1375 | sdp->device = scsidp; | 1367 | sdp->device = scsidp; |
1376 | init_waitqueue_head(&sdp->o_excl_wait); | 1368 | init_waitqueue_head(&sdp->o_excl_wait); |
1377 | sdp->sg_tablesize = min(q->max_hw_segments, q->max_phys_segments); | 1369 | sdp->sg_tablesize = min(q->max_hw_segments, q->max_phys_segments); |
1370 | sdp->index = k; | ||
1378 | 1371 | ||
1379 | sg_nr_dev++; | 1372 | error = 0; |
1380 | sg_dev_arr[k] = sdp; | ||
1381 | write_unlock_irqrestore(&sg_dev_arr_lock, iflags); | ||
1382 | error = k; | ||
1383 | |||
1384 | out: | 1373 | out: |
1385 | if (error < 0) | 1374 | if (error) { |
1386 | kfree(sdp); | 1375 | kfree(sdp); |
1387 | kfree(old_sg_dev_arr); | 1376 | return ERR_PTR(error); |
1388 | return error; | 1377 | } |
1389 | 1378 | return sdp; | |
1390 | expand_failed: | ||
1391 | printk(KERN_WARNING "sg_alloc: device array cannot be resized\n"); | ||
1392 | error = -ENOMEM; | ||
1393 | goto out; | ||
1394 | 1379 | ||
1395 | overflow: | 1380 | overflow: |
1396 | write_unlock_irqrestore(&sg_dev_arr_lock, iflags); | ||
1397 | sdev_printk(KERN_WARNING, scsidp, | 1381 | sdev_printk(KERN_WARNING, scsidp, |
1398 | "Unable to attach sg device type=%d, minor " | 1382 | "Unable to attach sg device type=%d, minor " |
1399 | "number exceeds %d\n", scsidp->type, SG_MAX_DEVS - 1); | 1383 | "number exceeds %d\n", scsidp->type, SG_MAX_DEVS - 1); |
@@ -1408,7 +1392,7 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) | |||
1408 | struct gendisk *disk; | 1392 | struct gendisk *disk; |
1409 | Sg_device *sdp = NULL; | 1393 | Sg_device *sdp = NULL; |
1410 | struct cdev * cdev = NULL; | 1394 | struct cdev * cdev = NULL; |
1411 | int error, k; | 1395 | int error; |
1412 | unsigned long iflags; | 1396 | unsigned long iflags; |
1413 | 1397 | ||
1414 | disk = alloc_disk(1); | 1398 | disk = alloc_disk(1); |
@@ -1427,15 +1411,15 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) | |||
1427 | cdev->owner = THIS_MODULE; | 1411 | cdev->owner = THIS_MODULE; |
1428 | cdev->ops = &sg_fops; | 1412 | cdev->ops = &sg_fops; |
1429 | 1413 | ||
1430 | error = sg_alloc(disk, scsidp); | 1414 | sdp = sg_alloc(disk, scsidp); |
1431 | if (error < 0) { | 1415 | if (IS_ERR(sdp)) { |
1432 | printk(KERN_WARNING "sg_alloc failed\n"); | 1416 | printk(KERN_WARNING "sg_alloc failed\n"); |
1417 | error = PTR_ERR(sdp); | ||
1433 | goto out; | 1418 | goto out; |
1434 | } | 1419 | } |
1435 | k = error; | ||
1436 | sdp = sg_dev_arr[k]; | ||
1437 | 1420 | ||
1438 | error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, k), 1); | 1421 | class_set_devdata(cl_dev, sdp); |
1422 | error = cdev_add(cdev, MKDEV(SCSI_GENERIC_MAJOR, sdp->index), 1); | ||
1439 | if (error) | 1423 | if (error) |
1440 | goto cdev_add_err; | 1424 | goto cdev_add_err; |
1441 | 1425 | ||
@@ -1444,8 +1428,8 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) | |||
1444 | struct class_device * sg_class_member; | 1428 | struct class_device * sg_class_member; |
1445 | 1429 | ||
1446 | sg_class_member = class_device_create(sg_sysfs_class, NULL, | 1430 | sg_class_member = class_device_create(sg_sysfs_class, NULL, |
1447 | MKDEV(SCSI_GENERIC_MAJOR, k), | 1431 | MKDEV(SCSI_GENERIC_MAJOR, sdp->index), |
1448 | cl_dev->dev, "%s", | 1432 | cl_dev->dev, "%s", |
1449 | disk->disk_name); | 1433 | disk->disk_name); |
1450 | if (IS_ERR(sg_class_member)) | 1434 | if (IS_ERR(sg_class_member)) |
1451 | printk(KERN_WARNING "sg_add: " | 1435 | printk(KERN_WARNING "sg_add: " |
@@ -1455,21 +1439,21 @@ sg_add(struct class_device *cl_dev, struct class_interface *cl_intf) | |||
1455 | &sg_class_member->kobj, "generic"); | 1439 | &sg_class_member->kobj, "generic"); |
1456 | if (error) | 1440 | if (error) |
1457 | printk(KERN_ERR "sg_add: unable to make symlink " | 1441 | printk(KERN_ERR "sg_add: unable to make symlink " |
1458 | "'generic' back to sg%d\n", k); | 1442 | "'generic' back to sg%d\n", sdp->index); |
1459 | } else | 1443 | } else |
1460 | printk(KERN_WARNING "sg_add: sg_sys INvalid\n"); | 1444 | printk(KERN_WARNING "sg_add: sg_sys Invalid\n"); |
1461 | 1445 | ||
1462 | sdev_printk(KERN_NOTICE, scsidp, | 1446 | sdev_printk(KERN_NOTICE, scsidp, |
1463 | "Attached scsi generic sg%d type %d\n", k,scsidp->type); | 1447 | "Attached scsi generic sg%d type %d\n", sdp->index, |
1448 | scsidp->type); | ||
1464 | 1449 | ||
1465 | return 0; | 1450 | return 0; |
1466 | 1451 | ||
1467 | cdev_add_err: | 1452 | cdev_add_err: |
1468 | write_lock_irqsave(&sg_dev_arr_lock, iflags); | 1453 | write_lock_irqsave(&sg_index_lock, iflags); |
1469 | kfree(sg_dev_arr[k]); | 1454 | idr_remove(&sg_index_idr, sdp->index); |
1470 | sg_dev_arr[k] = NULL; | 1455 | write_unlock_irqrestore(&sg_index_lock, iflags); |
1471 | sg_nr_dev--; | 1456 | kfree(sdp); |
1472 | write_unlock_irqrestore(&sg_dev_arr_lock, iflags); | ||
1473 | 1457 | ||
1474 | out: | 1458 | out: |
1475 | put_disk(disk); | 1459 | put_disk(disk); |
@@ -1482,64 +1466,56 @@ static void | |||
1482 | sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf) | 1466 | sg_remove(struct class_device *cl_dev, struct class_interface *cl_intf) |
1483 | { | 1467 | { |
1484 | struct scsi_device *scsidp = to_scsi_device(cl_dev->dev); | 1468 | struct scsi_device *scsidp = to_scsi_device(cl_dev->dev); |
1485 | Sg_device *sdp = NULL; | 1469 | Sg_device *sdp = class_get_devdata(cl_dev); |
1486 | unsigned long iflags; | 1470 | unsigned long iflags; |
1487 | Sg_fd *sfp; | 1471 | Sg_fd *sfp; |
1488 | Sg_fd *tsfp; | 1472 | Sg_fd *tsfp; |
1489 | Sg_request *srp; | 1473 | Sg_request *srp; |
1490 | Sg_request *tsrp; | 1474 | Sg_request *tsrp; |
1491 | int k, delay; | 1475 | int delay; |
1492 | 1476 | ||
1493 | if (NULL == sg_dev_arr) | 1477 | if (!sdp) |
1494 | return; | 1478 | return; |
1479 | |||
1495 | delay = 0; | 1480 | delay = 0; |
1496 | write_lock_irqsave(&sg_dev_arr_lock, iflags); | 1481 | write_lock_irqsave(&sg_index_lock, iflags); |
1497 | for (k = 0; k < sg_dev_max; k++) { | 1482 | if (sdp->headfp) { |
1498 | sdp = sg_dev_arr[k]; | 1483 | sdp->detached = 1; |
1499 | if ((NULL == sdp) || (sdp->device != scsidp)) | 1484 | for (sfp = sdp->headfp; sfp; sfp = tsfp) { |
1500 | continue; /* dirty but lowers nesting */ | 1485 | tsfp = sfp->nextfp; |
1501 | if (sdp->headfp) { | 1486 | for (srp = sfp->headrp; srp; srp = tsrp) { |
1502 | sdp->detached = 1; | 1487 | tsrp = srp->nextrp; |
1503 | for (sfp = sdp->headfp; sfp; sfp = tsfp) { | 1488 | if (sfp->closed || (0 == sg_srp_done(srp, sfp))) |
1504 | tsfp = sfp->nextfp; | 1489 | sg_finish_rem_req(srp); |
1505 | for (srp = sfp->headrp; srp; srp = tsrp) { | ||
1506 | tsrp = srp->nextrp; | ||
1507 | if (sfp->closed || (0 == sg_srp_done(srp, sfp))) | ||
1508 | sg_finish_rem_req(srp); | ||
1509 | } | ||
1510 | if (sfp->closed) { | ||
1511 | scsi_device_put(sdp->device); | ||
1512 | __sg_remove_sfp(sdp, sfp); | ||
1513 | } else { | ||
1514 | delay = 1; | ||
1515 | wake_up_interruptible(&sfp->read_wait); | ||
1516 | kill_fasync(&sfp->async_qp, SIGPOLL, | ||
1517 | POLL_HUP); | ||
1518 | } | ||
1519 | } | 1490 | } |
1520 | SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d, dirty\n", k)); | 1491 | if (sfp->closed) { |
1521 | if (NULL == sdp->headfp) { | 1492 | scsi_device_put(sdp->device); |
1522 | sg_dev_arr[k] = NULL; | 1493 | __sg_remove_sfp(sdp, sfp); |
1494 | } else { | ||
1495 | delay = 1; | ||
1496 | wake_up_interruptible(&sfp->read_wait); | ||
1497 | kill_fasync(&sfp->async_qp, SIGPOLL, | ||
1498 | POLL_HUP); | ||
1523 | } | 1499 | } |
1524 | } else { /* nothing active, simple case */ | ||
1525 | SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d\n", k)); | ||
1526 | sg_dev_arr[k] = NULL; | ||
1527 | } | 1500 | } |
1528 | sg_nr_dev--; | 1501 | SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d, dirty\n", sdp->index)); |
1529 | break; | 1502 | if (NULL == sdp->headfp) { |
1530 | } | 1503 | idr_remove(&sg_index_idr, sdp->index); |
1531 | write_unlock_irqrestore(&sg_dev_arr_lock, iflags); | 1504 | } |
1532 | 1505 | } else { /* nothing active, simple case */ | |
1533 | if (sdp) { | 1506 | SCSI_LOG_TIMEOUT(3, printk("sg_remove: dev=%d\n", sdp->index)); |
1534 | sysfs_remove_link(&scsidp->sdev_gendev.kobj, "generic"); | 1507 | idr_remove(&sg_index_idr, sdp->index); |
1535 | class_device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, k)); | 1508 | } |
1536 | cdev_del(sdp->cdev); | 1509 | write_unlock_irqrestore(&sg_index_lock, iflags); |
1537 | sdp->cdev = NULL; | 1510 | |
1538 | put_disk(sdp->disk); | 1511 | sysfs_remove_link(&scsidp->sdev_gendev.kobj, "generic"); |
1539 | sdp->disk = NULL; | 1512 | class_device_destroy(sg_sysfs_class, MKDEV(SCSI_GENERIC_MAJOR, sdp->index)); |
1540 | if (NULL == sdp->headfp) | 1513 | cdev_del(sdp->cdev); |
1541 | kfree((char *) sdp); | 1514 | sdp->cdev = NULL; |
1542 | } | 1515 | put_disk(sdp->disk); |
1516 | sdp->disk = NULL; | ||
1517 | if (NULL == sdp->headfp) | ||
1518 | kfree(sdp); | ||
1543 | 1519 | ||
1544 | if (delay) | 1520 | if (delay) |
1545 | msleep(10); /* dirty detach so delay device destruction */ | 1521 | msleep(10); /* dirty detach so delay device destruction */ |
@@ -1609,9 +1585,7 @@ exit_sg(void) | |||
1609 | sg_sysfs_valid = 0; | 1585 | sg_sysfs_valid = 0; |
1610 | unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0), | 1586 | unregister_chrdev_region(MKDEV(SCSI_GENERIC_MAJOR, 0), |
1611 | SG_MAX_DEVS); | 1587 | SG_MAX_DEVS); |
1612 | kfree((char *)sg_dev_arr); | 1588 | idr_destroy(&sg_index_idr); |
1613 | sg_dev_arr = NULL; | ||
1614 | sg_dev_max = 0; | ||
1615 | } | 1589 | } |
1616 | 1590 | ||
1617 | static int | 1591 | static int |
@@ -2331,10 +2305,10 @@ sg_get_nth_sfp(Sg_device * sdp, int nth) | |||
2331 | unsigned long iflags; | 2305 | unsigned long iflags; |
2332 | int k; | 2306 | int k; |
2333 | 2307 | ||
2334 | read_lock_irqsave(&sg_dev_arr_lock, iflags); | 2308 | read_lock_irqsave(&sg_index_lock, iflags); |
2335 | for (k = 0, resp = sdp->headfp; resp && (k < nth); | 2309 | for (k = 0, resp = sdp->headfp; resp && (k < nth); |
2336 | ++k, resp = resp->nextfp) ; | 2310 | ++k, resp = resp->nextfp) ; |
2337 | read_unlock_irqrestore(&sg_dev_arr_lock, iflags); | 2311 | read_unlock_irqrestore(&sg_index_lock, iflags); |
2338 | return resp; | 2312 | return resp; |
2339 | } | 2313 | } |
2340 | #endif | 2314 | #endif |
@@ -2361,7 +2335,7 @@ sg_add_sfp(Sg_device * sdp, int dev) | |||
2361 | sfp->cmd_q = SG_DEF_COMMAND_Q; | 2335 | sfp->cmd_q = SG_DEF_COMMAND_Q; |
2362 | sfp->keep_orphan = SG_DEF_KEEP_ORPHAN; | 2336 | sfp->keep_orphan = SG_DEF_KEEP_ORPHAN; |
2363 | sfp->parentdp = sdp; | 2337 | sfp->parentdp = sdp; |
2364 | write_lock_irqsave(&sg_dev_arr_lock, iflags); | 2338 | write_lock_irqsave(&sg_index_lock, iflags); |
2365 | if (!sdp->headfp) | 2339 | if (!sdp->headfp) |
2366 | sdp->headfp = sfp; | 2340 | sdp->headfp = sfp; |
2367 | else { /* add to tail of existing list */ | 2341 | else { /* add to tail of existing list */ |
@@ -2370,7 +2344,7 @@ sg_add_sfp(Sg_device * sdp, int dev) | |||
2370 | pfp = pfp->nextfp; | 2344 | pfp = pfp->nextfp; |
2371 | pfp->nextfp = sfp; | 2345 | pfp->nextfp = sfp; |
2372 | } | 2346 | } |
2373 | write_unlock_irqrestore(&sg_dev_arr_lock, iflags); | 2347 | write_unlock_irqrestore(&sg_index_lock, iflags); |
2374 | SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: sfp=0x%p\n", sfp)); | 2348 | SCSI_LOG_TIMEOUT(3, printk("sg_add_sfp: sfp=0x%p\n", sfp)); |
2375 | if (unlikely(sg_big_buff != def_reserved_size)) | 2349 | if (unlikely(sg_big_buff != def_reserved_size)) |
2376 | sg_big_buff = def_reserved_size; | 2350 | sg_big_buff = def_reserved_size; |
@@ -2431,22 +2405,14 @@ sg_remove_sfp(Sg_device * sdp, Sg_fd * sfp) | |||
2431 | if (0 == dirty) { | 2405 | if (0 == dirty) { |
2432 | unsigned long iflags; | 2406 | unsigned long iflags; |
2433 | 2407 | ||
2434 | write_lock_irqsave(&sg_dev_arr_lock, iflags); | 2408 | write_lock_irqsave(&sg_index_lock, iflags); |
2435 | __sg_remove_sfp(sdp, sfp); | 2409 | __sg_remove_sfp(sdp, sfp); |
2436 | if (sdp->detached && (NULL == sdp->headfp)) { | 2410 | if (sdp->detached && (NULL == sdp->headfp)) { |
2437 | int k, maxd; | 2411 | idr_remove(&sg_index_idr, sdp->index); |
2438 | 2412 | kfree(sdp); | |
2439 | maxd = sg_dev_max; | ||
2440 | for (k = 0; k < maxd; ++k) { | ||
2441 | if (sdp == sg_dev_arr[k]) | ||
2442 | break; | ||
2443 | } | ||
2444 | if (k < maxd) | ||
2445 | sg_dev_arr[k] = NULL; | ||
2446 | kfree((char *) sdp); | ||
2447 | res = 1; | 2413 | res = 1; |
2448 | } | 2414 | } |
2449 | write_unlock_irqrestore(&sg_dev_arr_lock, iflags); | 2415 | write_unlock_irqrestore(&sg_index_lock, iflags); |
2450 | } else { | 2416 | } else { |
2451 | /* MOD_INC's to inhibit unloading sg and associated adapter driver */ | 2417 | /* MOD_INC's to inhibit unloading sg and associated adapter driver */ |
2452 | /* only bump the access_count if we actually succeeded in | 2418 | /* only bump the access_count if we actually succeeded in |
@@ -2546,16 +2512,25 @@ sg_allow_access(unsigned char opcode, char dev_type) | |||
2546 | 2512 | ||
2547 | #ifdef CONFIG_SCSI_PROC_FS | 2513 | #ifdef CONFIG_SCSI_PROC_FS |
2548 | static int | 2514 | static int |
2515 | sg_idr_max_id(int id, void *p, void *data) | ||
2516 | { | ||
2517 | int *k = data; | ||
2518 | |||
2519 | if (*k < id) | ||
2520 | *k = id; | ||
2521 | |||
2522 | return 0; | ||
2523 | } | ||
2524 | |||
2525 | static int | ||
2549 | sg_last_dev(void) | 2526 | sg_last_dev(void) |
2550 | { | 2527 | { |
2551 | int k; | 2528 | int k = 0; |
2552 | unsigned long iflags; | 2529 | unsigned long iflags; |
2553 | 2530 | ||
2554 | read_lock_irqsave(&sg_dev_arr_lock, iflags); | 2531 | read_lock_irqsave(&sg_index_lock, iflags); |
2555 | for (k = sg_dev_max - 1; k >= 0; --k) | 2532 | idr_for_each(&sg_index_idr, sg_idr_max_id, &k); |
2556 | if (sg_dev_arr[k] && sg_dev_arr[k]->device) | 2533 | read_unlock_irqrestore(&sg_index_lock, iflags); |
2557 | break; | ||
2558 | read_unlock_irqrestore(&sg_dev_arr_lock, iflags); | ||
2559 | return k + 1; /* origin 1 */ | 2534 | return k + 1; /* origin 1 */ |
2560 | } | 2535 | } |
2561 | #endif | 2536 | #endif |
@@ -2563,15 +2538,13 @@ sg_last_dev(void) | |||
2563 | static Sg_device * | 2538 | static Sg_device * |
2564 | sg_get_dev(int dev) | 2539 | sg_get_dev(int dev) |
2565 | { | 2540 | { |
2566 | Sg_device *sdp = NULL; | 2541 | Sg_device *sdp; |
2567 | unsigned long iflags; | 2542 | unsigned long iflags; |
2568 | 2543 | ||
2569 | if (sg_dev_arr && (dev >= 0)) { | 2544 | read_lock_irqsave(&sg_index_lock, iflags); |
2570 | read_lock_irqsave(&sg_dev_arr_lock, iflags); | 2545 | sdp = idr_find(&sg_index_idr, dev); |
2571 | if (dev < sg_dev_max) | 2546 | read_unlock_irqrestore(&sg_index_lock, iflags); |
2572 | sdp = sg_dev_arr[dev]; | 2547 | |
2573 | read_unlock_irqrestore(&sg_dev_arr_lock, iflags); | ||
2574 | } | ||
2575 | return sdp; | 2548 | return sdp; |
2576 | } | 2549 | } |
2577 | 2550 | ||
@@ -2805,8 +2778,6 @@ static void * dev_seq_start(struct seq_file *s, loff_t *pos) | |||
2805 | if (! it) | 2778 | if (! it) |
2806 | return NULL; | 2779 | return NULL; |
2807 | 2780 | ||
2808 | if (NULL == sg_dev_arr) | ||
2809 | return NULL; | ||
2810 | it->index = *pos; | 2781 | it->index = *pos; |
2811 | it->max = sg_last_dev(); | 2782 | it->max = sg_last_dev(); |
2812 | if (it->index >= it->max) | 2783 | if (it->index >= it->max) |
@@ -2942,8 +2913,8 @@ static int sg_proc_seq_show_debug(struct seq_file *s, void *v) | |||
2942 | Sg_device *sdp; | 2913 | Sg_device *sdp; |
2943 | 2914 | ||
2944 | if (it && (0 == it->index)) { | 2915 | if (it && (0 == it->index)) { |
2945 | seq_printf(s, "dev_max(currently)=%d max_active_device=%d " | 2916 | seq_printf(s, "max_active_device=%d(origin 1)\n", |
2946 | "(origin 1)\n", sg_dev_max, (int)it->max); | 2917 | (int)it->max); |
2947 | seq_printf(s, " def_reserved_size=%d\n", sg_big_buff); | 2918 | seq_printf(s, " def_reserved_size=%d\n", sg_big_buff); |
2948 | } | 2919 | } |
2949 | sdp = it ? sg_get_dev(it->index) : NULL; | 2920 | sdp = it ? sg_get_dev(it->index) : NULL; |
diff --git a/drivers/scsi/sr.c b/drivers/scsi/sr.c index 902eb11ffe8a..c61999031141 100644 --- a/drivers/scsi/sr.c +++ b/drivers/scsi/sr.c | |||
@@ -78,7 +78,7 @@ MODULE_ALIAS_SCSI_DEVICE(TYPE_WORM); | |||
78 | 78 | ||
79 | static int sr_probe(struct device *); | 79 | static int sr_probe(struct device *); |
80 | static int sr_remove(struct device *); | 80 | static int sr_remove(struct device *); |
81 | static int sr_init_command(struct scsi_cmnd *); | 81 | static int sr_done(struct scsi_cmnd *); |
82 | 82 | ||
83 | static struct scsi_driver sr_template = { | 83 | static struct scsi_driver sr_template = { |
84 | .owner = THIS_MODULE, | 84 | .owner = THIS_MODULE, |
@@ -87,7 +87,7 @@ static struct scsi_driver sr_template = { | |||
87 | .probe = sr_probe, | 87 | .probe = sr_probe, |
88 | .remove = sr_remove, | 88 | .remove = sr_remove, |
89 | }, | 89 | }, |
90 | .init_command = sr_init_command, | 90 | .done = sr_done, |
91 | }; | 91 | }; |
92 | 92 | ||
93 | static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG]; | 93 | static unsigned long sr_index_bits[SR_DISKS / BITS_PER_LONG]; |
@@ -210,12 +210,12 @@ static int sr_media_change(struct cdrom_device_info *cdi, int slot) | |||
210 | } | 210 | } |
211 | 211 | ||
212 | /* | 212 | /* |
213 | * rw_intr is the interrupt routine for the device driver. | 213 | * sr_done is the interrupt routine for the device driver. |
214 | * | 214 | * |
215 | * It will be notified on the end of a SCSI read / write, and will take on | 215 | * It will be notified on the end of a SCSI read / write, and will take one |
216 | * of several actions based on success or failure. | 216 | * of several actions based on success or failure. |
217 | */ | 217 | */ |
218 | static void rw_intr(struct scsi_cmnd * SCpnt) | 218 | static int sr_done(struct scsi_cmnd *SCpnt) |
219 | { | 219 | { |
220 | int result = SCpnt->result; | 220 | int result = SCpnt->result; |
221 | int this_count = SCpnt->request_bufflen; | 221 | int this_count = SCpnt->request_bufflen; |
@@ -288,27 +288,42 @@ static void rw_intr(struct scsi_cmnd * SCpnt) | |||
288 | } | 288 | } |
289 | } | 289 | } |
290 | 290 | ||
291 | /* | 291 | return good_bytes; |
292 | * This calls the generic completion function, now that we know | ||
293 | * how many actual sectors finished, and how many sectors we need | ||
294 | * to say have failed. | ||
295 | */ | ||
296 | scsi_io_completion(SCpnt, good_bytes); | ||
297 | } | 292 | } |
298 | 293 | ||
299 | static int sr_init_command(struct scsi_cmnd * SCpnt) | 294 | static int sr_prep_fn(struct request_queue *q, struct request *rq) |
300 | { | 295 | { |
301 | int block=0, this_count, s_size, timeout = SR_TIMEOUT; | 296 | int block=0, this_count, s_size, timeout = SR_TIMEOUT; |
302 | struct scsi_cd *cd = scsi_cd(SCpnt->request->rq_disk); | 297 | struct scsi_cd *cd; |
298 | struct scsi_cmnd *SCpnt; | ||
299 | struct scsi_device *sdp = q->queuedata; | ||
300 | int ret; | ||
301 | |||
302 | if (rq->cmd_type == REQ_TYPE_BLOCK_PC) { | ||
303 | ret = scsi_setup_blk_pc_cmnd(sdp, rq); | ||
304 | goto out; | ||
305 | } else if (rq->cmd_type != REQ_TYPE_FS) { | ||
306 | ret = BLKPREP_KILL; | ||
307 | goto out; | ||
308 | } | ||
309 | ret = scsi_setup_fs_cmnd(sdp, rq); | ||
310 | if (ret != BLKPREP_OK) | ||
311 | goto out; | ||
312 | SCpnt = rq->special; | ||
313 | cd = scsi_cd(rq->rq_disk); | ||
314 | |||
315 | /* from here on until we're complete, any goto out | ||
316 | * is used for a killable error condition */ | ||
317 | ret = BLKPREP_KILL; | ||
303 | 318 | ||
304 | SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %s, block = %d\n", | 319 | SCSI_LOG_HLQUEUE(1, printk("Doing sr request, dev = %s, block = %d\n", |
305 | cd->disk->disk_name, block)); | 320 | cd->disk->disk_name, block)); |
306 | 321 | ||
307 | if (!cd->device || !scsi_device_online(cd->device)) { | 322 | if (!cd->device || !scsi_device_online(cd->device)) { |
308 | SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", | 323 | SCSI_LOG_HLQUEUE(2, printk("Finishing %ld sectors\n", |
309 | SCpnt->request->nr_sectors)); | 324 | rq->nr_sectors)); |
310 | SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt)); | 325 | SCSI_LOG_HLQUEUE(2, printk("Retry with 0x%p\n", SCpnt)); |
311 | return 0; | 326 | goto out; |
312 | } | 327 | } |
313 | 328 | ||
314 | if (cd->device->changed) { | 329 | if (cd->device->changed) { |
@@ -316,7 +331,7 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
316 | * quietly refuse to do anything to a changed disc until the | 331 | * quietly refuse to do anything to a changed disc until the |
317 | * changed bit has been reset | 332 | * changed bit has been reset |
318 | */ | 333 | */ |
319 | return 0; | 334 | goto out; |
320 | } | 335 | } |
321 | 336 | ||
322 | /* | 337 | /* |
@@ -333,21 +348,21 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
333 | 348 | ||
334 | if (s_size != 512 && s_size != 1024 && s_size != 2048) { | 349 | if (s_size != 512 && s_size != 1024 && s_size != 2048) { |
335 | scmd_printk(KERN_ERR, SCpnt, "bad sector size %d\n", s_size); | 350 | scmd_printk(KERN_ERR, SCpnt, "bad sector size %d\n", s_size); |
336 | return 0; | 351 | goto out; |
337 | } | 352 | } |
338 | 353 | ||
339 | if (rq_data_dir(SCpnt->request) == WRITE) { | 354 | if (rq_data_dir(rq) == WRITE) { |
340 | if (!cd->device->writeable) | 355 | if (!cd->device->writeable) |
341 | return 0; | 356 | goto out; |
342 | SCpnt->cmnd[0] = WRITE_10; | 357 | SCpnt->cmnd[0] = WRITE_10; |
343 | SCpnt->sc_data_direction = DMA_TO_DEVICE; | 358 | SCpnt->sc_data_direction = DMA_TO_DEVICE; |
344 | cd->cdi.media_written = 1; | 359 | cd->cdi.media_written = 1; |
345 | } else if (rq_data_dir(SCpnt->request) == READ) { | 360 | } else if (rq_data_dir(rq) == READ) { |
346 | SCpnt->cmnd[0] = READ_10; | 361 | SCpnt->cmnd[0] = READ_10; |
347 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; | 362 | SCpnt->sc_data_direction = DMA_FROM_DEVICE; |
348 | } else { | 363 | } else { |
349 | blk_dump_rq_flags(SCpnt->request, "Unknown sr command"); | 364 | blk_dump_rq_flags(rq, "Unknown sr command"); |
350 | return 0; | 365 | goto out; |
351 | } | 366 | } |
352 | 367 | ||
353 | { | 368 | { |
@@ -368,10 +383,10 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
368 | /* | 383 | /* |
369 | * request doesn't start on hw block boundary, add scatter pads | 384 | * request doesn't start on hw block boundary, add scatter pads |
370 | */ | 385 | */ |
371 | if (((unsigned int)SCpnt->request->sector % (s_size >> 9)) || | 386 | if (((unsigned int)rq->sector % (s_size >> 9)) || |
372 | (SCpnt->request_bufflen % s_size)) { | 387 | (SCpnt->request_bufflen % s_size)) { |
373 | scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n"); | 388 | scmd_printk(KERN_NOTICE, SCpnt, "unaligned transfer\n"); |
374 | return 0; | 389 | goto out; |
375 | } | 390 | } |
376 | 391 | ||
377 | this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9); | 392 | this_count = (SCpnt->request_bufflen >> 9) / (s_size >> 9); |
@@ -379,12 +394,12 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
379 | 394 | ||
380 | SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", | 395 | SCSI_LOG_HLQUEUE(2, printk("%s : %s %d/%ld 512 byte blocks.\n", |
381 | cd->cdi.name, | 396 | cd->cdi.name, |
382 | (rq_data_dir(SCpnt->request) == WRITE) ? | 397 | (rq_data_dir(rq) == WRITE) ? |
383 | "writing" : "reading", | 398 | "writing" : "reading", |
384 | this_count, SCpnt->request->nr_sectors)); | 399 | this_count, rq->nr_sectors)); |
385 | 400 | ||
386 | SCpnt->cmnd[1] = 0; | 401 | SCpnt->cmnd[1] = 0; |
387 | block = (unsigned int)SCpnt->request->sector / (s_size >> 9); | 402 | block = (unsigned int)rq->sector / (s_size >> 9); |
388 | 403 | ||
389 | if (this_count > 0xffff) { | 404 | if (this_count > 0xffff) { |
390 | this_count = 0xffff; | 405 | this_count = 0xffff; |
@@ -410,16 +425,12 @@ static int sr_init_command(struct scsi_cmnd * SCpnt) | |||
410 | SCpnt->timeout_per_command = timeout; | 425 | SCpnt->timeout_per_command = timeout; |
411 | 426 | ||
412 | /* | 427 | /* |
413 | * This is the completion routine we use. This is matched in terms | ||
414 | * of capability to this function. | ||
415 | */ | ||
416 | SCpnt->done = rw_intr; | ||
417 | |||
418 | /* | ||
419 | * This indicates that the command is ready from our end to be | 428 | * This indicates that the command is ready from our end to be |
420 | * queued. | 429 | * queued. |
421 | */ | 430 | */ |
422 | return 1; | 431 | ret = BLKPREP_OK; |
432 | out: | ||
433 | return scsi_prep_return(q, rq, ret); | ||
423 | } | 434 | } |
424 | 435 | ||
425 | static int sr_block_open(struct inode *inode, struct file *file) | 436 | static int sr_block_open(struct inode *inode, struct file *file) |
@@ -590,6 +601,7 @@ static int sr_probe(struct device *dev) | |||
590 | 601 | ||
591 | /* FIXME: need to handle a get_capabilities failure properly ?? */ | 602 | /* FIXME: need to handle a get_capabilities failure properly ?? */ |
592 | get_capabilities(cd); | 603 | get_capabilities(cd); |
604 | blk_queue_prep_rq(sdev->request_queue, sr_prep_fn); | ||
593 | sr_vendor_init(cd); | 605 | sr_vendor_init(cd); |
594 | 606 | ||
595 | disk->driverfs_dev = &sdev->sdev_gendev; | 607 | disk->driverfs_dev = &sdev->sdev_gendev; |
diff --git a/drivers/scsi/sun3_NCR5380.c b/drivers/scsi/sun3_NCR5380.c index 98e3fe10c1dc..dc15a22105f7 100644 --- a/drivers/scsi/sun3_NCR5380.c +++ b/drivers/scsi/sun3_NCR5380.c | |||
@@ -2055,7 +2055,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) | |||
2055 | sink = 1; | 2055 | sink = 1; |
2056 | do_abort(instance); | 2056 | do_abort(instance); |
2057 | cmd->result = DID_ERROR << 16; | 2057 | cmd->result = DID_ERROR << 16; |
2058 | cmd->done(cmd); | 2058 | cmd->scsi_done(cmd); |
2059 | return; | 2059 | return; |
2060 | #endif | 2060 | #endif |
2061 | case PHASE_DATAIN: | 2061 | case PHASE_DATAIN: |
@@ -2115,7 +2115,7 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) | |||
2115 | sink = 1; | 2115 | sink = 1; |
2116 | do_abort(instance); | 2116 | do_abort(instance); |
2117 | cmd->result = DID_ERROR << 16; | 2117 | cmd->result = DID_ERROR << 16; |
2118 | cmd->done(cmd); | 2118 | cmd->scsi_done(cmd); |
2119 | /* XXX - need to source or sink data here, as appropriate */ | 2119 | /* XXX - need to source or sink data here, as appropriate */ |
2120 | } else { | 2120 | } else { |
2121 | #ifdef REAL_DMA | 2121 | #ifdef REAL_DMA |
@@ -2254,25 +2254,21 @@ static void NCR5380_information_transfer (struct Scsi_Host *instance) | |||
2254 | cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); | 2254 | cmd->result = (cmd->result & 0x00ffff) | (DID_ERROR << 16); |
2255 | 2255 | ||
2256 | #ifdef AUTOSENSE | 2256 | #ifdef AUTOSENSE |
2257 | if ((cmd->cmnd[0] == REQUEST_SENSE) && | ||
2258 | hostdata->ses.cmd_len) { | ||
2259 | scsi_eh_restore_cmnd(cmd, &hostdata->ses); | ||
2260 | hostdata->ses.cmd_len = 0 ; | ||
2261 | } | ||
2262 | |||
2257 | if ((cmd->cmnd[0] != REQUEST_SENSE) && | 2263 | if ((cmd->cmnd[0] != REQUEST_SENSE) && |
2258 | (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) { | 2264 | (status_byte(cmd->SCp.Status) == CHECK_CONDITION)) { |
2265 | scsi_eh_prep_cmnd(cmd, &hostdata->ses, NULL, 0, ~0); | ||
2259 | ASEN_PRINTK("scsi%d: performing request sense\n", | 2266 | ASEN_PRINTK("scsi%d: performing request sense\n", |
2260 | HOSTNO); | 2267 | HOSTNO); |
2261 | cmd->cmnd[0] = REQUEST_SENSE; | ||
2262 | cmd->cmnd[1] &= 0xe0; | ||
2263 | cmd->cmnd[2] = 0; | ||
2264 | cmd->cmnd[3] = 0; | ||
2265 | cmd->cmnd[4] = sizeof(cmd->sense_buffer); | ||
2266 | cmd->cmnd[5] = 0; | ||
2267 | cmd->cmd_len = COMMAND_SIZE(cmd->cmnd[0]); | ||
2268 | |||
2269 | cmd->use_sg = 0; | ||
2270 | /* this is initialized from initialize_SCp | 2268 | /* this is initialized from initialize_SCp |
2271 | cmd->SCp.buffer = NULL; | 2269 | cmd->SCp.buffer = NULL; |
2272 | cmd->SCp.buffers_residual = 0; | 2270 | cmd->SCp.buffers_residual = 0; |
2273 | */ | 2271 | */ |
2274 | cmd->request_buffer = (char *) cmd->sense_buffer; | ||
2275 | cmd->request_bufflen = sizeof(cmd->sense_buffer); | ||
2276 | 2272 | ||
2277 | local_irq_save(flags); | 2273 | local_irq_save(flags); |
2278 | LIST(cmd,hostdata->issue_queue); | 2274 | LIST(cmd,hostdata->issue_queue); |
diff --git a/drivers/scsi/tmscsim.c b/drivers/scsi/tmscsim.c index 5db1520f8ba9..5c72ca31a47a 100644 --- a/drivers/scsi/tmscsim.c +++ b/drivers/scsi/tmscsim.c | |||
@@ -567,12 +567,12 @@ dc390_StartSCSI( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_sr | |||
567 | pDCB->TagMask |= 1 << tag[1]; | 567 | pDCB->TagMask |= 1 << tag[1]; |
568 | pSRB->TagNumber = tag[1]; | 568 | pSRB->TagNumber = tag[1]; |
569 | DC390_write8(ScsiFifo, tag[1]); | 569 | DC390_write8(ScsiFifo, tag[1]); |
570 | DEBUG1(printk(KERN_INFO "DC390: Select w/DisCn for Cmd %li (SRB %p), block tag %02x\n", scmd->pid, pSRB, tag[1])); | 570 | DEBUG1(printk(KERN_INFO "DC390: Select w/DisCn for Cmd %li (SRB %p), block tag %02x\n", scmd->serial_number, pSRB, tag[1])); |
571 | cmd = SEL_W_ATN3; | 571 | cmd = SEL_W_ATN3; |
572 | } else { | 572 | } else { |
573 | /* No TagQ */ | 573 | /* No TagQ */ |
574 | //no_tag: | 574 | //no_tag: |
575 | DEBUG1(printk(KERN_INFO "DC390: Select w%s/DisCn for Cmd %li (SRB %p), No TagQ\n", disc_allowed ? "" : "o", scmd->pid, pSRB)); | 575 | DEBUG1(printk(KERN_INFO "DC390: Select w%s/DisCn for Cmd %li (SRB %p), No TagQ\n", disc_allowed ? "" : "o", scmd->serial_number, pSRB)); |
576 | } | 576 | } |
577 | 577 | ||
578 | pSRB->SRBState = SRB_START_; | 578 | pSRB->SRBState = SRB_START_; |
@@ -623,7 +623,7 @@ dc390_StartSCSI( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_sr | |||
623 | { | 623 | { |
624 | dc390_freetag (pDCB, pSRB); | 624 | dc390_freetag (pDCB, pSRB); |
625 | DEBUG0(printk ("DC390: Interrupt during Start SCSI (pid %li, target %02i-%02i)\n", | 625 | DEBUG0(printk ("DC390: Interrupt during Start SCSI (pid %li, target %02i-%02i)\n", |
626 | scmd->pid, scmd->device->id, scmd->device->lun)); | 626 | scmd->serial_number, scmd->device->id, scmd->device->lun)); |
627 | pSRB->SRBState = SRB_READY; | 627 | pSRB->SRBState = SRB_READY; |
628 | //DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD); | 628 | //DC390_write8 (ScsiCmd, CLEAR_FIFO_CMD); |
629 | pACB->SelLost++; | 629 | pACB->SelLost++; |
@@ -1708,7 +1708,7 @@ dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* | |||
1708 | status = pSRB->TargetStatus; | 1708 | status = pSRB->TargetStatus; |
1709 | 1709 | ||
1710 | DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p, pid %li\n", status, pcmd->result,\ | 1710 | DEBUG0(printk (" SRBdone (%02x,%08x), SRB %p, pid %li\n", status, pcmd->result,\ |
1711 | pSRB, pcmd->pid)); | 1711 | pSRB, pcmd->serial_number)); |
1712 | if(pSRB->SRBFlag & AUTO_REQSENSE) | 1712 | if(pSRB->SRBFlag & AUTO_REQSENSE) |
1713 | { /* Last command was a Request Sense */ | 1713 | { /* Last command was a Request Sense */ |
1714 | pSRB->SRBFlag &= ~AUTO_REQSENSE; | 1714 | pSRB->SRBFlag &= ~AUTO_REQSENSE; |
@@ -1729,7 +1729,7 @@ dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* | |||
1729 | } else { | 1729 | } else { |
1730 | SET_RES_DRV(pcmd->result, DRIVER_SENSE); | 1730 | SET_RES_DRV(pcmd->result, DRIVER_SENSE); |
1731 | //pSRB->ScsiCmdLen = (u8) (pSRB->Segment1[0] >> 8); | 1731 | //pSRB->ScsiCmdLen = (u8) (pSRB->Segment1[0] >> 8); |
1732 | DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun)); | 1732 | DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->serial_number, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun)); |
1733 | pSRB->TotalXferredLen = 0; | 1733 | pSRB->TotalXferredLen = 0; |
1734 | SET_RES_DID(pcmd->result, DID_SOFT_ERROR); | 1734 | SET_RES_DID(pcmd->result, DID_SOFT_ERROR); |
1735 | } | 1735 | } |
@@ -1749,7 +1749,7 @@ dc390_SRBdone( struct dc390_acb* pACB, struct dc390_dcb* pDCB, struct dc390_srb* | |||
1749 | else if (status == SAM_STAT_TASK_SET_FULL) | 1749 | else if (status == SAM_STAT_TASK_SET_FULL) |
1750 | { | 1750 | { |
1751 | scsi_track_queue_full(pcmd->device, pDCB->GoingSRBCnt - 1); | 1751 | scsi_track_queue_full(pcmd->device, pDCB->GoingSRBCnt - 1); |
1752 | DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->pid, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun)); | 1752 | DEBUG0 (printk ("DC390: RETRY pid %li (%02x), target %02i-%02i\n", pcmd->serial_number, pcmd->cmnd[0], pcmd->device->id, pcmd->device->lun)); |
1753 | pSRB->TotalXferredLen = 0; | 1753 | pSRB->TotalXferredLen = 0; |
1754 | SET_RES_DID(pcmd->result, DID_SOFT_ERROR); | 1754 | SET_RES_DID(pcmd->result, DID_SOFT_ERROR); |
1755 | } | 1755 | } |
@@ -1803,7 +1803,7 @@ cmd_done: | |||
1803 | /* Add to free list */ | 1803 | /* Add to free list */ |
1804 | dc390_Free_insert (pACB, pSRB); | 1804 | dc390_Free_insert (pACB, pSRB); |
1805 | 1805 | ||
1806 | DEBUG0(printk (KERN_DEBUG "DC390: SRBdone: done pid %li\n", pcmd->pid)); | 1806 | DEBUG0(printk (KERN_DEBUG "DC390: SRBdone: done pid %li\n", pcmd->serial_number)); |
1807 | pcmd->scsi_done (pcmd); | 1807 | pcmd->scsi_done (pcmd); |
1808 | 1808 | ||
1809 | return; | 1809 | return; |
@@ -1998,7 +1998,7 @@ static int DC390_abort(struct scsi_cmnd *cmd) | |||
1998 | struct dc390_dcb *pDCB = (struct dc390_dcb*) cmd->device->hostdata; | 1998 | struct dc390_dcb *pDCB = (struct dc390_dcb*) cmd->device->hostdata; |
1999 | 1999 | ||
2000 | scmd_printk(KERN_WARNING, cmd, | 2000 | scmd_printk(KERN_WARNING, cmd, |
2001 | "DC390: Abort command (pid %li)\n", cmd->pid); | 2001 | "DC390: Abort command (pid %li)\n", cmd->serial_number); |
2002 | 2002 | ||
2003 | /* abort() is too stupid for already sent commands at the moment. | 2003 | /* abort() is too stupid for already sent commands at the moment. |
2004 | * If it's called we are in trouble anyway, so let's dump some info | 2004 | * If it's called we are in trouble anyway, so let's dump some info |
@@ -2006,7 +2006,7 @@ static int DC390_abort(struct scsi_cmnd *cmd) | |||
2006 | dc390_dumpinfo(pACB, pDCB, NULL); | 2006 | dc390_dumpinfo(pACB, pDCB, NULL); |
2007 | 2007 | ||
2008 | pDCB->DCBFlag |= ABORT_DEV_; | 2008 | pDCB->DCBFlag |= ABORT_DEV_; |
2009 | printk(KERN_INFO "DC390: Aborted pid %li\n", cmd->pid); | 2009 | printk(KERN_INFO "DC390: Aborted pid %li\n", cmd->serial_number); |
2010 | 2010 | ||
2011 | return FAILED; | 2011 | return FAILED; |
2012 | } | 2012 | } |
diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c index 9e8232a1f169..fc9f51818e8f 100644 --- a/drivers/scsi/u14-34f.c +++ b/drivers/scsi/u14-34f.c | |||
@@ -1254,7 +1254,7 @@ static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scs | |||
1254 | 1254 | ||
1255 | if (SCpnt->host_scribble) | 1255 | if (SCpnt->host_scribble) |
1256 | panic("%s: qcomm, pid %ld, SCpnt %p already active.\n", | 1256 | panic("%s: qcomm, pid %ld, SCpnt %p already active.\n", |
1257 | BN(j), SCpnt->pid, SCpnt); | 1257 | BN(j), SCpnt->serial_number, SCpnt); |
1258 | 1258 | ||
1259 | /* i is the mailbox number, look for the first free mailbox | 1259 | /* i is the mailbox number, look for the first free mailbox |
1260 | starting from last_cp_used */ | 1260 | starting from last_cp_used */ |
@@ -1285,7 +1285,7 @@ static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scs | |||
1285 | 1285 | ||
1286 | if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n", | 1286 | if (do_trace) printk("%s: qcomm, mbox %d, target %d.%d:%d, pid %ld.\n", |
1287 | BN(j), i, SCpnt->device->channel, SCpnt->device->id, | 1287 | BN(j), i, SCpnt->device->channel, SCpnt->device->id, |
1288 | SCpnt->device->lun, SCpnt->pid); | 1288 | SCpnt->device->lun, SCpnt->serial_number); |
1289 | 1289 | ||
1290 | cpp->opcode = OP_SCSI; | 1290 | cpp->opcode = OP_SCSI; |
1291 | cpp->channel = SCpnt->device->channel; | 1291 | cpp->channel = SCpnt->device->channel; |
@@ -1312,7 +1312,7 @@ static int u14_34f_queuecommand(struct scsi_cmnd *SCpnt, void (*done)(struct scs | |||
1312 | unmap_dma(i, j); | 1312 | unmap_dma(i, j); |
1313 | SCpnt->host_scribble = NULL; | 1313 | SCpnt->host_scribble = NULL; |
1314 | scmd_printk(KERN_INFO, SCpnt, | 1314 | scmd_printk(KERN_INFO, SCpnt, |
1315 | "qcomm, pid %ld, adapter busy.\n", SCpnt->pid); | 1315 | "qcomm, pid %ld, adapter busy.\n", SCpnt->serial_number); |
1316 | return 1; | 1316 | return 1; |
1317 | } | 1317 | } |
1318 | 1318 | ||
@@ -1333,13 +1333,13 @@ static int u14_34f_eh_abort(struct scsi_cmnd *SCarg) { | |||
1333 | 1333 | ||
1334 | if (SCarg->host_scribble == NULL) { | 1334 | if (SCarg->host_scribble == NULL) { |
1335 | scmd_printk(KERN_INFO, SCarg, "abort, pid %ld inactive.\n", | 1335 | scmd_printk(KERN_INFO, SCarg, "abort, pid %ld inactive.\n", |
1336 | SCarg->pid); | 1336 | SCarg->serial_number); |
1337 | return SUCCESS; | 1337 | return SUCCESS; |
1338 | } | 1338 | } |
1339 | 1339 | ||
1340 | i = *(unsigned int *)SCarg->host_scribble; | 1340 | i = *(unsigned int *)SCarg->host_scribble; |
1341 | scmd_printk(KERN_INFO, SCarg, "abort, mbox %d, pid %ld.\n", | 1341 | scmd_printk(KERN_INFO, SCarg, "abort, mbox %d, pid %ld.\n", |
1342 | i, SCarg->pid); | 1342 | i, SCarg->serial_number); |
1343 | 1343 | ||
1344 | if (i >= sh[j]->can_queue) | 1344 | if (i >= sh[j]->can_queue) |
1345 | panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j)); | 1345 | panic("%s: abort, invalid SCarg->host_scribble.\n", BN(j)); |
@@ -1383,7 +1383,7 @@ static int u14_34f_eh_abort(struct scsi_cmnd *SCarg) { | |||
1383 | SCarg->host_scribble = NULL; | 1383 | SCarg->host_scribble = NULL; |
1384 | HD(j)->cp_stat[i] = FREE; | 1384 | HD(j)->cp_stat[i] = FREE; |
1385 | printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n", | 1385 | printk("%s, abort, mbox %d ready, DID_ABORT, pid %ld done.\n", |
1386 | BN(j), i, SCarg->pid); | 1386 | BN(j), i, SCarg->serial_number); |
1387 | SCarg->scsi_done(SCarg); | 1387 | SCarg->scsi_done(SCarg); |
1388 | return SUCCESS; | 1388 | return SUCCESS; |
1389 | } | 1389 | } |
@@ -1397,12 +1397,12 @@ static int u14_34f_eh_host_reset(struct scsi_cmnd *SCarg) { | |||
1397 | struct scsi_cmnd *SCpnt; | 1397 | struct scsi_cmnd *SCpnt; |
1398 | 1398 | ||
1399 | j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number; | 1399 | j = ((struct hostdata *) SCarg->device->host->hostdata)->board_number; |
1400 | scmd_printk(KERN_INFO, SCarg, "reset, enter, pid %ld.\n", SCarg->pid); | 1400 | scmd_printk(KERN_INFO, SCarg, "reset, enter, pid %ld.\n", SCarg->serial_number); |
1401 | 1401 | ||
1402 | spin_lock_irq(sh[j]->host_lock); | 1402 | spin_lock_irq(sh[j]->host_lock); |
1403 | 1403 | ||
1404 | if (SCarg->host_scribble == NULL) | 1404 | if (SCarg->host_scribble == NULL) |
1405 | printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->pid); | 1405 | printk("%s: reset, pid %ld inactive.\n", BN(j), SCarg->serial_number); |
1406 | 1406 | ||
1407 | if (HD(j)->in_reset) { | 1407 | if (HD(j)->in_reset) { |
1408 | printk("%s: reset, exit, already in reset.\n", BN(j)); | 1408 | printk("%s: reset, exit, already in reset.\n", BN(j)); |
@@ -1440,13 +1440,13 @@ static int u14_34f_eh_host_reset(struct scsi_cmnd *SCarg) { | |||
1440 | if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) { | 1440 | if (HD(j)->cp_stat[i] == READY || HD(j)->cp_stat[i] == ABORTING) { |
1441 | HD(j)->cp_stat[i] = ABORTING; | 1441 | HD(j)->cp_stat[i] = ABORTING; |
1442 | printk("%s: reset, mbox %d aborting, pid %ld.\n", | 1442 | printk("%s: reset, mbox %d aborting, pid %ld.\n", |
1443 | BN(j), i, SCpnt->pid); | 1443 | BN(j), i, SCpnt->serial_number); |
1444 | } | 1444 | } |
1445 | 1445 | ||
1446 | else { | 1446 | else { |
1447 | HD(j)->cp_stat[i] = IN_RESET; | 1447 | HD(j)->cp_stat[i] = IN_RESET; |
1448 | printk("%s: reset, mbox %d in reset, pid %ld.\n", | 1448 | printk("%s: reset, mbox %d in reset, pid %ld.\n", |
1449 | BN(j), i, SCpnt->pid); | 1449 | BN(j), i, SCpnt->serial_number); |
1450 | } | 1450 | } |
1451 | 1451 | ||
1452 | if (SCpnt->host_scribble == NULL) | 1452 | if (SCpnt->host_scribble == NULL) |
@@ -1495,7 +1495,7 @@ static int u14_34f_eh_host_reset(struct scsi_cmnd *SCarg) { | |||
1495 | HD(j)->cp_stat[i] = LOCKED; | 1495 | HD(j)->cp_stat[i] = LOCKED; |
1496 | 1496 | ||
1497 | printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n", | 1497 | printk("%s, reset, mbox %d locked, DID_RESET, pid %ld done.\n", |
1498 | BN(j), i, SCpnt->pid); | 1498 | BN(j), i, SCpnt->serial_number); |
1499 | } | 1499 | } |
1500 | 1500 | ||
1501 | else if (HD(j)->cp_stat[i] == ABORTING) { | 1501 | else if (HD(j)->cp_stat[i] == ABORTING) { |
@@ -1508,7 +1508,7 @@ static int u14_34f_eh_host_reset(struct scsi_cmnd *SCarg) { | |||
1508 | HD(j)->cp_stat[i] = FREE; | 1508 | HD(j)->cp_stat[i] = FREE; |
1509 | 1509 | ||
1510 | printk("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n", | 1510 | printk("%s, reset, mbox %d aborting, DID_RESET, pid %ld done.\n", |
1511 | BN(j), i, SCpnt->pid); | 1511 | BN(j), i, SCpnt->serial_number); |
1512 | } | 1512 | } |
1513 | 1513 | ||
1514 | else | 1514 | else |
@@ -1522,7 +1522,7 @@ static int u14_34f_eh_host_reset(struct scsi_cmnd *SCarg) { | |||
1522 | HD(j)->in_reset = FALSE; | 1522 | HD(j)->in_reset = FALSE; |
1523 | do_trace = FALSE; | 1523 | do_trace = FALSE; |
1524 | 1524 | ||
1525 | if (arg_done) printk("%s: reset, exit, pid %ld done.\n", BN(j), SCarg->pid); | 1525 | if (arg_done) printk("%s: reset, exit, pid %ld done.\n", BN(j), SCarg->serial_number); |
1526 | else printk("%s: reset, exit.\n", BN(j)); | 1526 | else printk("%s: reset, exit.\n", BN(j)); |
1527 | 1527 | ||
1528 | spin_unlock_irq(sh[j]->host_lock); | 1528 | spin_unlock_irq(sh[j]->host_lock); |
@@ -1639,7 +1639,7 @@ static int reorder(unsigned int j, unsigned long cursec, | |||
1639 | 1639 | ||
1640 | if (!input_only) for (n = 0; n < n_ready; n++) { | 1640 | if (!input_only) for (n = 0; n < n_ready; n++) { |
1641 | k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt; | 1641 | k = il[n]; cpp = &HD(j)->cp[k]; SCpnt = cpp->SCpnt; |
1642 | ll[n] = SCpnt->request->nr_sectors; pl[n] = SCpnt->pid; | 1642 | ll[n] = SCpnt->request->nr_sectors; pl[n] = SCpnt->serial_number; |
1643 | 1643 | ||
1644 | if (!n) continue; | 1644 | if (!n) continue; |
1645 | 1645 | ||
@@ -1666,7 +1666,7 @@ static int reorder(unsigned int j, unsigned long cursec, | |||
1666 | printk("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %ld"\ | 1666 | printk("%s %d.%d:%d pid %ld mb %d fc %d nr %d sec %ld ns %ld"\ |
1667 | " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n", | 1667 | " cur %ld s:%c r:%c rev:%c in:%c ov:%c xd %d.\n", |
1668 | (ihdlr ? "ihdlr" : "qcomm"), SCpnt->channel, SCpnt->target, | 1668 | (ihdlr ? "ihdlr" : "qcomm"), SCpnt->channel, SCpnt->target, |
1669 | SCpnt->lun, SCpnt->pid, k, flushcount, n_ready, | 1669 | SCpnt->lun, SCpnt->serial_number, k, flushcount, n_ready, |
1670 | SCpnt->request->sector, SCpnt->request->nr_sectors, cursec, | 1670 | SCpnt->request->sector, SCpnt->request->nr_sectors, cursec, |
1671 | YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only), | 1671 | YESNO(s), YESNO(r), YESNO(rev), YESNO(input_only), |
1672 | YESNO(overlap), cpp->xdir); | 1672 | YESNO(overlap), cpp->xdir); |
@@ -1703,7 +1703,7 @@ static void flush_dev(struct scsi_device *dev, unsigned long cursec, unsigned in | |||
1703 | scmd_printk(KERN_INFO, SCpnt, | 1703 | scmd_printk(KERN_INFO, SCpnt, |
1704 | "%s, pid %ld, mbox %d, adapter" | 1704 | "%s, pid %ld, mbox %d, adapter" |
1705 | " busy, will abort.\n", (ihdlr ? "ihdlr" : "qcomm"), | 1705 | " busy, will abort.\n", (ihdlr ? "ihdlr" : "qcomm"), |
1706 | SCpnt->pid, k); | 1706 | SCpnt->serial_number, k); |
1707 | HD(j)->cp_stat[k] = ABORTING; | 1707 | HD(j)->cp_stat[k] = ABORTING; |
1708 | continue; | 1708 | continue; |
1709 | } | 1709 | } |
@@ -1787,11 +1787,11 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { | |||
1787 | 1787 | ||
1788 | if (SCpnt->host_scribble == NULL) | 1788 | if (SCpnt->host_scribble == NULL) |
1789 | panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", BN(j), i, | 1789 | panic("%s: ihdlr, mbox %d, pid %ld, SCpnt %p garbled.\n", BN(j), i, |
1790 | SCpnt->pid, SCpnt); | 1790 | SCpnt->serial_number, SCpnt); |
1791 | 1791 | ||
1792 | if (*(unsigned int *)SCpnt->host_scribble != i) | 1792 | if (*(unsigned int *)SCpnt->host_scribble != i) |
1793 | panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n", | 1793 | panic("%s: ihdlr, mbox %d, pid %ld, index mismatch %d.\n", |
1794 | BN(j), i, SCpnt->pid, *(unsigned int *)SCpnt->host_scribble); | 1794 | BN(j), i, SCpnt->serial_number, *(unsigned int *)SCpnt->host_scribble); |
1795 | 1795 | ||
1796 | sync_dma(i, j); | 1796 | sync_dma(i, j); |
1797 | 1797 | ||
@@ -1835,12 +1835,12 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { | |||
1835 | (SCpnt->sense_buffer[2] & 0xf) == NOT_READY))) | 1835 | (SCpnt->sense_buffer[2] & 0xf) == NOT_READY))) |
1836 | scmd_printk(KERN_INFO, SCpnt, | 1836 | scmd_printk(KERN_INFO, SCpnt, |
1837 | "ihdlr, pid %ld, target_status 0x%x, sense key 0x%x.\n", | 1837 | "ihdlr, pid %ld, target_status 0x%x, sense key 0x%x.\n", |
1838 | SCpnt->pid, spp->target_status, | 1838 | SCpnt->serial_number, spp->target_status, |
1839 | SCpnt->sense_buffer[2]); | 1839 | SCpnt->sense_buffer[2]); |
1840 | 1840 | ||
1841 | HD(j)->target_to[scmd_id(SCpnt)][scmd_channel(SCpnt)] = 0; | 1841 | HD(j)->target_to[scmd_id(SCpnt)][scmd_channel(SCpnt)] = 0; |
1842 | 1842 | ||
1843 | if (HD(j)->last_retried_pid == SCpnt->pid) HD(j)->retries = 0; | 1843 | if (HD(j)->last_retried_pid == SCpnt->serial_number) HD(j)->retries = 0; |
1844 | 1844 | ||
1845 | break; | 1845 | break; |
1846 | case ASST: /* Selection Time Out */ | 1846 | case ASST: /* Selection Time Out */ |
@@ -1877,7 +1877,7 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { | |||
1877 | #endif | 1877 | #endif |
1878 | 1878 | ||
1879 | HD(j)->retries++; | 1879 | HD(j)->retries++; |
1880 | HD(j)->last_retried_pid = SCpnt->pid; | 1880 | HD(j)->last_retried_pid = SCpnt->serial_number; |
1881 | } | 1881 | } |
1882 | else | 1882 | else |
1883 | status = DID_ERROR << 16; | 1883 | status = DID_ERROR << 16; |
@@ -1907,7 +1907,7 @@ static irqreturn_t ihdlr(int irq, unsigned int j) { | |||
1907 | #endif | 1907 | #endif |
1908 | scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x,"\ | 1908 | scmd_printk(KERN_INFO, SCpnt, "ihdlr, mbox %2d, err 0x%x:%x,"\ |
1909 | " pid %ld, reg 0x%x, count %d.\n", | 1909 | " pid %ld, reg 0x%x, count %d.\n", |
1910 | i, spp->adapter_status, spp->target_status, SCpnt->pid, | 1910 | i, spp->adapter_status, spp->target_status, SCpnt->serial_number, |
1911 | reg, HD(j)->iocount); | 1911 | reg, HD(j)->iocount); |
1912 | 1912 | ||
1913 | unmap_dma(i, j); | 1913 | unmap_dma(i, j); |
diff --git a/drivers/scsi/wd33c93.c b/drivers/scsi/wd33c93.c index b92ff047af38..0e8e642fd3b0 100644 --- a/drivers/scsi/wd33c93.c +++ b/drivers/scsi/wd33c93.c | |||
@@ -381,7 +381,7 @@ wd33c93_queuecommand(struct scsi_cmnd *cmd, | |||
381 | hostdata = (struct WD33C93_hostdata *) cmd->device->host->hostdata; | 381 | hostdata = (struct WD33C93_hostdata *) cmd->device->host->hostdata; |
382 | 382 | ||
383 | DB(DB_QUEUE_COMMAND, | 383 | DB(DB_QUEUE_COMMAND, |
384 | printk("Q-%d-%02x-%ld( ", cmd->device->id, cmd->cmnd[0], cmd->pid)) | 384 | printk("Q-%d-%02x-%ld( ", cmd->device->id, cmd->cmnd[0], cmd->serial_number)) |
385 | 385 | ||
386 | /* Set up a few fields in the scsi_cmnd structure for our own use: | 386 | /* Set up a few fields in the scsi_cmnd structure for our own use: |
387 | * - host_scribble is the pointer to the next cmd in the input queue | 387 | * - host_scribble is the pointer to the next cmd in the input queue |
@@ -463,7 +463,7 @@ wd33c93_queuecommand(struct scsi_cmnd *cmd, | |||
463 | 463 | ||
464 | wd33c93_execute(cmd->device->host); | 464 | wd33c93_execute(cmd->device->host); |
465 | 465 | ||
466 | DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->pid)) | 466 | DB(DB_QUEUE_COMMAND, printk(")Q-%ld ", cmd->serial_number)) |
467 | 467 | ||
468 | spin_unlock_irq(&hostdata->lock); | 468 | spin_unlock_irq(&hostdata->lock); |
469 | return 0; | 469 | return 0; |
@@ -686,7 +686,7 @@ wd33c93_execute(struct Scsi_Host *instance) | |||
686 | */ | 686 | */ |
687 | 687 | ||
688 | DB(DB_EXECUTE, | 688 | DB(DB_EXECUTE, |
689 | printk("%s%ld)EX-2 ", (cmd->SCp.phase) ? "d:" : "", cmd->pid)) | 689 | printk("%s%ld)EX-2 ", (cmd->SCp.phase) ? "d:" : "", cmd->serial_number)) |
690 | } | 690 | } |
691 | 691 | ||
692 | static void | 692 | static void |
@@ -963,7 +963,7 @@ wd33c93_intr(struct Scsi_Host *instance) | |||
963 | case CSR_XFER_DONE | PHS_COMMAND: | 963 | case CSR_XFER_DONE | PHS_COMMAND: |
964 | case CSR_UNEXP | PHS_COMMAND: | 964 | case CSR_UNEXP | PHS_COMMAND: |
965 | case CSR_SRV_REQ | PHS_COMMAND: | 965 | case CSR_SRV_REQ | PHS_COMMAND: |
966 | DB(DB_INTR, printk("CMND-%02x,%ld", cmd->cmnd[0], cmd->pid)) | 966 | DB(DB_INTR, printk("CMND-%02x,%ld", cmd->cmnd[0], cmd->serial_number)) |
967 | transfer_pio(regs, cmd->cmnd, cmd->cmd_len, DATA_OUT_DIR, | 967 | transfer_pio(regs, cmd->cmnd, cmd->cmd_len, DATA_OUT_DIR, |
968 | hostdata); | 968 | hostdata); |
969 | hostdata->state = S_CONNECTED; | 969 | hostdata->state = S_CONNECTED; |
@@ -1007,7 +1007,7 @@ wd33c93_intr(struct Scsi_Host *instance) | |||
1007 | switch (msg) { | 1007 | switch (msg) { |
1008 | 1008 | ||
1009 | case COMMAND_COMPLETE: | 1009 | case COMMAND_COMPLETE: |
1010 | DB(DB_INTR, printk("CCMP-%ld", cmd->pid)) | 1010 | DB(DB_INTR, printk("CCMP-%ld", cmd->serial_number)) |
1011 | write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK); | 1011 | write_wd33c93_cmd(regs, WD_CMD_NEGATE_ACK); |
1012 | hostdata->state = S_PRE_CMP_DISC; | 1012 | hostdata->state = S_PRE_CMP_DISC; |
1013 | break; | 1013 | break; |
@@ -1174,7 +1174,7 @@ wd33c93_intr(struct Scsi_Host *instance) | |||
1174 | 1174 | ||
1175 | write_wd33c93(regs, WD_SOURCE_ID, SRCID_ER); | 1175 | write_wd33c93(regs, WD_SOURCE_ID, SRCID_ER); |
1176 | if (phs == 0x60) { | 1176 | if (phs == 0x60) { |
1177 | DB(DB_INTR, printk("SX-DONE-%ld", cmd->pid)) | 1177 | DB(DB_INTR, printk("SX-DONE-%ld", cmd->serial_number)) |
1178 | cmd->SCp.Message = COMMAND_COMPLETE; | 1178 | cmd->SCp.Message = COMMAND_COMPLETE; |
1179 | lun = read_wd33c93(regs, WD_TARGET_LUN); | 1179 | lun = read_wd33c93(regs, WD_TARGET_LUN); |
1180 | DB(DB_INTR, printk(":%d.%d", cmd->SCp.Status, lun)) | 1180 | DB(DB_INTR, printk(":%d.%d", cmd->SCp.Status, lun)) |
@@ -1201,7 +1201,7 @@ wd33c93_intr(struct Scsi_Host *instance) | |||
1201 | } else { | 1201 | } else { |
1202 | printk | 1202 | printk |
1203 | ("%02x:%02x:%02x-%ld: Unknown SEL_XFER_DONE phase!!---", | 1203 | ("%02x:%02x:%02x-%ld: Unknown SEL_XFER_DONE phase!!---", |
1204 | asr, sr, phs, cmd->pid); | 1204 | asr, sr, phs, cmd->serial_number); |
1205 | spin_unlock_irqrestore(&hostdata->lock, flags); | 1205 | spin_unlock_irqrestore(&hostdata->lock, flags); |
1206 | } | 1206 | } |
1207 | break; | 1207 | break; |
@@ -1266,7 +1266,7 @@ wd33c93_intr(struct Scsi_Host *instance) | |||
1266 | spin_unlock_irqrestore(&hostdata->lock, flags); | 1266 | spin_unlock_irqrestore(&hostdata->lock, flags); |
1267 | return; | 1267 | return; |
1268 | } | 1268 | } |
1269 | DB(DB_INTR, printk("UNEXP_DISC-%ld", cmd->pid)) | 1269 | DB(DB_INTR, printk("UNEXP_DISC-%ld", cmd->serial_number)) |
1270 | hostdata->connected = NULL; | 1270 | hostdata->connected = NULL; |
1271 | hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); | 1271 | hostdata->busy[cmd->device->id] &= ~(1 << cmd->device->lun); |
1272 | hostdata->state = S_UNCONNECTED; | 1272 | hostdata->state = S_UNCONNECTED; |
@@ -1292,7 +1292,7 @@ wd33c93_intr(struct Scsi_Host *instance) | |||
1292 | */ | 1292 | */ |
1293 | 1293 | ||
1294 | write_wd33c93(regs, WD_SOURCE_ID, SRCID_ER); | 1294 | write_wd33c93(regs, WD_SOURCE_ID, SRCID_ER); |
1295 | DB(DB_INTR, printk("DISC-%ld", cmd->pid)) | 1295 | DB(DB_INTR, printk("DISC-%ld", cmd->serial_number)) |
1296 | if (cmd == NULL) { | 1296 | if (cmd == NULL) { |
1297 | printk(" - Already disconnected! "); | 1297 | printk(" - Already disconnected! "); |
1298 | hostdata->state = S_UNCONNECTED; | 1298 | hostdata->state = S_UNCONNECTED; |
@@ -1491,7 +1491,7 @@ wd33c93_intr(struct Scsi_Host *instance) | |||
1491 | } else | 1491 | } else |
1492 | hostdata->state = S_CONNECTED; | 1492 | hostdata->state = S_CONNECTED; |
1493 | 1493 | ||
1494 | DB(DB_INTR, printk("-%ld", cmd->pid)) | 1494 | DB(DB_INTR, printk("-%ld", cmd->serial_number)) |
1495 | spin_unlock_irqrestore(&hostdata->lock, flags); | 1495 | spin_unlock_irqrestore(&hostdata->lock, flags); |
1496 | break; | 1496 | break; |
1497 | 1497 | ||
@@ -1638,7 +1638,7 @@ wd33c93_abort(struct scsi_cmnd * cmd) | |||
1638 | cmd->result = DID_ABORT << 16; | 1638 | cmd->result = DID_ABORT << 16; |
1639 | printk | 1639 | printk |
1640 | ("scsi%d: Abort - removing command %ld from input_Q. ", | 1640 | ("scsi%d: Abort - removing command %ld from input_Q. ", |
1641 | instance->host_no, cmd->pid); | 1641 | instance->host_no, cmd->serial_number); |
1642 | enable_irq(cmd->device->host->irq); | 1642 | enable_irq(cmd->device->host->irq); |
1643 | cmd->scsi_done(cmd); | 1643 | cmd->scsi_done(cmd); |
1644 | return SUCCESS; | 1644 | return SUCCESS; |
@@ -1663,7 +1663,7 @@ wd33c93_abort(struct scsi_cmnd * cmd) | |||
1663 | unsigned long timeout; | 1663 | unsigned long timeout; |
1664 | 1664 | ||
1665 | printk("scsi%d: Aborting connected command %ld - ", | 1665 | printk("scsi%d: Aborting connected command %ld - ", |
1666 | instance->host_no, cmd->pid); | 1666 | instance->host_no, cmd->serial_number); |
1667 | 1667 | ||
1668 | printk("stopping DMA - "); | 1668 | printk("stopping DMA - "); |
1669 | if (hostdata->dma == D_DMA_RUNNING) { | 1669 | if (hostdata->dma == D_DMA_RUNNING) { |
@@ -1730,7 +1730,7 @@ wd33c93_abort(struct scsi_cmnd * cmd) | |||
1730 | if (tmp == cmd) { | 1730 | if (tmp == cmd) { |
1731 | printk | 1731 | printk |
1732 | ("scsi%d: Abort - command %ld found on disconnected_Q - ", | 1732 | ("scsi%d: Abort - command %ld found on disconnected_Q - ", |
1733 | instance->host_no, cmd->pid); | 1733 | instance->host_no, cmd->serial_number); |
1734 | printk("Abort SNOOZE. "); | 1734 | printk("Abort SNOOZE. "); |
1735 | enable_irq(cmd->device->host->irq); | 1735 | enable_irq(cmd->device->host->irq); |
1736 | return FAILED; | 1736 | return FAILED; |
@@ -2184,7 +2184,7 @@ wd33c93_proc_info(struct Scsi_Host *instance, char *buf, char **start, off_t off | |||
2184 | if (hd->connected) { | 2184 | if (hd->connected) { |
2185 | cmd = (struct scsi_cmnd *) hd->connected; | 2185 | cmd = (struct scsi_cmnd *) hd->connected; |
2186 | sprintf(tbuf, " %ld-%d:%d(%02x)", | 2186 | sprintf(tbuf, " %ld-%d:%d(%02x)", |
2187 | cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); | 2187 | cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); |
2188 | strcat(bp, tbuf); | 2188 | strcat(bp, tbuf); |
2189 | } | 2189 | } |
2190 | } | 2190 | } |
@@ -2193,7 +2193,7 @@ wd33c93_proc_info(struct Scsi_Host *instance, char *buf, char **start, off_t off | |||
2193 | cmd = (struct scsi_cmnd *) hd->input_Q; | 2193 | cmd = (struct scsi_cmnd *) hd->input_Q; |
2194 | while (cmd) { | 2194 | while (cmd) { |
2195 | sprintf(tbuf, " %ld-%d:%d(%02x)", | 2195 | sprintf(tbuf, " %ld-%d:%d(%02x)", |
2196 | cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); | 2196 | cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); |
2197 | strcat(bp, tbuf); | 2197 | strcat(bp, tbuf); |
2198 | cmd = (struct scsi_cmnd *) cmd->host_scribble; | 2198 | cmd = (struct scsi_cmnd *) cmd->host_scribble; |
2199 | } | 2199 | } |
@@ -2203,7 +2203,7 @@ wd33c93_proc_info(struct Scsi_Host *instance, char *buf, char **start, off_t off | |||
2203 | cmd = (struct scsi_cmnd *) hd->disconnected_Q; | 2203 | cmd = (struct scsi_cmnd *) hd->disconnected_Q; |
2204 | while (cmd) { | 2204 | while (cmd) { |
2205 | sprintf(tbuf, " %ld-%d:%d(%02x)", | 2205 | sprintf(tbuf, " %ld-%d:%d(%02x)", |
2206 | cmd->pid, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); | 2206 | cmd->serial_number, cmd->device->id, cmd->device->lun, cmd->cmnd[0]); |
2207 | strcat(bp, tbuf); | 2207 | strcat(bp, tbuf); |
2208 | cmd = (struct scsi_cmnd *) cmd->host_scribble; | 2208 | cmd = (struct scsi_cmnd *) cmd->host_scribble; |
2209 | } | 2209 | } |
diff --git a/drivers/scsi/zorro7xx.c b/drivers/scsi/zorro7xx.c index c822debc2668..ac67394c7373 100644 --- a/drivers/scsi/zorro7xx.c +++ b/drivers/scsi/zorro7xx.c | |||
@@ -69,7 +69,7 @@ static struct zorro_device_id zorro7xx_zorro_tbl[] __devinitdata = { | |||
69 | static int __devinit zorro7xx_init_one(struct zorro_dev *z, | 69 | static int __devinit zorro7xx_init_one(struct zorro_dev *z, |
70 | const struct zorro_device_id *ent) | 70 | const struct zorro_device_id *ent) |
71 | { | 71 | { |
72 | struct Scsi_Host * host = NULL; | 72 | struct Scsi_Host *host; |
73 | struct NCR_700_Host_Parameters *hostdata; | 73 | struct NCR_700_Host_Parameters *hostdata; |
74 | struct zorro_driver_data *zdd; | 74 | struct zorro_driver_data *zdd; |
75 | unsigned long board, ioaddr; | 75 | unsigned long board, ioaddr; |
@@ -89,14 +89,12 @@ static int __devinit zorro7xx_init_one(struct zorro_dev *z, | |||
89 | return -EBUSY; | 89 | return -EBUSY; |
90 | } | 90 | } |
91 | 91 | ||
92 | hostdata = kmalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); | 92 | hostdata = kzalloc(sizeof(struct NCR_700_Host_Parameters), GFP_KERNEL); |
93 | if (hostdata == NULL) { | 93 | if (!hostdata) { |
94 | printk(KERN_ERR "zorro7xx: Failed to allocate host data\n"); | 94 | printk(KERN_ERR "zorro7xx: Failed to allocate host data\n"); |
95 | goto out_release; | 95 | goto out_release; |
96 | } | 96 | } |
97 | 97 | ||
98 | memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters)); | ||
99 | |||
100 | /* Fill in the required pieces of hostdata */ | 98 | /* Fill in the required pieces of hostdata */ |
101 | if (ioaddr > 0x01000000) | 99 | if (ioaddr > 0x01000000) |
102 | hostdata->base = ioremap(ioaddr, zorro_resource_len(z)); | 100 | hostdata->base = ioremap(ioaddr, zorro_resource_len(z)); |