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

📄 dasd.c

📁 linux和2410结合开发 用他可以生成2410所需的zImage文件
💻 C
📖 第 1 页 / 共 5 页
字号:
		switch (qp->head->status) {		case CQR_STATUS_QUEUED:			/* try to start the first I/O that can be started */			if (device->discipline->start_IO == NULL)				BUG ();                        device->discipline->start_IO(qp->head);			break;		case CQR_STATUS_IN_IO:			/* Check, if to invoke the missing interrupt handler */			if (dasd_check_expire_time (qp->head)) {				/* to be filled with MIH */			}			break;		case CQR_STATUS_PENDING:			/* just wait */			break;		default:			BUG ();		}	}	s390irq_spin_unlock_irqrestore (irq, flags);} /* end dasd_process_queues *//* * function dasd_run_bh * acquires the locks needed and then runs the bh */static voiddasd_run_bh (dasd_device_t * device){	long flags;	spin_lock_irqsave (&io_request_lock, flags);	atomic_set (&device->bh_scheduled, 0);	dasd_process_queues (device);	spin_unlock_irqrestore (&io_request_lock, flags);}/* * function dasd_schedule_bh * schedules the request_fn to run with next run_bh cycle */voiddasd_schedule_bh (dasd_device_t * device){	/* Protect against rescheduling, when already running */	if (atomic_compare_and_swap (0, 1, &device->bh_scheduled)) {		return;	}	INIT_LIST_HEAD (&device->bh_tq.list);	device->bh_tq.sync = 0;	device->bh_tq.routine = (void *) (void *) dasd_run_bh;	device->bh_tq.data = device;	queue_task (&device->bh_tq, &tq_immediate);	mark_bh (IMMEDIATE_BH);	return;}/* * function do_dasd_request * is called from ll_rw_blk.c and provides the caller of * dasd_process_queues */static voiddo_dasd_request (request_queue_t * queue){        dasd_device_t *device = (dasd_device_t *)queue->queuedata;	dasd_process_queues (device);}/* * DASD_HANDLE_STATE_CHANGE_PENDING * * DESCRIPTION *   Handles the state change pending interrupt. *   Search for the device related request queue and check if the first *   cqr in queue in in status 'CQR_STATUE_PENDING'. *   If so the status is set to 'CQR_STATUS_QUEUED' to reactivate *   the device. * *  PARAMETER *   stat               device status of state change pending interrupt. */voiddasd_handle_state_change_pending (devstat_t * stat){	dasd_device_t **device_addr;	ccw_req_t *cqr;	device_addr = dasd_device_from_devno (stat->devno);	if (device_addr == NULL) {		printk (KERN_DEBUG PRINTK_HEADER			"unable to find device for state change pending "			"interrupt: devno%04x\n",                         stat->devno);                return;	}         /* re-activate first request in queue */        cqr = (*device_addr)->queue.head;                if (cqr->status == CQR_STATUS_PENDING) {                                DASD_MESSAGE (KERN_DEBUG, (*device_addr), "%s",                              "device request queue restarted by "                              "state change pending interrupt\n");                                del_timer (&(*device_addr)->timer);                                check_then_set (&cqr->status,                                CQR_STATUS_PENDING, CQR_STATUS_QUEUED);                                dasd_schedule_bh (*device_addr);                        }} /* end dasd_handle_state_change_pending *//* * function dasd_int_handler * is the DASD driver's default interrupt handler for SSCH-IO */voiddasd_int_handler (int irq, void *ds, struct pt_regs *regs){	int ip;	ccw_req_t *cqr;	dasd_device_t *device;        unsigned long long now;	dasd_era_t era = dasd_era_none; /* default is everything is okay */	devstat_t *stat = (devstat_t *)ds;        if (stat == NULL) {                BUG();	}        DASD_DRIVER_DEBUG_EVENT (6, dasd_int_handler,                                 "Interrupt: IRQ %02x, stat %02x, devno %04x",                                 irq,                                 stat->dstat,                                 stat->devno);        asm volatile ("STCK %0":"=m" (now));        /* first of all check for state change pending interrupt */        if ((stat->dstat & DEV_STAT_ATTENTION ) &&             (stat->dstat & DEV_STAT_DEV_END   ) &&            (stat->dstat & DEV_STAT_UNIT_EXCEP)   ) {                DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,                                         "State change Interrupt: %04x",                                         stat->devno);                dasd_handle_state_change_pending (stat);                return;        }	ip = stat->intparm;	if (!ip) {		/* no intparm: unsolicited interrupt */                DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,                                         "Unsolicited Interrupt: %04x",                                         stat->devno);		printk (KERN_DEBUG PRINTK_HEADER                        "unsolicited interrupt: irq 0x%x devno %04x\n",                        irq,                        stat->devno);		return;	}	if (ip & 0x80000001) {                DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,                                         "spurious Interrupt: %04x",                                         stat->devno);		printk (KERN_DEBUG PRINTK_HEADER                        "spurious interrupt: irq 0x%x devno %04x, parm %08x\n",                        irq,                        stat->devno,ip);		return;	}	cqr = (ccw_req_t *)(long)ip;        /* check status - the request might have been killed because of dyn dettach */	if (cqr->status != CQR_STATUS_IN_IO) {                DASD_DRIVER_DEBUG_EVENT (2, dasd_int_handler,                                         "invalid status %02x on device %04x",                                         cqr->status,                                         stat->devno);		printk (KERN_DEBUG PRINTK_HEADER                        "invalid status: irq 0x%x devno %04x, status %02x\n",                        irq,                        stat->devno,                        cqr->status);		return;	}	device = (dasd_device_t *) cqr->device;	if (device == NULL ||             device != ds-offsetof(dasd_device_t,dev_status)) {                BUG();	}	if (device->devinfo.irq != irq) {                BUG();	}	if (strncmp (device->discipline->ebcname, (char *) &cqr->magic, 4)) {                BUG();	}        /* first of all lets try to find out the appropriate era_action */        DASD_DEVICE_DEBUG_EVENT (4, device," Int: CS/DS 0x%04x",                                 ((stat->cstat<<8)|stat->dstat));	/* first of all lets try to find out the appropriate era_action */	if (stat->flag & DEVSTAT_FLAG_SENSE_AVAIL ||	    stat->dstat & ~(DEV_STAT_CHN_END | DEV_STAT_DEV_END)) {		/* anything abnormal ? */		if (device->discipline->examine_error == NULL ||		    stat->flag & DEVSTAT_HALT_FUNCTION) {			era = dasd_era_fatal;		} else {			era = device->discipline->examine_error (cqr, stat);		}                DASD_DRIVER_DEBUG_EVENT (1, dasd_int_handler," era_code %d",                                         era);	}        if ( era == dasd_era_none ) {                check_then_set(&cqr->status,                                CQR_STATUS_IN_IO,                                CQR_STATUS_DONE);                cqr->stopclk=now;		/* start the next queued request if possible -> fast_io */                if (cqr->next &&                    cqr->next->status == CQR_STATUS_QUEUED) {                        if (device->discipline->start_IO (cqr->next) != 0) {                                printk (KERN_WARNING PRINTK_HEADER                                        "Interrupt fastpath failed!\n");                        }                 }        } else { /* error */		if (cqr->dstat == NULL)			cqr->dstat = kmalloc (sizeof (devstat_t), GFP_ATOMIC);		if (cqr->dstat) {			memcpy (cqr->dstat, stat, sizeof (devstat_t));		} else {			PRINT_ERR ("no memory for dstat...ignoring\n");		}#ifdef ERP_DEBUG		/* dump sense data */		if (device->discipline            &&                     device->discipline->dump_sense  ) {                        device->discipline->dump_sense (device,                                                         cqr);		}#endif		switch (era) {		case dasd_era_fatal:			check_then_set (&cqr->status,                                         CQR_STATUS_IN_IO,					CQR_STATUS_FAILED);                        cqr->stopclk = now;			break;		case dasd_era_recover:			check_then_set (&cqr->status,                                         CQR_STATUS_IN_IO,					CQR_STATUS_ERROR);			break;		default:			BUG ();		}	}        if ( cqr == device->init_cqr &&             ( cqr->status == CQR_STATUS_DONE ||               cqr->status == CQR_STATUS_FAILED )){                dasd_state_init_to_ready(device);                if ( atomic_read(&dasd_init_pending) == 0)                        wake_up (&dasd_init_waitq);        }	dasd_schedule_bh (device);} /* end dasd_int_handler *//* SECTION: Some stuff related to error recovery *//* * DEFAULT_ERP_ACTION * * DESCRIPTION *   sets up the default-ERP ccw_req_t, namely one, which performs a TIC *   to the original channel program with a retry counter of 16 * * PARAMETER *   cqr                failed CQR * * RETURN VALUES *   erp                CQR performing the ERP */ccw_req_t *dasd_default_erp_action (ccw_req_t * cqr){        dasd_device_t *device = cqr->device;	ccw_req_t     *erp    = dasd_alloc_request ((char *) &cqr->magic, 1, 0, cqr->device);	printk (KERN_DEBUG PRINTK_HEADER "Default ERP called... \n");	if (!erp) {                DASD_MESSAGE (KERN_ERR, device, "%s",                              "Unable to allocate ERP request");                                check_then_set (&cqr->status,                                CQR_STATUS_ERROR,                                CQR_STATUS_FAILED);                asm volatile ("STCK %0":"=m" (cqr->stopclk));                return cqr;	}	erp->cpaddr->cmd_code = CCW_CMD_TIC;	erp->cpaddr->cda = (__u32) (addr_t) cqr->cpaddr;	erp->function = dasd_default_erp_action;	erp->refers = cqr;	erp->device = cqr->device;	erp->magic = cqr->magic;	erp->retries = 16;	erp->status = CQR_STATUS_FILLED;        dasd_chanq_enq_head (&device->queue,                             erp);	return erp;} /* end dasd_default_erp_action *//* * DEFAULT_ERP_POSTACTION * * DESCRIPTION *   Frees all ERPs of the current ERP Chain and set the status *   of the original CQR either to CQR_STATUS_DONE if ERP was successful *   or to CQR_STATUS_FAILED if ERP was NOT successful. *   NOTE: This function is only called if no discipline postaction *         is available * * PARAMETER *   erp                current erp_head * * RETURN VALUES *   cqr                pointer to the original CQR */ccw_req_t *dasd_default_erp_postaction (ccw_req_t *erp){	ccw_req_t     *cqr      = NULL,                       *free_erp = NULL;	dasd_device_t *device   = erp->device;	int           success;	if (erp->refers   == NULL ||             erp->function == NULL   ) {		BUG ();	}	if (erp->status == CQR_STATUS_DONE)		success = 1;	else		success = 0;	/* free all ERPs - but NOT the original cqr */	while (erp->refers != NULL) {		free_erp = erp;		erp      = erp->refers;		/* remove the request from the device queue */		dasd_chanq_deq (&device->queue,                                free_erp);		/* free the finished erp request */		dasd_free_request (free_erp, free_erp->device);	}	/* save ptr to original cqr */	cqr = erp;	/* set corresponding status to original cqr */	if (success) {		check_then_set (&cqr->status,                                 CQR_STATUS_ERROR,				CQR_STATUS_DONE);	} else {		check_then_set (&cqr->status,				CQR_STATUS_ERROR,                                 CQR_STATUS_FAILED);                asm volatile ("STCK %0":"=m" (cqr->stopclk));	}	return cqr;} /* end default_erp_postaction *//* SECTION: The helpers of the struct file_operations *//* * function dasd_format * performs formatting of _device_ according to _fdata_ * Note: The discipline's format_function is assumed to deliver formatting * commands to format a single unit of the device. In terms of the ECKD * devices this means CCWs are generated to format a single track. */static intdasd_format (dasd_device_t * device, format_data_t * fdata){	int rc = 0;	int openct = atomic_read (&device->open_count);	if (openct > 1) {		DASD_MESSAGE (KERN_WARNING, device, "%s",			      "dasd_format: device is open! expect errors.");	}	DASD_MESSAG

⌨️ 快捷键说明

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