ncr53c8xx.c
来自「linux 内核源代码」· C语言 代码 · 共 2,376 行 · 第 1/5 页
C
2,376 行
return m;}static void __m_free_dma(m_bush_t bush, void *m, int size, char *name){ u_long flags; struct m_pool *mp; spin_lock_irqsave(&ncr53c8xx_lock, flags); mp = ___get_dma_pool(bush); if (mp) __m_free(mp, m, size, name); if (mp && !mp->nump) ___del_dma_pool(mp); spin_unlock_irqrestore(&ncr53c8xx_lock, flags);}static m_addr_t __vtobus(m_bush_t bush, void *m){ u_long flags; m_pool_s *mp; int hc = VTOB_HASH_CODE(m); m_vtob_s *vp = NULL; m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK; spin_lock_irqsave(&ncr53c8xx_lock, flags); mp = ___get_dma_pool(bush); if (mp) { vp = mp->vtob[hc]; while (vp && (m_addr_t) vp->vaddr != a) vp = vp->next; } spin_unlock_irqrestore(&ncr53c8xx_lock, flags); return vp ? vp->baddr + (((m_addr_t) m) - a) : 0;}#define _m_calloc_dma(np, s, n) __m_calloc_dma(np->dev, s, n)#define _m_free_dma(np, p, s, n) __m_free_dma(np->dev, p, s, n)#define m_calloc_dma(s, n) _m_calloc_dma(np, s, n)#define m_free_dma(p, s, n) _m_free_dma(np, p, s, n)#define _vtobus(np, p) __vtobus(np->dev, p)#define vtobus(p) _vtobus(np, p)/* * Deal with DMA mapping/unmapping. *//* To keep track of the dma mapping (sg/single) that has been set */#define __data_mapped SCp.phase#define __data_mapping SCp.have_data_instatic void __unmap_scsi_data(struct device *dev, struct scsi_cmnd *cmd){ switch(cmd->__data_mapped) { case 2: scsi_dma_unmap(cmd); break; } cmd->__data_mapped = 0;}static int __map_scsi_sg_data(struct device *dev, struct scsi_cmnd *cmd){ int use_sg; use_sg = scsi_dma_map(cmd); if (!use_sg) return 0; cmd->__data_mapped = 2; cmd->__data_mapping = use_sg; return use_sg;}#define unmap_scsi_data(np, cmd) __unmap_scsi_data(np->dev, cmd)#define map_scsi_sg_data(np, cmd) __map_scsi_sg_data(np->dev, cmd)/*==========================================================**** Driver setup.**** This structure is initialized from linux config ** options. It can be overridden at boot-up by the boot ** command line.****==========================================================*/static struct ncr_driver_setup driver_setup = SCSI_NCR_DRIVER_SETUP;#ifndef MODULE#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORTstatic struct ncr_driver_setup driver_safe_setup __initdata = SCSI_NCR_DRIVER_SAFE_SETUP;#endif#endif /* !MODULE */#define initverbose (driver_setup.verbose)#define bootverbose (np->verbose)/*===================================================================**** Driver setup from the boot command line****===================================================================*/#ifdef MODULE#define ARG_SEP ' '#else#define ARG_SEP ','#endif#define OPT_TAGS 1#define OPT_MASTER_PARITY 2#define OPT_SCSI_PARITY 3#define OPT_DISCONNECTION 4#define OPT_SPECIAL_FEATURES 5#define OPT_UNUSED_1 6#define OPT_FORCE_SYNC_NEGO 7#define OPT_REVERSE_PROBE 8#define OPT_DEFAULT_SYNC 9#define OPT_VERBOSE 10#define OPT_DEBUG 11#define OPT_BURST_MAX 12#define OPT_LED_PIN 13#define OPT_MAX_WIDE 14#define OPT_SETTLE_DELAY 15#define OPT_DIFF_SUPPORT 16#define OPT_IRQM 17#define OPT_PCI_FIX_UP 18#define OPT_BUS_CHECK 19#define OPT_OPTIMIZE 20#define OPT_RECOVERY 21#define OPT_SAFE_SETUP 22#define OPT_USE_NVRAM 23#define OPT_EXCLUDE 24#define OPT_HOST_ID 25#ifdef SCSI_NCR_IARB_SUPPORT#define OPT_IARB 26#endif#ifdef MODULE#define ARG_SEP ' '#else#define ARG_SEP ','#endif#ifndef MODULEstatic char setup_token[] __initdata = "tags:" "mpar:" "spar:" "disc:" "specf:" "ultra:" "fsn:" "revprob:" "sync:" "verb:" "debug:" "burst:" "led:" "wide:" "settle:" "diff:" "irqm:" "pcifix:" "buschk:" "optim:" "recovery:" "safe:" "nvram:" "excl:" "hostid:"#ifdef SCSI_NCR_IARB_SUPPORT "iarb:"#endif ; /* DONNOT REMOVE THIS ';' */static int __init get_setup_token(char *p){ char *cur = setup_token; char *pc; int i = 0; while (cur != NULL && (pc = strchr(cur, ':')) != NULL) { ++pc; ++i; if (!strncmp(p, cur, pc - cur)) return i; cur = pc; } return 0;}static int __init sym53c8xx__setup(char *str){#ifdef SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT char *cur = str; char *pc, *pv; int i, val, c; int xi = 0; while (cur != NULL && (pc = strchr(cur, ':')) != NULL) { char *pe; val = 0; pv = pc; c = *++pv; if (c == 'n') val = 0; else if (c == 'y') val = 1; else val = (int) simple_strtoul(pv, &pe, 0); switch (get_setup_token(cur)) { case OPT_TAGS: driver_setup.default_tags = val; if (pe && *pe == '/') { i = 0; while (*pe && *pe != ARG_SEP && i < sizeof(driver_setup.tag_ctrl)-1) { driver_setup.tag_ctrl[i++] = *pe++; } driver_setup.tag_ctrl[i] = '\0'; } break; case OPT_MASTER_PARITY: driver_setup.master_parity = val; break; case OPT_SCSI_PARITY: driver_setup.scsi_parity = val; break; case OPT_DISCONNECTION: driver_setup.disconnection = val; break; case OPT_SPECIAL_FEATURES: driver_setup.special_features = val; break; case OPT_FORCE_SYNC_NEGO: driver_setup.force_sync_nego = val; break; case OPT_REVERSE_PROBE: driver_setup.reverse_probe = val; break; case OPT_DEFAULT_SYNC: driver_setup.default_sync = val; break; case OPT_VERBOSE: driver_setup.verbose = val; break; case OPT_DEBUG: driver_setup.debug = val; break; case OPT_BURST_MAX: driver_setup.burst_max = val; break; case OPT_LED_PIN: driver_setup.led_pin = val; break; case OPT_MAX_WIDE: driver_setup.max_wide = val? 1:0; break; case OPT_SETTLE_DELAY: driver_setup.settle_delay = val; break; case OPT_DIFF_SUPPORT: driver_setup.diff_support = val; break; case OPT_IRQM: driver_setup.irqm = val; break; case OPT_PCI_FIX_UP: driver_setup.pci_fix_up = val; break; case OPT_BUS_CHECK: driver_setup.bus_check = val; break; case OPT_OPTIMIZE: driver_setup.optimize = val; break; case OPT_RECOVERY: driver_setup.recovery = val; break; case OPT_USE_NVRAM: driver_setup.use_nvram = val; break; case OPT_SAFE_SETUP: memcpy(&driver_setup, &driver_safe_setup, sizeof(driver_setup)); break; case OPT_EXCLUDE: if (xi < SCSI_NCR_MAX_EXCLUDES) driver_setup.excludes[xi++] = val; break; case OPT_HOST_ID: driver_setup.host_id = val; break;#ifdef SCSI_NCR_IARB_SUPPORT case OPT_IARB: driver_setup.iarb = val; break;#endif default: printk("sym53c8xx_setup: unexpected boot option '%.*s' ignored\n", (int)(pc-cur+1), cur); break; } if ((cur = strchr(cur, ARG_SEP)) != NULL) ++cur; }#endif /* SCSI_NCR_BOOT_COMMAND_LINE_SUPPORT */ return 1;}#endif /* !MODULE *//*===================================================================**** Get device queue depth from boot command line.****===================================================================*/#define DEF_DEPTH (driver_setup.default_tags)#define ALL_TARGETS -2#define NO_TARGET -1#define ALL_LUNS -2#define NO_LUN -1static int device_queue_depth(int unit, int target, int lun){ int c, h, t, u, v; char *p = driver_setup.tag_ctrl; char *ep; h = -1; t = NO_TARGET; u = NO_LUN; while ((c = *p++) != 0) { v = simple_strtoul(p, &ep, 0); switch(c) { case '/': ++h; t = ALL_TARGETS; u = ALL_LUNS; break; case 't': if (t != target) t = (target == v) ? v : NO_TARGET; u = ALL_LUNS; break; case 'u': if (u != lun) u = (lun == v) ? v : NO_LUN; break; case 'q': if (h == unit && (t == ALL_TARGETS || t == target) && (u == ALL_LUNS || u == lun)) return v; break; case '-': t = ALL_TARGETS; u = ALL_LUNS; break; default: break; } p = ep; } return DEF_DEPTH;}/*==========================================================**** The CCB done queue uses an array of CCB virtual ** addresses. Empty entries are flagged using the bogus ** virtual address 0xffffffff.**** Since PCI ensures that only aligned DWORDs are accessed ** atomically, 64 bit little-endian architecture requires ** to test the high order DWORD of the entry to determine ** if it is empty or valid.**** BTW, I will make things differently as soon as I will ** have a better idea, but this is simple and should work.****==========================================================*/ #define SCSI_NCR_CCB_DONE_SUPPORT#ifdef SCSI_NCR_CCB_DONE_SUPPORT#define MAX_DONE 24#define CCB_DONE_EMPTY 0xffffffffUL/* All 32 bit architectures */#if BITS_PER_LONG == 32#define CCB_DONE_VALID(cp) (((u_long) cp) != CCB_DONE_EMPTY)/* All > 32 bit (64 bit) architectures regardless endian-ness */#else#define CCB_DONE_VALID(cp) \ ((((u_long) cp) & 0xffffffff00000000ul) && \ (((u_long) cp) & 0xfffffffful) != CCB_DONE_EMPTY)#endif#endif /* SCSI_NCR_CCB_DONE_SUPPORT *//*==========================================================**** Configuration and Debugging****==========================================================*//*** SCSI address of this device.** The boot routines should have set it.** If not, use this.*/#ifndef SCSI_NCR_MYADDR#define SCSI_NCR_MYADDR (7)#endif/*** The maximum number of tags per logic unit.** Used only for disk devices that support tags.*/#ifndef SCSI_NCR_MAX_TAGS#define SCSI_NCR_MAX_TAGS (8)#endif/*** TAGS are actually limited to 64 tags/lun.** We need to deal with power of 2, for alignment constraints.*/#if SCSI_NCR_MAX_TAGS > 64#define MAX_TAGS (64)#else#define MAX_TAGS SCSI_NCR_MAX_TAGS#endif#define NO_TAG (255)/*** Choose appropriate type for tag bitmap.*/#if MAX_TAGS > 32typedef u64 tagmap_t;#elsetypedef u32 tagmap_t;#endif/*** Number of targets supported by the driver.** n permits target numbers 0..n-1.** Default is 16, meaning targets #0..#15.** #7 .. is myself.*/#ifdef SCSI_NCR_MAX_TARGET#define MAX_TARGET (SCSI_NCR_MAX_TARGET)#else#define MAX_TARGET (16)#endif/*** Number of logic units supported by the driver.** n enables logic unit numbers 0..n-1.** The common SCSI devices require only** one lun, so take 1 as the default.*/#ifdef SCSI_NCR_MAX_LUN#define MAX_LUN SCSI_NCR_MAX_LUN#else#define MAX_LUN (1)#endif
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?