diff options
Diffstat (limited to 'drivers/scsi/atp870u.c')
| -rw-r--r-- | drivers/scsi/atp870u.c | 157 |
1 files changed, 83 insertions, 74 deletions
diff --git a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c index 412f8301b757..0ec41f34f462 100644 --- a/drivers/scsi/atp870u.c +++ b/drivers/scsi/atp870u.c | |||
| @@ -2625,29 +2625,32 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 2625 | unsigned int base_io, tmport, error,n; | 2625 | unsigned int base_io, tmport, error,n; |
| 2626 | unsigned char host_id; | 2626 | unsigned char host_id; |
| 2627 | struct Scsi_Host *shpnt = NULL; | 2627 | struct Scsi_Host *shpnt = NULL; |
| 2628 | struct atp_unit atp_dev, *p; | 2628 | struct atp_unit *atpdev, *p; |
| 2629 | unsigned char setupdata[2][16]; | 2629 | unsigned char setupdata[2][16]; |
| 2630 | int count = 0; | 2630 | int count = 0; |
| 2631 | 2631 | ||
| 2632 | atpdev = kzalloc(sizeof(*atpdev), GFP_KERNEL); | ||
| 2633 | if (!atpdev) | ||
| 2634 | return -ENOMEM; | ||
| 2635 | |||
| 2632 | if (pci_enable_device(pdev)) | 2636 | if (pci_enable_device(pdev)) |
| 2633 | return -EIO; | 2637 | goto err_eio; |
| 2634 | 2638 | ||
| 2635 | if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { | 2639 | if (!pci_set_dma_mask(pdev, DMA_32BIT_MASK)) { |
| 2636 | printk(KERN_INFO "atp870u: use 32bit DMA mask.\n"); | 2640 | printk(KERN_INFO "atp870u: use 32bit DMA mask.\n"); |
| 2637 | } else { | 2641 | } else { |
| 2638 | printk(KERN_ERR "atp870u: DMA mask required but not available.\n"); | 2642 | printk(KERN_ERR "atp870u: DMA mask required but not available.\n"); |
| 2639 | return -EIO; | 2643 | goto err_eio; |
| 2640 | } | 2644 | } |
| 2641 | 2645 | ||
| 2642 | memset(&atp_dev, 0, sizeof atp_dev); | ||
| 2643 | /* | 2646 | /* |
| 2644 | * It's probably easier to weed out some revisions like | 2647 | * It's probably easier to weed out some revisions like |
| 2645 | * this than via the PCI device table | 2648 | * this than via the PCI device table |
| 2646 | */ | 2649 | */ |
| 2647 | if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) { | 2650 | if (ent->device == PCI_DEVICE_ID_ARTOP_AEC7610) { |
| 2648 | error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver); | 2651 | error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver); |
| 2649 | if (atp_dev.chip_ver < 2) | 2652 | if (atpdev->chip_ver < 2) |
| 2650 | return -EIO; | 2653 | goto err_eio; |
| 2651 | } | 2654 | } |
| 2652 | 2655 | ||
| 2653 | switch (ent->device) { | 2656 | switch (ent->device) { |
| @@ -2656,15 +2659,15 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 2656 | case ATP880_DEVID1: | 2659 | case ATP880_DEVID1: |
| 2657 | case ATP880_DEVID2: | 2660 | case ATP880_DEVID2: |
| 2658 | case ATP885_DEVID: | 2661 | case ATP885_DEVID: |
| 2659 | atp_dev.chip_ver = 0x04; | 2662 | atpdev->chip_ver = 0x04; |
| 2660 | default: | 2663 | default: |
| 2661 | break; | 2664 | break; |
| 2662 | } | 2665 | } |
| 2663 | base_io = pci_resource_start(pdev, 0); | 2666 | base_io = pci_resource_start(pdev, 0); |
| 2664 | base_io &= 0xfffffff8; | 2667 | base_io &= 0xfffffff8; |
| 2665 | 2668 | ||
| 2666 | if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { | 2669 | if ((ent->device == ATP880_DEVID1)||(ent->device == ATP880_DEVID2)) { |
| 2667 | error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atp_dev.chip_ver); | 2670 | error = pci_read_config_byte(pdev, PCI_CLASS_REVISION, &atpdev->chip_ver); |
| 2668 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 | 2671 | pci_write_config_byte(pdev, PCI_LATENCY_TIMER, 0x80);//JCC082803 |
| 2669 | 2672 | ||
| 2670 | host_id = inb(base_io + 0x39); | 2673 | host_id = inb(base_io + 0x39); |
| @@ -2672,17 +2675,17 @@ static int atp870u_probe(struct pci_dev *pdev, const struct pci_device_id *ent) | |||
| 2672 | 2675 | ||
| 2673 | printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d" | 2676 | printk(KERN_INFO " ACARD AEC-67160 PCI Ultra3 LVD Host Adapter: %d" |
| 2674 | " IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); | 2677 | " IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); |
| 2675 | atp_dev.ioport[0] = base_io + 0x40; | 2678 | atpdev->ioport[0] = base_io + 0x40; |
| 2676 | atp_dev.pciport[0] = base_io + 0x28; | 2679 | atpdev->pciport[0] = base_io + 0x28; |
| 2677 | atp_dev.dev_id = ent->device; | 2680 | atpdev->dev_id = ent->device; |
| 2678 | atp_dev.host_id[0] = host_id; | 2681 | atpdev->host_id[0] = host_id; |
| 2679 | 2682 | ||
| 2680 | tmport = base_io + 0x22; | 2683 | tmport = base_io + 0x22; |
| 2681 | atp_dev.scam_on = inb(tmport); | 2684 | atpdev->scam_on = inb(tmport); |
| 2682 | tmport += 0x13; | 2685 | tmport += 0x13; |
| 2683 | atp_dev.global_map[0] = inb(tmport); | 2686 | atpdev->global_map[0] = inb(tmport); |
| 2684 | tmport += 0x07; | 2687 | tmport += 0x07; |
| 2685 | atp_dev.ultra_map[0] = inw(tmport); | 2688 | atpdev->ultra_map[0] = inw(tmport); |
| 2686 | 2689 | ||
| 2687 | n = 0x3f09; | 2690 | n = 0x3f09; |
| 2688 | next_fblk_880: | 2691 | next_fblk_880: |
| @@ -2695,57 +2698,57 @@ next_fblk_880: | |||
| 2695 | if (inb(base_io + 0x30) == 0xff) | 2698 | if (inb(base_io + 0x30) == 0xff) |
| 2696 | goto flash_ok_880; | 2699 | goto flash_ok_880; |
| 2697 | 2700 | ||
| 2698 | atp_dev.sp[0][m++] = inb(base_io + 0x30); | 2701 | atpdev->sp[0][m++] = inb(base_io + 0x30); |
| 2699 | atp_dev.sp[0][m++] = inb(base_io + 0x31); | 2702 | atpdev->sp[0][m++] = inb(base_io + 0x31); |
| 2700 | atp_dev.sp[0][m++] = inb(base_io + 0x32); | 2703 | atpdev->sp[0][m++] = inb(base_io + 0x32); |
| 2701 | atp_dev.sp[0][m++] = inb(base_io + 0x33); | 2704 | atpdev->sp[0][m++] = inb(base_io + 0x33); |
| 2702 | outw(n, base_io + 0x34); | 2705 | outw(n, base_io + 0x34); |
| 2703 | n += 0x0002; | 2706 | n += 0x0002; |
| 2704 | atp_dev.sp[0][m++] = inb(base_io + 0x30); | 2707 | atpdev->sp[0][m++] = inb(base_io + 0x30); |
| 2705 | atp_dev.sp[0][m++] = inb(base_io + 0x31); | 2708 | atpdev->sp[0][m++] = inb(base_io + 0x31); |
| 2706 | atp_dev.sp[0][m++] = inb(base_io + 0x32); | 2709 | atpdev->sp[0][m++] = inb(base_io + 0x32); |
| 2707 | atp_dev.sp[0][m++] = inb(base_io + 0x33); | 2710 | atpdev->sp[0][m++] = inb(base_io + 0x33); |
| 2708 | outw(n, base_io + 0x34); | 2711 | outw(n, base_io + 0x34); |
| 2709 | n += 0x0002; | 2712 | n += 0x0002; |
| 2710 | atp_dev.sp[0][m++] = inb(base_io + 0x30); | 2713 | atpdev->sp[0][m++] = inb(base_io + 0x30); |
| 2711 | atp_dev.sp[0][m++] = inb(base_io + 0x31); | 2714 | atpdev->sp[0][m++] = inb(base_io + 0x31); |
| 2712 | atp_dev.sp[0][m++] = inb(base_io + 0x32); | 2715 | atpdev->sp[0][m++] = inb(base_io + 0x32); |
| 2713 | atp_dev.sp[0][m++] = inb(base_io + 0x33); | 2716 | atpdev->sp[0][m++] = inb(base_io + 0x33); |
| 2714 | outw(n, base_io + 0x34); | 2717 | outw(n, base_io + 0x34); |
| 2715 | n += 0x0002; | 2718 | n += 0x0002; |
| 2716 | atp_dev.sp[0][m++] = inb(base_io + 0x30); | 2719 | atpdev->sp[0][m++] = inb(base_io + 0x30); |
| 2717 | atp_dev.sp[0][m++] = inb(base_io + 0x31); | 2720 | atpdev->sp[0][m++] = inb(base_io + 0x31); |
| 2718 | atp_dev.sp[0][m++] = inb(base_io + 0x32); | 2721 | atpdev->sp[0][m++] = inb(base_io + 0x32); |
| 2719 | atp_dev.sp[0][m++] = inb(base_io + 0x33); | 2722 | atpdev->sp[0][m++] = inb(base_io + 0x33); |
| 2720 | n += 0x0018; | 2723 | n += 0x0018; |
| 2721 | goto next_fblk_880; | 2724 | goto next_fblk_880; |
| 2722 | flash_ok_880: | 2725 | flash_ok_880: |
| 2723 | outw(0, base_io + 0x34); | 2726 | outw(0, base_io + 0x34); |
| 2724 | atp_dev.ultra_map[0] = 0; | 2727 | atpdev->ultra_map[0] = 0; |
| 2725 | atp_dev.async[0] = 0; | 2728 | atpdev->async[0] = 0; |
| 2726 | for (k = 0; k < 16; k++) { | 2729 | for (k = 0; k < 16; k++) { |
| 2727 | n = 1; | 2730 | n = 1; |
| 2728 | n = n << k; | 2731 | n = n << k; |
| 2729 | if (atp_dev.sp[0][k] > 1) { | 2732 | if (atpdev->sp[0][k] > 1) { |
| 2730 | atp_dev.ultra_map[0] |= n; | 2733 | atpdev->ultra_map[0] |= n; |
| 2731 | } else { | 2734 | } else { |
| 2732 | if (atp_dev.sp[0][k] == 0) | 2735 | if (atpdev->sp[0][k] == 0) |
| 2733 | atp_dev.async[0] |= n; | 2736 | atpdev->async[0] |= n; |
| 2734 | } | 2737 | } |
| 2735 | } | 2738 | } |
| 2736 | atp_dev.async[0] = ~(atp_dev.async[0]); | 2739 | atpdev->async[0] = ~(atpdev->async[0]); |
| 2737 | outb(atp_dev.global_map[0], base_io + 0x35); | 2740 | outb(atpdev->global_map[0], base_io + 0x35); |
| 2738 | 2741 | ||
| 2739 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); | 2742 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); |
| 2740 | if (!shpnt) | 2743 | if (!shpnt) |
| 2741 | return -ENOMEM; | 2744 | goto err_nomem; |
| 2742 | 2745 | ||
| 2743 | p = (struct atp_unit *)&shpnt->hostdata; | 2746 | p = (struct atp_unit *)&shpnt->hostdata; |
| 2744 | 2747 | ||
| 2745 | atp_dev.host = shpnt; | 2748 | atpdev->host = shpnt; |
| 2746 | atp_dev.pdev = pdev; | 2749 | atpdev->pdev = pdev; |
| 2747 | pci_set_drvdata(pdev, p); | 2750 | pci_set_drvdata(pdev, p); |
| 2748 | memcpy(p, &atp_dev, sizeof atp_dev); | 2751 | memcpy(p, atpdev, sizeof(*atpdev)); |
| 2749 | if (atp870u_init_tables(shpnt) < 0) { | 2752 | if (atp870u_init_tables(shpnt) < 0) { |
| 2750 | printk(KERN_ERR "Unable to allocate tables for Acard controller\n"); | 2753 | printk(KERN_ERR "Unable to allocate tables for Acard controller\n"); |
| 2751 | goto unregister; | 2754 | goto unregister; |
| @@ -2798,24 +2801,24 @@ flash_ok_880: | |||
| 2798 | printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%x, IRQ:%d.\n" | 2801 | printk(KERN_INFO " ACARD AEC-67162 PCI Ultra3 LVD Host Adapter: IO:%x, IRQ:%d.\n" |
| 2799 | , base_io, pdev->irq); | 2802 | , base_io, pdev->irq); |
| 2800 | 2803 | ||
| 2801 | atp_dev.pdev = pdev; | 2804 | atpdev->pdev = pdev; |
| 2802 | atp_dev.dev_id = ent->device; | 2805 | atpdev->dev_id = ent->device; |
| 2803 | atp_dev.baseport = base_io; | 2806 | atpdev->baseport = base_io; |
| 2804 | atp_dev.ioport[0] = base_io + 0x80; | 2807 | atpdev->ioport[0] = base_io + 0x80; |
| 2805 | atp_dev.ioport[1] = base_io + 0xc0; | 2808 | atpdev->ioport[1] = base_io + 0xc0; |
| 2806 | atp_dev.pciport[0] = base_io + 0x40; | 2809 | atpdev->pciport[0] = base_io + 0x40; |
| 2807 | atp_dev.pciport[1] = base_io + 0x50; | 2810 | atpdev->pciport[1] = base_io + 0x50; |
| 2808 | 2811 | ||
| 2809 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); | 2812 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); |
| 2810 | if (!shpnt) | 2813 | if (!shpnt) |
| 2811 | return -ENOMEM; | 2814 | goto err_nomem; |
| 2812 | 2815 | ||
| 2813 | p = (struct atp_unit *)&shpnt->hostdata; | 2816 | p = (struct atp_unit *)&shpnt->hostdata; |
| 2814 | 2817 | ||
| 2815 | atp_dev.host = shpnt; | 2818 | atpdev->host = shpnt; |
| 2816 | atp_dev.pdev = pdev; | 2819 | atpdev->pdev = pdev; |
| 2817 | pci_set_drvdata(pdev, p); | 2820 | pci_set_drvdata(pdev, p); |
| 2818 | memcpy(p, &atp_dev, sizeof(struct atp_unit)); | 2821 | memcpy(p, atpdev, sizeof(struct atp_unit)); |
| 2819 | if (atp870u_init_tables(shpnt) < 0) | 2822 | if (atp870u_init_tables(shpnt) < 0) |
| 2820 | goto unregister; | 2823 | goto unregister; |
| 2821 | 2824 | ||
| @@ -2974,33 +2977,33 @@ flash_ok_885: | |||
| 2974 | printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: %d " | 2977 | printk(KERN_INFO " ACARD AEC-671X PCI Ultra/W SCSI-2/3 Host Adapter: %d " |
| 2975 | "IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); | 2978 | "IO:%x, IRQ:%d.\n", count, base_io, pdev->irq); |
| 2976 | 2979 | ||
| 2977 | atp_dev.ioport[0] = base_io; | 2980 | atpdev->ioport[0] = base_io; |
| 2978 | atp_dev.pciport[0] = base_io + 0x20; | 2981 | atpdev->pciport[0] = base_io + 0x20; |
| 2979 | atp_dev.dev_id = ent->device; | 2982 | atpdev->dev_id = ent->device; |
| 2980 | host_id &= 0x07; | 2983 | host_id &= 0x07; |
| 2981 | atp_dev.host_id[0] = host_id; | 2984 | atpdev->host_id[0] = host_id; |
| 2982 | tmport = base_io + 0x22; | 2985 | tmport = base_io + 0x22; |
| 2983 | atp_dev.scam_on = inb(tmport); | 2986 | atpdev->scam_on = inb(tmport); |
| 2984 | tmport += 0x0b; | 2987 | tmport += 0x0b; |
| 2985 | atp_dev.global_map[0] = inb(tmport++); | 2988 | atpdev->global_map[0] = inb(tmport++); |
| 2986 | atp_dev.ultra_map[0] = inw(tmport); | 2989 | atpdev->ultra_map[0] = inw(tmport); |
| 2987 | 2990 | ||
| 2988 | if (atp_dev.ultra_map[0] == 0) { | 2991 | if (atpdev->ultra_map[0] == 0) { |
| 2989 | atp_dev.scam_on = 0x00; | 2992 | atpdev->scam_on = 0x00; |
| 2990 | atp_dev.global_map[0] = 0x20; | 2993 | atpdev->global_map[0] = 0x20; |
| 2991 | atp_dev.ultra_map[0] = 0xffff; | 2994 | atpdev->ultra_map[0] = 0xffff; |
| 2992 | } | 2995 | } |
| 2993 | 2996 | ||
| 2994 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); | 2997 | shpnt = scsi_host_alloc(&atp870u_template, sizeof(struct atp_unit)); |
| 2995 | if (!shpnt) | 2998 | if (!shpnt) |
| 2996 | return -ENOMEM; | 2999 | goto err_nomem; |
| 2997 | 3000 | ||
| 2998 | p = (struct atp_unit *)&shpnt->hostdata; | 3001 | p = (struct atp_unit *)&shpnt->hostdata; |
| 2999 | 3002 | ||
| 3000 | atp_dev.host = shpnt; | 3003 | atpdev->host = shpnt; |
| 3001 | atp_dev.pdev = pdev; | 3004 | atpdev->pdev = pdev; |
| 3002 | pci_set_drvdata(pdev, p); | 3005 | pci_set_drvdata(pdev, p); |
| 3003 | memcpy(p, &atp_dev, sizeof atp_dev); | 3006 | memcpy(p, atpdev, sizeof(*atpdev)); |
| 3004 | if (atp870u_init_tables(shpnt) < 0) | 3007 | if (atp870u_init_tables(shpnt) < 0) |
| 3005 | goto unregister; | 3008 | goto unregister; |
| 3006 | 3009 | ||
| @@ -3010,7 +3013,7 @@ flash_ok_885: | |||
| 3010 | } | 3013 | } |
| 3011 | 3014 | ||
| 3012 | spin_lock_irqsave(shpnt->host_lock, flags); | 3015 | spin_lock_irqsave(shpnt->host_lock, flags); |
| 3013 | if (atp_dev.chip_ver > 0x07) { /* check if atp876 chip then enable terminator */ | 3016 | if (atpdev->chip_ver > 0x07) { /* check if atp876 chip then enable terminator */ |
| 3014 | tmport = base_io + 0x3e; | 3017 | tmport = base_io + 0x3e; |
| 3015 | outb(0x00, tmport); | 3018 | outb(0x00, tmport); |
| 3016 | } | 3019 | } |
| @@ -3044,7 +3047,7 @@ flash_ok_885: | |||
| 3044 | outb((inb(tmport) & 0xef), tmport); | 3047 | outb((inb(tmport) & 0xef), tmport); |
| 3045 | tmport++; | 3048 | tmport++; |
| 3046 | outb((inb(tmport) | 0x20), tmport); | 3049 | outb((inb(tmport) | 0x20), tmport); |
| 3047 | if (atp_dev.chip_ver == 4) | 3050 | if (atpdev->chip_ver == 4) |
| 3048 | shpnt->max_id = 16; | 3051 | shpnt->max_id = 16; |
| 3049 | else | 3052 | else |
| 3050 | shpnt->max_id = 8; | 3053 | shpnt->max_id = 8; |
| @@ -3093,6 +3096,12 @@ unregister: | |||
| 3093 | printk("atp870u_prob:unregister\n"); | 3096 | printk("atp870u_prob:unregister\n"); |
| 3094 | scsi_host_put(shpnt); | 3097 | scsi_host_put(shpnt); |
| 3095 | return -1; | 3098 | return -1; |
| 3099 | err_eio: | ||
| 3100 | kfree(atpdev); | ||
| 3101 | return -EIO; | ||
| 3102 | err_nomem: | ||
| 3103 | kfree(atpdev); | ||
| 3104 | return -ENOMEM; | ||
| 3096 | } | 3105 | } |
| 3097 | 3106 | ||
| 3098 | /* The abort command does not leave the device in a clean state where | 3107 | /* The abort command does not leave the device in a clean state where |
