?? mac_esp.c
字號:
/* * 68k mac 53c9[46] scsi driver * * copyright (c) 1998, David Weis weisd3458@uni.edu * * debugging on Quadra 800 and 660AV Michael Schmitz, Dave Kilzer 7/98 * * based loosely on cyber_esp.c *//* these are unused for now */#define myreadl(addr) (*(volatile unsigned int *) (addr))#define mywritel(b, addr) ((*(volatile unsigned int *) (addr)) = (b))#include <linux/kernel.h>#include <linux/delay.h>#include <linux/types.h>#include <linux/ctype.h>#include <linux/string.h>#include <linux/slab.h>#include <linux/blk.h>#include <linux/proc_fs.h>#include <linux/stat.h>#include <linux/init.h>#include "scsi.h"#include "hosts.h"#include "NCR53C9x.h"#include "mac_esp.h"#include <asm/io.h>#include <asm/setup.h>#include <asm/irq.h>#include <asm/macints.h>#include <asm/machw.h>#include <asm/mac_via.h>#include <asm/pgtable.h>#include <asm/macintosh.h>#define mac_turnon_irq(x) mac_enable_irq(x)#define mac_turnoff_irq(x) mac_disable_irq(x)extern inline void esp_handle(struct NCR_ESP *esp);extern void mac_esp_intr(int irq, void *dev_id, struct pt_regs *pregs);static int dma_bytes_sent(struct NCR_ESP * esp, int fifo_count);static int dma_can_transfer(struct NCR_ESP * esp, Scsi_Cmnd *sp);static void dma_dump_state(struct NCR_ESP * esp);static void dma_init_read(struct NCR_ESP * esp, char * vaddress, int length);static void dma_init_write(struct NCR_ESP * esp, char * vaddress, int length);static void dma_ints_off(struct NCR_ESP * esp);static void dma_ints_on(struct NCR_ESP * esp);static int dma_irq_p(struct NCR_ESP * esp);static int dma_irq_p_quick(struct NCR_ESP * esp);static void dma_led_off(struct NCR_ESP * esp);static void dma_led_on(struct NCR_ESP *esp);static int dma_ports_p(struct NCR_ESP *esp);static void dma_setup(struct NCR_ESP * esp, __u32 addr, int count, int write);static void dma_setup_quick(struct NCR_ESP * esp, __u32 addr, int count, int write);static int esp_dafb_dma_irq_p(struct NCR_ESP * espdev);static int esp_iosb_dma_irq_p(struct NCR_ESP * espdev);static volatile unsigned char cmd_buffer[16]; /* This is where all commands are put * before they are transferred to the ESP chip * via PIO. */static int esp_initialized = 0;static int setup_num_esps = -1;static int setup_disconnect = -1;static int setup_nosync = -1;static int setup_can_queue = -1;static int setup_cmd_per_lun = -1;static int setup_sg_tablesize = -1;#ifdef SUPPORT_TAGSstatic int setup_use_tagged_queuing = -1;#endifstatic int setup_hostid = -1;/* * Experimental ESP inthandler; check macints.c to make sure dev_id is * set up properly! */void mac_esp_intr(int irq, void *dev_id, struct pt_regs *pregs){ struct NCR_ESP *esp = (struct NCR_ESP *) dev_id; int irq_p = 0; /* Handle the one ESP interrupt showing at this IRQ level. */ if(((esp)->irq & 0xff) == irq) { /* * Debug .. */ irq_p = esp->dma_irq_p(esp); printk("mac_esp: irq_p %x current %p disconnected %p\n", irq_p, esp->current_SC, esp->disconnected_SC); /* * Mac: if we're here, it's an ESP interrupt for sure! */ if((esp->current_SC || esp->disconnected_SC)) { esp->dma_ints_off(esp); ESPIRQ(("I%d(", esp->esp_id)); esp_handle(esp); ESPIRQ((")")); esp->dma_ints_on(esp); } }}/* * Debug hooks; use for playing with the interrupt flag testing and interrupt * acknowledge on the various machines */void scsi_esp_polled(int irq, void *dev_id, struct pt_regs *pregs){ if (esp_initialized == 0) return; mac_esp_intr(irq, dev_id, pregs);}void fake_intr(int irq, void *dev_id, struct pt_regs *pregs){#ifdef DEBUG_MAC_ESP printk("mac_esp: got irq\n");#endif mac_esp_intr(irq, dev_id, pregs);}void fake_drq(int irq, void *dev_id, struct pt_regs *pregs){ printk("mac_esp: got drq\n");}#define DRIVER_SETUP/* * Function : mac_esp_setup(char *str, int *ints) * * Purpose : booter command line initialization of the overrides array, * * Inputs : str - unused, ints - array of integer parameters with ints[0] * equal to the number of ints. * * Currently unused in the new driver; need to add settable parameters to the * detect function. * */static int __init mac_esp_setup(char *str, int *ints) {#ifdef DRIVER_SETUP /* Format of mac53c9x parameter is: * mac53c9x=<num_esps>,<disconnect>,<nosync>,<can_queue>,<cmd_per_lun>,<sg_tablesize>,<hostid>,<use_tags> * Negative values mean don't change. */ /* Grmbl... the standard parameter parsing can't handle negative numbers * :-( So let's do it ourselves! */ int i = ints[0]+1, fact; while( str && (isdigit(*str) || *str == '-') && i <= 10) { if (*str == '-') fact = -1, ++str; else fact = 1; ints[i++] = simple_strtoul( str, NULL, 0 ) * fact; if ((str = strchr( str, ',' )) != NULL) ++str; } ints[0] = i-1; if (ints[0] < 1) { printk( "mac_esp_setup: no arguments!\n" ); return 0; } if (ints[0] >= 1) { if (ints[1] > 0) /* no limits on this, just > 0 */ if (ints[1] >= 0 && ints[1] <= 2) setup_num_esps = ints[1]; else if (ints[1] > 2) printk( "mac_esp_setup: invalid number of hosts %d !\n", ints[1] ); } if (ints[0] >= 2) { if (ints[2] > 0) setup_disconnect = ints[2]; } if (ints[0] >= 3) { if (ints[3] >= 0) { setup_nosync = ints[3]; } } if (ints[0] >= 4) { if (ints[4] > 0) /* no limits on this, just > 0 */ setup_can_queue = ints[4]; } if (ints[0] >= 5) { if (ints[5] > 0) setup_cmd_per_lun = ints[5]; } if (ints[0] >= 6) { if (ints[6] >= 0) { setup_sg_tablesize = ints[6]; /* Must be <= SG_ALL (255) */ if (setup_sg_tablesize > SG_ALL) setup_sg_tablesize = SG_ALL; } } if (ints[0] >= 7) { /* Must be between 0 and 7 */ if (ints[7] >= 0 && ints[7] <= 7) setup_hostid = ints[7]; else if (ints[7] > 7) printk( "mac_esp_setup: invalid host ID %d !\n", ints[7] ); }#ifdef SUPPORT_TAGS if (ints[0] >= 8) { if (ints[8] >= 0) setup_use_tagged_queuing = !!ints[8]; }#endif#endif return 1; }__setup("mac53c9x=", mac_esp_setup);/* * ESP address 'detection' */unsigned long get_base(int chip_num){ /* * using the chip_num and mac model, figure out where the * chips are mapped */ unsigned long io_base = 0x50f00000; unsigned int second_offset = 0x402; unsigned long scsi_loc = 0; switch (macintosh_config->scsi_type) { /* 950, 900, 700 */ case MAC_SCSI_QUADRA2: scsi_loc = io_base + 0xf000 + ((chip_num == 0) ? 0 : second_offset); break; /* av's */ case MAC_SCSI_QUADRA3: scsi_loc = io_base + 0x18000 + ((chip_num == 0) ? 0 : second_offset); break; /* most quadra/centris models are like this */ case MAC_SCSI_QUADRA: scsi_loc = io_base + 0x10000; break; default: printk("mac_esp: get_base: hit default!\n"); scsi_loc = io_base + 0x10000; break; } /* switch */ printk("mac_esp: io base at 0x%lx\n", scsi_loc); return scsi_loc;}/* * Model dependent ESP setup */int mac_esp_detect(Scsi_Host_Template * tpnt){ int quick = 0; int chipnum, chipspresent = 0;#if 0 unsigned long timeout;#endif if (esp_initialized > 0) return -ENODEV; /* what do we have in this machine... */ if (MACHW_PRESENT(MAC_SCSI_96)) { chipspresent ++; } if (MACHW_PRESENT(MAC_SCSI_96_2)) { chipspresent ++; } /* number of ESPs present ? */ if (setup_num_esps >= 0) { if (chipspresent >= setup_num_esps) chipspresent = setup_num_esps; else printk("mac_esp_detect: num_hosts detected %d setup %d \n", chipspresent, setup_num_esps); } /* TODO: add disconnect / nosync flags */ /* setup variables */ tpnt->can_queue = (setup_can_queue > 0) ? setup_can_queue : 7; tpnt->cmd_per_lun = (setup_cmd_per_lun > 0) ? setup_cmd_per_lun : 1; tpnt->sg_tablesize = (setup_sg_tablesize >= 0) ? setup_sg_tablesize : SG_ALL; if (setup_hostid >= 0) tpnt->this_id = setup_hostid; else { /* use 7 as default */ tpnt->this_id = 7; }#ifdef SUPPORT_TAGS if (setup_use_tagged_queuing < 0) setup_use_tagged_queuing = DEFAULT_USE_TAGGED_QUEUING;#endif for (chipnum = 0; chipnum < chipspresent; chipnum ++) { struct NCR_ESP * esp; esp = esp_allocate(tpnt, (void *) NULL); esp->eregs = (struct ESP_regs *) get_base(chipnum); esp->dma_irq_p = &esp_dafb_dma_irq_p; if (chipnum == 0) { if (macintosh_config->scsi_type == MAC_SCSI_QUADRA) { /* most machines except those below :-) */ quick = 1; esp->dma_irq_p = &esp_iosb_dma_irq_p; } else if (macintosh_config->scsi_type == MAC_SCSI_QUADRA3) { /* mostly av's */
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -