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

📄 tape_34xx.c

📁 linux-2.6.15.6
💻 C
📖 第 1 页 / 共 3 页
字号:
			/* all data checks for 3480 should result in one of			 * the above erpa-codes. For 3490, other data-check			 * conditions do exist. */			if (device->cdev->id.driver_info == tape_3480)				return tape_34xx_erp_bug(device, request,							 irb, -6);		}	}	if (sense[0] & SENSE_OVERRUN)		return tape_34xx_erp_overrun(device, request, irb);	if (sense[1] & SENSE_RECORD_SEQUENCE_ERR)		return tape_34xx_erp_sequence(device, request, irb);	/* Sensing erpa codes */	switch (sense[3]) {	case 0x00:		/* Unit check with erpa code 0. Report and ignore. */		PRINT_WARN("Non-error sense was found. "			   "Unit-check will be ignored.\n");		return TAPE_IO_SUCCESS;	case 0x21:		/*		 * Data streaming not operational. CU will switch to		 * interlock mode. Reissue the command.		 */		PRINT_WARN("Data streaming not operational. "			   "Switching to interlock-mode.\n");		return tape_34xx_erp_retry(request);	case 0x22:		/*		 * Path equipment check. Might be drive adapter error, buffer		 * error on the lower interface, internal path not usable,		 * or error during cartridge load.		 */		PRINT_WARN("A path equipment check occurred. One of the "			   "following conditions occurred:\n");		PRINT_WARN("drive adapter error, buffer error on the lower "			   "interface, internal path not usable, error "			   "during cartridge load.\n");		return tape_34xx_erp_failed(request, -EIO);	case 0x24:		/*		 * Load display check. Load display was command was issued,		 * but the drive is displaying a drive check message. Can		 * be threated as "device end".		 */		return tape_34xx_erp_succeeded(request);	case 0x27:		/*		 * Command reject. May indicate illegal channel program or		 * buffer over/underrun. Since all channel programs are		 * issued by this driver and ought be correct, we assume a		 * over/underrun situation and retry the channel program.		 */		return tape_34xx_erp_retry(request);	case 0x29:		/*		 * Function incompatible. Either the tape is idrc compressed		 * but the hardware isn't capable to do idrc, or a perform		 * subsystem func is issued and the CU is not on-line.		 */		PRINT_WARN ("Function incompatible. Try to switch off idrc\n");		return tape_34xx_erp_failed(request, -EIO);	case 0x2a:		/*		 * Unsolicited environmental data. An internal counter		 * overflows, we can ignore this and reissue the cmd.		 */		return tape_34xx_erp_retry(request);	case 0x2b:		/*		 * Environmental data present. Indicates either unload		 * completed ok or read buffered log command completed ok.		 */		if (request->op == TO_RUN) {			/* Rewind unload completed ok. */			tape_med_state_set(device, MS_UNLOADED);			return tape_34xx_erp_succeeded(request);		}		/* tape_34xx doesn't use read buffered log commands. */		return tape_34xx_erp_bug(device, request, irb, sense[3]);	case 0x2c:		/*		 * Permanent equipment check. CU has tried recovery, but		 * did not succeed.		 */		return tape_34xx_erp_failed(request, -EIO);	case 0x2d:		/* Data security erase failure. */		if (request->op == TO_DSE)			return tape_34xx_erp_failed(request, -EIO);		/* Data security erase failure, but no such command issued. */		return tape_34xx_erp_bug(device, request, irb, sense[3]);	case 0x2e:		/*		 * Not capable. This indicates either that the drive fails		 * reading the format id mark or that that format specified		 * is not supported by the drive.		 */		PRINT_WARN("Drive not capable processing the tape format!\n");		return tape_34xx_erp_failed(request, -EMEDIUMTYPE);	case 0x30:		/* The medium is write protected. */		PRINT_WARN("Medium is write protected!\n");		return tape_34xx_erp_failed(request, -EACCES);	case 0x32:		// Tension loss. We cannot recover this, it's an I/O error.		PRINT_WARN("The drive lost tape tension.\n");		return tape_34xx_erp_failed(request, -EIO);	case 0x33:		/*		 * Load Failure. The cartridge was not inserted correctly or		 * the tape is not threaded correctly.		 */		PRINT_WARN("Cartridge load failure. Reload the cartridge "			   "and try again.\n");		tape_34xx_delete_sbid_from(device, 0);		return tape_34xx_erp_failed(request, -EIO);	case 0x34:		/*		 * Unload failure. The drive cannot maintain tape tension		 * and control tape movement during an unload operation.		 */		PRINT_WARN("Failure during cartridge unload. "			   "Please try manually.\n");		if (request->op == TO_RUN)			return tape_34xx_erp_failed(request, -EIO);		return tape_34xx_erp_bug(device, request, irb, sense[3]);	case 0x35:		/*		 * Drive equipment check. One of the following:		 * - cu cannot recover from a drive detected error		 * - a check code message is shown on drive display		 * - the cartridge loader does not respond correctly		 * - a failure occurs during an index, load, or unload cycle		 */		PRINT_WARN("Equipment check! Please check the drive and "			   "the cartridge loader.\n");		return tape_34xx_erp_failed(request, -EIO);	case 0x36:		if (device->cdev->id.driver_info == tape_3490)			/* End of data. */			return tape_34xx_erp_failed(request, -EIO);		/* This erpa is reserved for 3480 */		return tape_34xx_erp_bug(device, request, irb, sense[3]);	case 0x37:		/*		 * Tape length error. The tape is shorter than reported in		 * the beginning-of-tape data.		 */		PRINT_WARN("Tape length error.\n");		return tape_34xx_erp_failed(request, -EIO);	case 0x38:		/*		 * Physical end of tape. A read/write operation reached		 * the physical end of tape.		 */		if (request->op==TO_WRI ||		    request->op==TO_DSE ||		    request->op==TO_WTM)			return tape_34xx_erp_failed(request, -ENOSPC);		return tape_34xx_erp_failed(request, -EIO);	case 0x39:		/* Backward at Beginning of tape. */		return tape_34xx_erp_failed(request, -EIO);	case 0x3a:		/* Drive switched to not ready. */		PRINT_WARN("Drive not ready. Turn the ready/not ready switch "			   "to ready position and try again.\n");		return tape_34xx_erp_failed(request, -EIO);	case 0x3b:		/* Manual rewind or unload. This causes an I/O error. */		PRINT_WARN("Medium was rewound or unloaded manually.\n");		tape_34xx_delete_sbid_from(device, 0);		return tape_34xx_erp_failed(request, -EIO);	case 0x42:		/*		 * Degraded mode. A condition that can cause degraded		 * performance is detected.		 */		PRINT_WARN("Subsystem is running in degraded mode.\n");		return tape_34xx_erp_retry(request);	case 0x43:		/* Drive not ready. */		tape_34xx_delete_sbid_from(device, 0);		tape_med_state_set(device, MS_UNLOADED);		/* Some commands commands are successful even in this case */		if (sense[1] & SENSE_DRIVE_ONLINE) {			switch(request->op) {				case TO_ASSIGN:				case TO_UNASSIGN:				case TO_DIS:				case TO_NOP:					return tape_34xx_done(request);					break;				default:					break;			}		}		PRINT_WARN("The drive is not ready.\n");		return tape_34xx_erp_failed(request, -ENOMEDIUM);	case 0x44:		/* Locate Block unsuccessful. */		if (request->op != TO_BLOCK && request->op != TO_LBL)			/* No locate block was issued. */			return tape_34xx_erp_bug(device, request,						 irb, sense[3]);		return tape_34xx_erp_failed(request, -EIO);	case 0x45:		/* The drive is assigned to a different channel path. */		PRINT_WARN("The drive is assigned elsewhere.\n");		return tape_34xx_erp_failed(request, -EIO);	case 0x46:		/*		 * Drive not on-line. Drive may be switched offline,		 * the power supply may be switched off or		 * the drive address may not be set correctly.		 */		PRINT_WARN("The drive is not on-line.");		return tape_34xx_erp_failed(request, -EIO);	case 0x47:		/* Volume fenced. CU reports volume integrity is lost. */		PRINT_WARN("Volume fenced. The volume integrity is lost.\n");		tape_34xx_delete_sbid_from(device, 0);		return tape_34xx_erp_failed(request, -EIO);	case 0x48:		/* Log sense data and retry request. */		return tape_34xx_erp_retry(request);	case 0x49:		/* Bus out check. A parity check error on the bus was found. */		PRINT_WARN("Bus out check. A data transfer over the bus "			   "has been corrupted.\n");		return tape_34xx_erp_failed(request, -EIO);	case 0x4a:		/* Control unit erp failed. */		PRINT_WARN("The control unit I/O error recovery failed.\n");		return tape_34xx_erp_failed(request, -EIO);	case 0x4b:		/*		 * CU and drive incompatible. The drive requests micro-program		 * patches, which are not available on the CU.		 */		PRINT_WARN("The drive needs microprogram patches from the "			   "control unit, which are not available.\n");		return tape_34xx_erp_failed(request, -EIO);	case 0x4c:		/*		 * Recovered Check-One failure. Cu develops a hardware error,		 * but is able to recover.		 */		return tape_34xx_erp_retry(request);	case 0x4d:		if (device->cdev->id.driver_info == tape_3490)			/*			 * Resetting event received. Since the driver does			 * not support resetting event recovery (which has to			 * be handled by the I/O Layer), retry our command.			 */			return tape_34xx_erp_retry(request);		/* This erpa is reserved for 3480. */		return tape_34xx_erp_bug(device, request, irb, sense[3]);	case 0x4e:		if (device->cdev->id.driver_info == tape_3490) {			/*			 * Maximum block size exceeded. This indicates, that			 * the block to be written is larger than allowed for			 * buffered mode.			 */			PRINT_WARN("Maximum block size for buffered "				   "mode exceeded.\n");			return tape_34xx_erp_failed(request, -ENOBUFS);		}		/* This erpa is reserved for 3480. */		return tape_34xx_erp_bug(device, request, irb, sense[3]);	case 0x50:		/*		 * Read buffered log (Overflow). CU is running in extended		 * buffered log mode, and a counter overflows. This should		 * never happen, since we're never running in extended		 * buffered log mode.		 */		return tape_34xx_erp_retry(request);	case 0x51:		/*		 * Read buffered log (EOV). EOF processing occurs while the		 * CU is in extended buffered log mode. This should never		 * happen, since we're never running in extended buffered		 * log mode.		 */		return tape_34xx_erp_retry(request);	case 0x52:		/* End of Volume complete. Rewind unload completed ok. */		if (request->op == TO_RUN) {			tape_med_state_set(device, MS_UNLOADED);			tape_34xx_delete_sbid_from(device, 0);			return tape_34xx_erp_succeeded(request);		}		return tape_34xx_erp_bug(device, request, irb, sense[3]);	case 0x53:		/* Global command intercept. */		return tape_34xx_erp_retry(request);	case 0x54:		/* Channel interface recovery (temporary). */		return tape_34xx_erp_retry(request);	case 0x55:		/* Channel interface recovery (permanent). */		PRINT_WARN("A permanent channel interface error occurred.\n");		return tape_34xx_erp_failed(request, -EIO);	case 0x56:		/* Channel protocol error. */		PRINT_WARN("A channel protocol error occurred.\n");		return tape_34xx_erp_failed(request, -EIO);	case 0x57:		if (device->cdev->id.driver_info == tape_3480) {			/* Attention intercept. */			PRINT_WARN("An attention intercept occurred, "				   "which will be recovered.\n");			return tape_34xx_erp_retry(request);		} else {			/* Global status intercept. */			PRINT_WARN("An global status intercept was received, "				   "which will be recovered.\n");			return tape_34xx_erp_retry(request);		}	case 0x5a:		/*		 * Tape length incompatible. The tape inserted is too long,		 * which could cause damage to the tape or the drive.		 */		PRINT_WARN("Tape Length Incompatible\n");		PRINT_WARN("Tape length exceeds IBM enhanced capacity "			"cartdridge length or a medium\n");		PRINT_WARN("with EC-CST identification mark has been mounted "			"in a device that writes\n");		PRINT_WARN("3480 or 3480 XF format.\n");		return tape_34xx_erp_failed(request, -EIO);	case 0x5b:		/* Format 3480 XF incompatible */		if (sense[1] & SENSE_BEGINNING_OF_TAPE)			/* The tape will get overwritten. */			return tape_34xx_erp_retry(request);		PRINT_WARN("Format 3480 XF Incompatible\n");		PRINT_WARN("Medium has been created in 3480 format. "			"To change the format writes\n");		PRINT_WARN("must be issued at BOT.\n");		return tape_34xx_erp_failed(request, -EIO);	case 0x5c:		/* Format 3480-2 XF incompatible */		PRINT_WARN("Format 3480-2 XF Incompatible\n");		PRINT_WARN("Device can only read 3480 or 3480 XF format.\n");		return tape_34xx_erp_failed(request, -EIO);	case 0x5d:		/* Tape length violation. */		PRINT_WARN("Tape Length Violation\n");		PRINT_WARN("The mounted tape exceeds IBM Enhanced Capacity "			"Cartdridge System Tape length.\n");		PRINT_WARN("This may cause damage to the drive or tape when "			"processing to the EOV\n");		return tape_34xx_erp_failed(request, -EMEDIUMTYPE);	case 0x5e:		/* Compaction algorithm incompatible. */		PRINT_WARN("Compaction Algorithm Incompatible\n");		PRINT_WARN("The volume is recorded using an incompatible "			"compaction algorithm,\n");		PRINT_WARN("which is not supported by the device.\n");		return tape_34xx_erp_failed(request, -EMEDIUMTYPE);		/* The following erpas should have been covered earlier. */	case 0x23: /* Read data check. */	case 0x25: /* Write data check. */	case 0x26: /* Data check (read opposite). */	case 0x28: /* Write id mark check. */	case 0x31: /* Tape void. */	case 0x40: /* Overrun error. */	case 0x41: /* Record sequence error. */		/* All other erpas are reserved for future use. */	default:		return tape_34xx_erp_bug(device, request, irb, sense[3]);	}}/* * 3480/3490 interrupt handler */static inttape_34xx_irq(struct tape_device *device, struct tape_request *request,	      struct irb *irb){	if (request == NULL)		return tape_34xx_unsolicited_irq(device, irb);	if ((irb->scsw.dstat & DEV_STAT_UNIT_EXCEP) &&	    (irb->scsw.dstat & DEV_STAT_DEV_END) &&	    (request->op == TO_WRI)) {		/* Write at end of volume */		PRINT_INFO("End of volume\n"); /* XXX */		return tape_34xx_erp_failed(request, -ENOSPC);	}	if (irb->scsw.dstat & DEV_STAT_UNIT_CHECK)		return tape_34xx_unit_check(device, request, irb);	if (irb->scsw.dstat & DEV_STAT_DEV_END) {		/*		 * A unit exception occurs on skipping over a tapemark block.		 */		if (irb->scsw.dstat & DEV_STAT_UNIT_EXCEP) {			if (request->op == TO_BSB || request->op == TO_FSB)				request->rescnt++;			else				DBF_EVENT(5, "Unit Exception!\n");		}		return tape_34xx_done(request);	}	DBF_EVENT(6, "xunknownirq\n");	PRINT_ERR("Unexpected interrupt.\n");	PRINT_ERR("Current op is: %s", tape_op_verbose[request->op]);	tape_dump_sense(device, request, irb);	return TAPE_IO_STOP;}/* * ioctl_overload */static inttape_34xx_ioctl(struct tape_device *device, unsigned int cmd, unsigned long arg){	if (cmd == TAPE390_DISPLAY) {		struct display_struct disp;		if (copy_from_user(&disp, (char __user *) arg, sizeof(disp)) != 0)			return -EFAULT;		return tape_std_display(device, &disp);	} else		return -EINVAL;}static inline voidtape_34xx_append_new_sbid(struct tape_34xx_block_id bid, struct list_head *l){	struct tape_34xx_sbid *	new_sbid;	new_sbid = kmalloc(sizeof(*new_sbid), GFP_ATOMIC);	if (!new_sbid)		return;	new_sbid->bid = bid;	list_add(&new_sbid->list, l);}/* * Build up the search block ID list. The block ID consists of a logical * block number and a hardware specific part. The hardware specific part * helps the tape drive to speed up searching for a specific block. */static voidtape_34xx_add_sbid(struct tape_device *device, struct tape_34xx_block_id bid){

⌨️ 快捷键说明

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