diff options
author | Ondrej Zary <linux@rainbow-software.org> | 2015-02-06 17:11:40 -0500 |
---|---|---|
committer | James Bottomley <JBottomley@Odin.com> | 2015-04-09 21:08:00 -0400 |
commit | 3a70c006edbe6071bd78e1e0c8004791cd4b531c (patch) | |
tree | afedc0e46453ffdc5861156f5c06859495065c8e | |
parent | 23e6940a9ecfc6477fb1216cad062e2fa12ea98f (diff) |
aha1542: rework hw_init
Cleanup hw_init, use goto for error handling.
Signed-off-by: Ondrej Zary <linux@rainbow-software.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: James Bottomley <JBottomley@Odin.com>
-rw-r--r-- | drivers/scsi/aha1542.c | 139 | ||||
-rw-r--r-- | drivers/scsi/aha1542.h | 1 |
2 files changed, 59 insertions, 81 deletions
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c index 4849d02661d8..8c915d721ce0 100644 --- a/drivers/scsi/aha1542.c +++ b/drivers/scsi/aha1542.c | |||
@@ -657,7 +657,7 @@ static void setup_mailboxes(int bse, struct Scsi_Host *shpnt) | |||
657 | aha1542_intr_reset(bse); | 657 | aha1542_intr_reset(bse); |
658 | } | 658 | } |
659 | 659 | ||
660 | static int aha1542_getconfig(int base_io, unsigned char *irq_level, unsigned char *dma_chan, unsigned char *scsi_id) | 660 | static int aha1542_getconfig(int base_io, unsigned int *irq_level, unsigned char *dma_chan, unsigned int *scsi_id) |
661 | { | 661 | { |
662 | u8 inquiry_result[3]; | 662 | u8 inquiry_result[3]; |
663 | int i; | 663 | int i; |
@@ -901,99 +901,76 @@ fail: | |||
901 | /* return non-zero on detection */ | 901 | /* return non-zero on detection */ |
902 | static struct Scsi_Host *aha1542_hw_init(struct scsi_host_template *tpnt, struct device *pdev, int indx) | 902 | static struct Scsi_Host *aha1542_hw_init(struct scsi_host_template *tpnt, struct device *pdev, int indx) |
903 | { | 903 | { |
904 | unsigned char dma_chan; | 904 | unsigned int base_io = bases[indx]; |
905 | unsigned char irq_level; | 905 | struct Scsi_Host *shpnt; |
906 | unsigned char scsi_id; | ||
907 | unsigned long flags; | ||
908 | unsigned int base_io; | ||
909 | int trans; | ||
910 | struct Scsi_Host *shpnt = NULL; | ||
911 | struct aha1542_hostdata *aha1542; | 906 | struct aha1542_hostdata *aha1542; |
912 | 907 | ||
913 | DEB(printk("aha1542_detect: \n")); | 908 | if (base_io == 0) |
914 | 909 | return NULL; | |
915 | tpnt->proc_name = "aha1542"; | ||
916 | |||
917 | if (bases[indx] != 0 && request_region(bases[indx], 4, "aha1542")) { | ||
918 | shpnt = scsi_host_alloc(tpnt, | ||
919 | sizeof(struct aha1542_hostdata)); | ||
920 | |||
921 | if(shpnt==NULL) { | ||
922 | release_region(bases[indx], 4); | ||
923 | return NULL; | ||
924 | } | ||
925 | aha1542 = shost_priv(shpnt); | ||
926 | if (!aha1542_test_port(bases[indx], shpnt)) | ||
927 | goto unregister; | ||
928 | 910 | ||
929 | base_io = bases[indx]; | 911 | if (!request_region(base_io, AHA1542_REGION_SIZE, "aha1542")) |
912 | return NULL; | ||
930 | 913 | ||
931 | aha1542_set_bus_times(indx); | 914 | shpnt = scsi_host_alloc(tpnt, sizeof(struct aha1542_hostdata)); |
915 | if (!shpnt) | ||
916 | goto release; | ||
917 | aha1542 = shost_priv(shpnt); | ||
932 | 918 | ||
933 | if (aha1542_query(base_io, &trans)) | 919 | if (!aha1542_test_port(base_io, shpnt)) |
934 | goto unregister; | 920 | goto unregister; |
935 | 921 | ||
936 | if (aha1542_getconfig(base_io, &irq_level, &dma_chan, &scsi_id) == -1) | 922 | aha1542_set_bus_times(indx); |
937 | goto unregister; | 923 | if (aha1542_query(base_io, &aha1542->bios_translation)) |
924 | goto unregister; | ||
925 | if (aha1542_getconfig(base_io, &shpnt->irq, &shpnt->dma_channel, &shpnt->this_id) == -1) | ||
926 | goto unregister; | ||
938 | 927 | ||
939 | printk(KERN_INFO "Configuring Adaptec (SCSI-ID %d) at IO:%x, IRQ %d", scsi_id, base_io, irq_level); | 928 | printk(KERN_INFO "Adaptec AHA-1542 (SCSI-ID %d) at IO 0x%x, IRQ %d", shpnt->this_id, base_io, shpnt->irq); |
940 | if (dma_chan != 0xFF) | 929 | if (shpnt->dma_channel != 0xFF) |
941 | printk(", DMA priority %d", dma_chan); | 930 | printk(", DMA %d", shpnt->dma_channel); |
942 | printk("\n"); | 931 | printk("\n"); |
932 | if (aha1542->bios_translation == BIOS_TRANSLATION_25563) | ||
933 | printk(KERN_INFO "aha1542.c: Using extended bios translation\n"); | ||
943 | 934 | ||
944 | setup_mailboxes(base_io, shpnt); | 935 | setup_mailboxes(base_io, shpnt); |
945 | 936 | ||
946 | DEB(printk("aha1542_detect: enable interrupt channel %d\n", irq_level)); | 937 | if (request_irq(shpnt->irq, do_aha1542_intr_handle, 0, |
947 | spin_lock_irqsave(&aha1542_lock, flags); | ||
948 | if (request_irq(irq_level, do_aha1542_intr_handle, 0, | ||
949 | "aha1542", shpnt)) { | 938 | "aha1542", shpnt)) { |
950 | printk(KERN_ERR "Unable to allocate IRQ for adaptec controller.\n"); | 939 | printk(KERN_ERR "Unable to allocate IRQ for adaptec controller.\n"); |
951 | spin_unlock_irqrestore(&aha1542_lock, flags); | 940 | goto unregister; |
952 | goto unregister; | 941 | } |
953 | } | 942 | if (shpnt->dma_channel != 0xFF) { |
954 | if (dma_chan != 0xFF) { | 943 | if (request_dma(shpnt->dma_channel, "aha1542")) { |
955 | if (request_dma(dma_chan, "aha1542")) { | 944 | printk(KERN_ERR "Unable to allocate DMA channel for Adaptec.\n"); |
956 | printk(KERN_ERR "Unable to allocate DMA channel for Adaptec.\n"); | 945 | goto free_irq; |
957 | free_irq(irq_level, shpnt); | 946 | } |
958 | spin_unlock_irqrestore(&aha1542_lock, flags); | 947 | if (shpnt->dma_channel == 0 || shpnt->dma_channel >= 5) { |
959 | goto unregister; | 948 | set_dma_mode(shpnt->dma_channel, DMA_MODE_CASCADE); |
960 | } | 949 | enable_dma(shpnt->dma_channel); |
961 | if (dma_chan == 0 || dma_chan >= 5) { | 950 | } |
962 | set_dma_mode(dma_chan, DMA_MODE_CASCADE); | 951 | } |
963 | enable_dma(dma_chan); | ||
964 | } | ||
965 | } | ||
966 | 952 | ||
967 | shpnt->this_id = scsi_id; | 953 | shpnt->unique_id = base_io; |
968 | shpnt->unique_id = base_io; | 954 | shpnt->io_port = base_io; |
969 | shpnt->io_port = base_io; | 955 | shpnt->n_io_port = AHA1542_REGION_SIZE; |
970 | shpnt->n_io_port = 4; /* Number of bytes of I/O space used */ | 956 | aha1542->aha1542_last_mbi_used = 2 * AHA1542_MAILBOXES - 1; |
971 | shpnt->dma_channel = dma_chan; | 957 | aha1542->aha1542_last_mbo_used = AHA1542_MAILBOXES - 1; |
972 | shpnt->irq = irq_level; | ||
973 | aha1542->bios_translation = trans; | ||
974 | if (trans == BIOS_TRANSLATION_25563) | ||
975 | printk(KERN_INFO "aha1542.c: Using extended bios translation\n"); | ||
976 | aha1542->aha1542_last_mbi_used = (2 * AHA1542_MAILBOXES - 1); | ||
977 | aha1542->aha1542_last_mbo_used = (AHA1542_MAILBOXES - 1); | ||
978 | memset(aha1542->SCint, 0, sizeof(aha1542->SCint)); | ||
979 | spin_unlock_irqrestore(&aha1542_lock, flags); | ||
980 | 958 | ||
981 | if (scsi_add_host(shpnt, pdev)) { | 959 | if (scsi_add_host(shpnt, pdev)) |
982 | if (shpnt->dma_channel != 0xff) | 960 | goto free_dma; |
983 | free_dma(shpnt->dma_channel); | ||
984 | free_irq(irq_level, shpnt); | ||
985 | goto unregister; | ||
986 | } | ||
987 | 961 | ||
988 | scsi_scan_host(shpnt); | 962 | scsi_scan_host(shpnt); |
989 | 963 | ||
990 | return shpnt; | 964 | return shpnt; |
965 | free_dma: | ||
966 | if (shpnt->dma_channel != 0xff) | ||
967 | free_dma(shpnt->dma_channel); | ||
968 | free_irq: | ||
969 | free_irq(shpnt->irq, shpnt); | ||
991 | unregister: | 970 | unregister: |
992 | release_region(bases[indx], 4); | 971 | scsi_host_put(shpnt); |
993 | scsi_host_put(shpnt); | 972 | release: |
994 | return NULL; | 973 | release_region(base_io, AHA1542_REGION_SIZE); |
995 | |||
996 | }; | ||
997 | 974 | ||
998 | return NULL; | 975 | return NULL; |
999 | } | 976 | } |
@@ -1001,10 +978,10 @@ unregister: | |||
1001 | static int aha1542_release(struct Scsi_Host *shost) | 978 | static int aha1542_release(struct Scsi_Host *shost) |
1002 | { | 979 | { |
1003 | scsi_remove_host(shost); | 980 | scsi_remove_host(shost); |
1004 | if (shost->irq) | ||
1005 | free_irq(shost->irq, shost); | ||
1006 | if (shost->dma_channel != 0xff) | 981 | if (shost->dma_channel != 0xff) |
1007 | free_dma(shost->dma_channel); | 982 | free_dma(shost->dma_channel); |
983 | if (shost->irq) | ||
984 | free_irq(shost->irq, shost); | ||
1008 | if (shost->io_port && shost->n_io_port) | 985 | if (shost->io_port && shost->n_io_port) |
1009 | release_region(shost->io_port, shost->n_io_port); | 986 | release_region(shost->io_port, shost->n_io_port); |
1010 | scsi_host_put(shost); | 987 | scsi_host_put(shost); |
diff --git a/drivers/scsi/aha1542.h b/drivers/scsi/aha1542.h index 1333a23c1e09..f58792b085a2 100644 --- a/drivers/scsi/aha1542.h +++ b/drivers/scsi/aha1542.h | |||
@@ -126,6 +126,7 @@ struct ccb { /* Command Control Block 5.3 */ | |||
126 | /* REQUEST SENSE */ | 126 | /* REQUEST SENSE */ |
127 | }; | 127 | }; |
128 | 128 | ||
129 | #define AHA1542_REGION_SIZE 4 | ||
129 | #define AHA1542_MAILBOXES 8 | 130 | #define AHA1542_MAILBOXES 8 |
130 | 131 | ||
131 | #endif | 132 | #endif |