⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sym53c8xx.c

📁 讲述linux的初始化过程
💻 C
📖 第 1 页 / 共 5 页
字号:
{	FreePages(m);	--mp->nump;}static m_pool_s mp0 = {0, ___mp0_getp, ___mp0_freep};#endif	/* SCSI_NCR_DYNAMIC_DMA_MAPPING */static void *m_calloc(int size, char *name){	u_long flags;	void *m;	NCR_LOCK_DRIVER(flags);	m = __m_calloc(&mp0, size, name);	NCR_UNLOCK_DRIVER(flags);	return m;}static void m_free(void *ptr, int size, char *name){	u_long flags;	NCR_LOCK_DRIVER(flags);	__m_free(&mp0, ptr, size, name);	NCR_UNLOCK_DRIVER(flags);}/* * DMAable pools. */#ifndef	SCSI_NCR_DYNAMIC_DMA_MAPPING/* Without pci bus iommu support, all the memory is assumed DMAable */#define __m_calloc_dma(b, s, n)		m_calloc(s, n)#define __m_free_dma(b, p, s, n)	m_free(p, s, n)#define __vtobus(b, p)			virt_to_bus(p)#else/* * With pci bus iommu support, we maintain one pool per pcidev and a  * hashed reverse table for virtual to bus physical address translations. */static m_addr_t ___dma_getp(m_pool_s *mp){	m_addr_t vp;	m_vtob_s *vbp;	vbp = __m_calloc(&mp0, sizeof(*vbp), "VTOB");	if (vbp) {		dma_addr_t daddr;		vp = (m_addr_t) pci_alloc_consistent(mp->bush,						PAGE_SIZE<<MEMO_PAGE_ORDER,						&daddr);		if (vp) {			int hc = VTOB_HASH_CODE(vp);			vbp->vaddr = vp;			vbp->baddr = daddr;			vbp->next = mp->vtob[hc];			mp->vtob[hc] = vbp;			++mp->nump;			return vp;		}		else			__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");	}	return 0;}static void ___dma_freep(m_pool_s *mp, m_addr_t m){	m_vtob_s **vbpp, *vbp;	int hc = VTOB_HASH_CODE(m);	vbpp = &mp->vtob[hc];	while (*vbpp && (*vbpp)->vaddr != m)		vbpp = &(*vbpp)->next;	if (*vbpp) {		vbp = *vbpp;		*vbpp = (*vbpp)->next;		pci_free_consistent(mp->bush, PAGE_SIZE<<MEMO_PAGE_ORDER,				    (void *)vbp->vaddr, (dma_addr_t)vbp->baddr);		__m_free(&mp0, vbp, sizeof(*vbp), "VTOB");		--mp->nump;	}}static inline m_pool_s *___get_dma_pool(m_bush_t bush){	m_pool_s *mp;	for (mp = mp0.next; mp && mp->bush != bush; mp = mp->next);	return mp;}static m_pool_s *___cre_dma_pool(m_bush_t bush){	m_pool_s *mp;	mp = __m_calloc(&mp0, sizeof(*mp), "MPOOL");	if (mp) {		bzero(mp, sizeof(*mp));		mp->bush = bush;		mp->getp = ___dma_getp;		mp->freep = ___dma_freep;		mp->next = mp0.next;		mp0.next = mp;	}	return mp;}static void ___del_dma_pool(m_pool_s *p){	struct m_pool **pp = &mp0.next;	while (*pp && *pp != p)		pp = &(*pp)->next;	if (*pp) {		*pp = (*pp)->next;		__m_free(&mp0, p, sizeof(*p), "MPOOL");	}}static void *__m_calloc_dma(m_bush_t bush, int size, char *name){	u_long flags;	struct m_pool *mp;	void *m = 0;	NCR_LOCK_DRIVER(flags);	mp = ___get_dma_pool(bush);	if (!mp)		mp = ___cre_dma_pool(bush);	if (mp)		m = __m_calloc(mp, size, name);	if (mp && !mp->nump)		___del_dma_pool(mp);	NCR_UNLOCK_DRIVER(flags);	return m;}static void __m_free_dma(m_bush_t bush, void *m, int size, char *name){	u_long flags;	struct m_pool *mp;	NCR_LOCK_DRIVER(flags);	mp = ___get_dma_pool(bush);	if (mp)		__m_free(mp, m, size, name);	if (mp && !mp->nump)		___del_dma_pool(mp);	NCR_UNLOCK_DRIVER(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 = 0;	m_addr_t a = ((m_addr_t) m) & ~MEMO_CLUSTER_MASK;	NCR_LOCK_DRIVER(flags);	mp = ___get_dma_pool(bush);	if (mp) {		vp = mp->vtob[hc];		while (vp && (m_addr_t) vp->vaddr != a)			vp = vp->next;	}	NCR_UNLOCK_DRIVER(flags);	return vp ? vp->baddr + (((m_addr_t) m) - a) : 0;}#endif	/* SCSI_NCR_DYNAMIC_DMA_MAPPING */#define _m_calloc_dma(np, s, n)		__m_calloc_dma(np->pdev, s, n)#define _m_free_dma(np, p, s, n)	__m_free_dma(np->pdev, 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->pdev, p)#define vtobus(p)			_vtobus(np, p)/* *  Deal with DMA mapping/unmapping. */#ifndef SCSI_NCR_DYNAMIC_DMA_MAPPING/* Linux versions prior to pci bus iommu kernel interface */#define __unmap_scsi_data(pdev, cmd)	do {; } while (0)#define __map_scsi_single_data(pdev, cmd) (__vtobus(pdev,(cmd)->request_buffer))#define __map_scsi_sg_data(pdev, cmd)	((cmd)->use_sg)#define __sync_scsi_data(pdev, cmd)	do {; } while (0)#define scsi_sg_dma_address(sc)		vtobus((sc)->address)#define scsi_sg_dma_len(sc)		((sc)->length)#else/* Linux version with pci bus iommu kernel interface *//* 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(pcidev_t pdev, Scsi_Cmnd *cmd){	int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);	switch(cmd->__data_mapped) {	case 2:		pci_unmap_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);		break;	case 1:		pci_unmap_single(pdev, cmd->__data_mapping,				 cmd->request_bufflen, dma_dir);		break;	}	cmd->__data_mapped = 0;}static u_long __map_scsi_single_data(pcidev_t pdev, Scsi_Cmnd *cmd){	dma_addr_t mapping;	int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);	if (cmd->request_bufflen == 0)		return 0;	mapping = pci_map_single(pdev, cmd->request_buffer,				 cmd->request_bufflen, dma_dir);	cmd->__data_mapped = 1;	cmd->__data_mapping = mapping;	return mapping;}static int __map_scsi_sg_data(pcidev_t pdev, Scsi_Cmnd *cmd){	int use_sg;	int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);	if (cmd->use_sg == 0)		return 0;	use_sg = pci_map_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);	cmd->__data_mapped = 2;	cmd->__data_mapping = use_sg;	return use_sg;}static void __sync_scsi_data(pcidev_t pdev, Scsi_Cmnd *cmd){	int dma_dir = scsi_to_pci_dma_dir(cmd->sc_data_direction);	switch(cmd->__data_mapped) {	case 2:		pci_dma_sync_sg(pdev, cmd->buffer, cmd->use_sg, dma_dir);		break;	case 1:		pci_dma_sync_single(pdev, cmd->__data_mapping,				    cmd->request_bufflen, dma_dir);		break;	}}#define scsi_sg_dma_address(sc)		sg_dma_address(sc)#define scsi_sg_dma_len(sc)		sg_dma_len(sc)#endif	/* SCSI_NCR_DYNAMIC_DMA_MAPPING */#define unmap_scsi_data(np, cmd)	__unmap_scsi_data(np->pdev, cmd)#define map_scsi_single_data(np, cmd)	__map_scsi_single_data(np->pdev, cmd)#define map_scsi_sg_data(np, cmd)	__map_scsi_sg_data(np->pdev, cmd)#define sync_scsi_data(np, cmd)		__sync_scsi_data(np->pdev, cmd)/* * Print out some buffer. */static void ncr_print_hex(u_char *p, int n){	while (n-- > 0)		printk (" %x", *p++);}static void ncr_printl_hex(char *label, u_char *p, int n){	printk("%s", label);	ncr_print_hex(p, n);	printk (".\n");}/***	Transfer direction****	Until some linux kernel version near 2.3.40, low-level scsi **	drivers were not told about data transfer direction.**	We check the existence of this feature that has been expected **	for a _long_ time by all SCSI driver developers by just **	testing against the definition of SCSI_DATA_UNKNOWN. Indeed **	this is a hack, but testing against a kernel version would **	have been a shame. ;-)*/#ifdef	SCSI_DATA_UNKNOWN#define scsi_data_direction(cmd)	(cmd->sc_data_direction)#else#define	SCSI_DATA_UNKNOWN	0#define	SCSI_DATA_WRITE		1#define	SCSI_DATA_READ		2#define	SCSI_DATA_NONE		3static __inline__ int scsi_data_direction(Scsi_Cmnd *cmd){	int direction;	switch((int) cmd->cmnd[0]) {	case 0x08:  /*	READ(6)				08 */	case 0x28:  /*	READ(10)			28 */	case 0xA8:  /*	READ(12)			A8 */		direction = SCSI_DATA_READ;		break;	case 0x0A:  /*	WRITE(6)			0A */	case 0x2A:  /*	WRITE(10)			2A */	case 0xAA:  /*	WRITE(12)			AA */		direction = SCSI_DATA_WRITE;		break;	default:		direction = SCSI_DATA_UNKNOWN;		break;	}	return direction;}#endif	/* SCSI_DATA_UNKNOWN *//***	Head of list of NCR boards****	For kernel version < 1.3.70, host is retrieved by its irq level.**	For later kernels, the internal host control block address **	(struct ncb) is used as device id parameter of the irq stuff.*/static struct Scsi_Host	*first_host = NULL;/***	/proc directory entry and proc_info function*/#if LINUX_VERSION_CODE < LinuxVersionCode(2,3,27)static struct proc_dir_entry proc_scsi_sym53c8xx = {    PROC_SCSI_SYM53C8XX, 9, NAME53C8XX,    S_IFDIR | S_IRUGO | S_IXUGO, 2};#endif#ifdef SCSI_NCR_PROC_INFO_SUPPORTstatic int sym53c8xx_proc_info(char *buffer, char **start, off_t offset,			int length, int hostno, int func);#endif/***	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;#ifdef	SCSI_NCR_BOOT_COMMAND_LINE_SUPPORTstatic struct ncr_driver_setup	driver_safe_setup __initdata	= SCSI_NCR_DRIVER_SAFE_SETUP;# ifdef	MODULEchar *sym53c8xx = 0;	/* command line passed by insmod */#  if LINUX_VERSION_CODE >= LinuxVersionCode(2,1,30)MODULE_PARM(sym53c8xx, "s");#  endif# endif#endif/***	Other Linux definitions*/#define SetScsiResult(cmd, h_sts, s_sts) \	cmd->result = (((h_sts) << 16) + ((s_sts) & 0x7f))/* We may have to remind our amnesiac SCSI layer of the reason of the abort */#if 0#define SetScsiAbortResult(cmd)	\	  SetScsiResult(	\	    cmd, 		\	    (cmd)->abort_reason == DID_TIME_OUT ? DID_TIME_OUT : DID_ABORT, \	    0xff)#else#define SetScsiAbortResult(cmd) SetScsiResult(cmd, DID_ABORT, 0xff)#endifstatic void sym53c8xx_select_queue_depths(	struct Scsi_Host *host, struct scsi_device *devlist);static void sym53c8xx_intr(int irq, void *dev_id, struct pt_regs * regs);static void sym53c8xx_timeout(unsigned long np);#define initverbose (driver_setup.verbose)#define bootverbose (np->verbose)#ifdef SCSI_NCR_NVRAM_SUPPORTstatic u_char Tekram_sync[16] __initdata =	{25,31,37,43, 50,62,75,125, 12,15,18,21, 6,7,9,10};#endif /* SCSI_NCR_NVRAM_SUPPORT *//***	Structures used by sym53c8xx_detect/sym53c8xx_pci_init to **	transmit device configuration to the ncr_attach() function.*/typedef struct {	int	bus;	u_char	device_fn;	u_long	base;	u_long	base_2;	u_long	io_port;	int	irq;/* port and reg fields to use INB, OUTB macros */	u_long	base_io;	volatile struct ncr_reg	*reg;} ncr_slot;typedef struct {	int type;#define	SCSI_NCR_SYMBIOS_NVRAM	(1)#define	SCSI_NCR_TEKRAM_NVRAM	(2)#ifdef	SCSI_NCR_NVRAM_SUPPORT	union {		Symbios_nvram Symbios;		Tekram_nvram Tekram;	} data;#endif} ncr_nvram;/***	Structure used by sym53c8xx_detect/sym53c8xx_pci_init**	to save data on each detected board for ncr_attach().*/typedef struct {	pcidev_t  pdev;	ncr_slot  slot;	ncr_chip  chip;	ncr_nvram *nvram;	u_char host_id;#ifdef	SCSI_NCR_PQS_PDS_SUPPORT	u_char pqs_pds;#endif	int attach_done;} ncr_device;/*==========================================================****	assert ()****==========================================================****	modified copy from 386bsd:/usr/include/sys/assert.h****----------------------------------------------------------*/#define	assert(expression) { \	if (!(expression)) { \		(void)panic( \			"assertion \"%s\" failed: file \"%s\", line %d\n", \

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -