brintos

brintos / linux-shallow public Read only

0
0
Text · 33.7 KiB · 751945f Raw
1233 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 *    tape device discipline for 3480/3490 tapes.4 *5 *    Copyright IBM Corp. 2001, 20096 *    Author(s): Carsten Otte <cotte@de.ibm.com>7 *		 Tuan Ngo-Anh <ngoanh@de.ibm.com>8 *		 Martin Schwidefsky <schwidefsky@de.ibm.com>9 */10 11#define KMSG_COMPONENT "tape_34xx"12#define pr_fmt(fmt) KMSG_COMPONENT ": " fmt13 14#include <linux/module.h>15#include <linux/init.h>16#include <linux/bio.h>17#include <linux/workqueue.h>18#include <linux/slab.h>19 20#define TAPE_DBF_AREA	tape_34xx_dbf21 22#include "tape.h"23#include "tape_std.h"24 25/*26 * Pointer to debug area.27 */28debug_info_t *TAPE_DBF_AREA = NULL;29EXPORT_SYMBOL(TAPE_DBF_AREA);30 31#define TAPE34XX_FMT_3480	032#define TAPE34XX_FMT_3480_2_XF	133#define TAPE34XX_FMT_3480_XF	234 35struct tape_34xx_block_id {36	unsigned int	wrap		: 1;37	unsigned int	segment		: 7;38	unsigned int	format		: 2;39	unsigned int	block		: 22;40};41 42/*43 * A list of block ID's is used to faster seek blocks.44 */45struct tape_34xx_sbid {46	struct list_head		list;47	struct tape_34xx_block_id	bid;48};49 50static void tape_34xx_delete_sbid_from(struct tape_device *, int);51 52/*53 * Medium sense for 34xx tapes. There is no 'real' medium sense call.54 * So we just do a normal sense.55 */56static void __tape_34xx_medium_sense(struct tape_request *request)57{58	struct tape_device *device = request->device;59	unsigned char *sense;60 61	if (request->rc == 0) {62		sense = request->cpdata;63 64		/*65		 * This isn't quite correct. But since INTERVENTION_REQUIRED66		 * means that the drive is 'neither ready nor on-line' it is67		 * only slightly inaccurate to say there is no tape loaded if68		 * the drive isn't online...69		 */70		if (sense[0] & SENSE_INTERVENTION_REQUIRED)71			tape_med_state_set(device, MS_UNLOADED);72		else73			tape_med_state_set(device, MS_LOADED);74 75		if (sense[1] & SENSE_WRITE_PROTECT)76			device->tape_generic_status |= GMT_WR_PROT(~0);77		else78			device->tape_generic_status &= ~GMT_WR_PROT(~0);79	} else80		DBF_EVENT(4, "tape_34xx: medium sense failed with rc=%d\n",81			request->rc);82	tape_free_request(request);83}84 85static int tape_34xx_medium_sense(struct tape_device *device)86{87	struct tape_request *request;88	int rc;89 90	request = tape_alloc_request(1, 32);91	if (IS_ERR(request)) {92		DBF_EXCEPTION(6, "MSEN fail\n");93		return PTR_ERR(request);94	}95 96	request->op = TO_MSEN;97	tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata);98	rc = tape_do_io_interruptible(device, request);99	__tape_34xx_medium_sense(request);100	return rc;101}102 103static void tape_34xx_medium_sense_async(struct tape_device *device)104{105	struct tape_request *request;106 107	request = tape_alloc_request(1, 32);108	if (IS_ERR(request)) {109		DBF_EXCEPTION(6, "MSEN fail\n");110		return;111	}112 113	request->op = TO_MSEN;114	tape_ccw_end(request->cpaddr, SENSE, 32, request->cpdata);115	request->callback = (void *) __tape_34xx_medium_sense;116	request->callback_data = NULL;117	tape_do_io_async(device, request);118}119 120struct tape_34xx_work {121	struct tape_device	*device;122	enum tape_op		 op;123	struct work_struct	 work;124};125 126/*127 * These functions are currently used only to schedule a medium_sense for128 * later execution. This is because we get an interrupt whenever a medium129 * is inserted but cannot call tape_do_io* from an interrupt context.130 * Maybe that's useful for other actions we want to start from the131 * interrupt handler.132 * Note: the work handler is called by the system work queue. The tape133 * commands started by the handler need to be asynchrounous, otherwise134 * a deadlock can occur e.g. in case of a deferred cc=1 (see __tape_do_irq).135 */136static void137tape_34xx_work_handler(struct work_struct *work)138{139	struct tape_34xx_work *p =140		container_of(work, struct tape_34xx_work, work);141	struct tape_device *device = p->device;142 143	switch(p->op) {144		case TO_MSEN:145			tape_34xx_medium_sense_async(device);146			break;147		default:148			DBF_EVENT(3, "T34XX: internal error: unknown work\n");149	}150	tape_put_device(device);151	kfree(p);152}153 154static int155tape_34xx_schedule_work(struct tape_device *device, enum tape_op op)156{157	struct tape_34xx_work *p;158 159	if ((p = kzalloc(sizeof(*p), GFP_ATOMIC)) == NULL)160		return -ENOMEM;161 162	INIT_WORK(&p->work, tape_34xx_work_handler);163 164	p->device = tape_get_device(device);165	p->op     = op;166 167	schedule_work(&p->work);168	return 0;169}170 171/*172 * Done Handler is called when dev stat = DEVICE-END (successful operation)173 */174static inline int175tape_34xx_done(struct tape_request *request)176{177	DBF_EVENT(6, "%s done\n", tape_op_verbose[request->op]);178 179	switch (request->op) {180		case TO_DSE:181		case TO_RUN:182		case TO_WRI:183		case TO_WTM:184		case TO_ASSIGN:185		case TO_UNASSIGN:186			tape_34xx_delete_sbid_from(request->device, 0);187			break;188		default:189			;190	}191	return TAPE_IO_SUCCESS;192}193 194static inline int195tape_34xx_erp_failed(struct tape_request *request, int rc)196{197	DBF_EVENT(3, "Error recovery failed for %s (RC=%d)\n",198		  tape_op_verbose[request->op], rc);199	return rc;200}201 202static inline int203tape_34xx_erp_succeeded(struct tape_request *request)204{205	DBF_EVENT(3, "Error Recovery successful for %s\n",206		  tape_op_verbose[request->op]);207	return tape_34xx_done(request);208}209 210static inline int211tape_34xx_erp_retry(struct tape_request *request)212{213	DBF_EVENT(3, "xerp retr %s\n", tape_op_verbose[request->op]);214	return TAPE_IO_RETRY;215}216 217/*218 * This function is called, when no request is outstanding and we get an219 * interrupt220 */221static int222tape_34xx_unsolicited_irq(struct tape_device *device, struct irb *irb)223{224	if (irb->scsw.cmd.dstat == 0x85) { /* READY */225		/* A medium was inserted in the drive. */226		DBF_EVENT(6, "xuud med\n");227		tape_34xx_delete_sbid_from(device, 0);228		tape_34xx_schedule_work(device, TO_MSEN);229	} else {230		DBF_EVENT(3, "unsol.irq! dev end: %08x\n", device->cdev_id);231		tape_dump_sense_dbf(device, NULL, irb);232	}233	return TAPE_IO_SUCCESS;234}235 236/*237 * Read Opposite Error Recovery Function:238 * Used, when Read Forward does not work239 */240static int241tape_34xx_erp_read_opposite(struct tape_device *device,242			    struct tape_request *request)243{244	if (request->op == TO_RFO) {245		/*246		 * We did read forward, but the data could not be read247		 * *correctly*. We transform the request to a read backward248		 * and try again.249		 */250		tape_std_read_backward(device, request);251		return tape_34xx_erp_retry(request);252	}253 254	/*255	 * We tried to read forward and backward, but hat no256	 * success -> failed.257	 */258	return tape_34xx_erp_failed(request, -EIO);259}260 261static int262tape_34xx_erp_bug(struct tape_device *device, struct tape_request *request,263		  struct irb *irb, int no)264{265	if (request->op != TO_ASSIGN) {266		dev_err(&device->cdev->dev, "An unexpected condition %d "267			"occurred in tape error recovery\n", no);268		tape_dump_sense_dbf(device, request, irb);269	}270	return tape_34xx_erp_failed(request, -EIO);271}272 273/*274 * Handle data overrun between cu and drive. The channel speed might275 * be too slow.276 */277static int278tape_34xx_erp_overrun(struct tape_device *device, struct tape_request *request,279		      struct irb *irb)280{281	if (irb->ecw[3] == 0x40) {282		dev_warn (&device->cdev->dev, "A data overrun occurred between"283			" the control unit and tape unit\n");284		return tape_34xx_erp_failed(request, -EIO);285	}286	return tape_34xx_erp_bug(device, request, irb, -1);287}288 289/*290 * Handle record sequence error.291 */292static int293tape_34xx_erp_sequence(struct tape_device *device,294		       struct tape_request *request, struct irb *irb)295{296	if (irb->ecw[3] == 0x41) {297		/*298		 * cu detected incorrect block-id sequence on tape.299		 */300		dev_warn (&device->cdev->dev, "The block ID sequence on the "301			"tape is incorrect\n");302		return tape_34xx_erp_failed(request, -EIO);303	}304	/*305	 * Record sequence error bit is set, but erpa does not306	 * show record sequence error.307	 */308	return tape_34xx_erp_bug(device, request, irb, -2);309}310 311/*312 * This function analyses the tape's sense-data in case of a unit-check.313 * If possible, it tries to recover from the error. Else the user is314 * informed about the problem.315 */316static int317tape_34xx_unit_check(struct tape_device *device, struct tape_request *request,318		     struct irb *irb)319{320	int inhibit_cu_recovery;321	__u8* sense;322 323	inhibit_cu_recovery = (*device->modeset_byte & 0x80) ? 1 : 0;324	sense = irb->ecw;325 326	if (327		sense[0] & SENSE_COMMAND_REJECT &&328		sense[1] & SENSE_WRITE_PROTECT329	) {330		if (331			request->op == TO_DSE ||332			request->op == TO_WRI ||333			request->op == TO_WTM334		) {335			/* medium is write protected */336			return tape_34xx_erp_failed(request, -EACCES);337		} else {338			return tape_34xx_erp_bug(device, request, irb, -3);339		}340	}341 342	/*343	 * Special cases for various tape-states when reaching344	 * end of recorded area345	 *346	 * FIXME: Maybe a special case of the special case:347	 *        sense[0] == SENSE_EQUIPMENT_CHECK &&348	 *        sense[1] == SENSE_DRIVE_ONLINE    &&349	 *        sense[3] == 0x47 (Volume Fenced)350	 *351	 *        This was caused by continued FSF or FSR after an352	 *        'End Of Data'.353	 */354	if ((355		sense[0] == SENSE_DATA_CHECK      ||356		sense[0] == SENSE_EQUIPMENT_CHECK ||357		sense[0] == (SENSE_EQUIPMENT_CHECK | SENSE_DEFERRED_UNIT_CHECK)358	) && (359		sense[1] == SENSE_DRIVE_ONLINE ||360		sense[1] == (SENSE_BEGINNING_OF_TAPE | SENSE_WRITE_MODE)361	)) {362		switch (request->op) {363		/*364		 * sense[0] == SENSE_DATA_CHECK   &&365		 * sense[1] == SENSE_DRIVE_ONLINE366		 * sense[3] == 0x36 (End Of Data)367		 *368		 * Further seeks might return a 'Volume Fenced'.369		 */370		case TO_FSF:371		case TO_FSB:372			/* Trying to seek beyond end of recorded area */373			return tape_34xx_erp_failed(request, -ENOSPC);374		case TO_BSB:375			return tape_34xx_erp_retry(request);376 377		/*378		 * sense[0] == SENSE_DATA_CHECK   &&379		 * sense[1] == SENSE_DRIVE_ONLINE &&380		 * sense[3] == 0x36 (End Of Data)381		 */382		case TO_LBL:383			/* Block could not be located. */384			tape_34xx_delete_sbid_from(device, 0);385			return tape_34xx_erp_failed(request, -EIO);386 387		case TO_RFO:388			/* Read beyond end of recorded area -> 0 bytes read */389			return tape_34xx_erp_failed(request, 0);390 391		/*392		 * sense[0] == SENSE_EQUIPMENT_CHECK &&393		 * sense[1] == SENSE_DRIVE_ONLINE    &&394		 * sense[3] == 0x38 (Physical End Of Volume)395		 */396		case TO_WRI:397			/* Writing at physical end of volume */398			return tape_34xx_erp_failed(request, -ENOSPC);399		default:400			return tape_34xx_erp_failed(request, 0);401		}402	}403 404	/* Sensing special bits */405	if (sense[0] & SENSE_BUS_OUT_CHECK)406		return tape_34xx_erp_retry(request);407 408	if (sense[0] & SENSE_DATA_CHECK) {409		/*410		 * hardware failure, damaged tape or improper411		 * operating conditions412		 */413		switch (sense[3]) {414		case 0x23:415			/* a read data check occurred */416			if ((sense[2] & SENSE_TAPE_SYNC_MODE) ||417			    inhibit_cu_recovery)418				// data check is not permanent, may be419				// recovered. We always use async-mode with420				// cu-recovery, so this should *never* happen.421				return tape_34xx_erp_bug(device, request,422							 irb, -4);423 424			/* data check is permanent, CU recovery has failed */425			dev_warn (&device->cdev->dev, "A read error occurred "426				"that cannot be recovered\n");427			return tape_34xx_erp_failed(request, -EIO);428		case 0x25:429			// a write data check occurred430			if ((sense[2] & SENSE_TAPE_SYNC_MODE) ||431			    inhibit_cu_recovery)432				// data check is not permanent, may be433				// recovered. We always use async-mode with434				// cu-recovery, so this should *never* happen.435				return tape_34xx_erp_bug(device, request,436							 irb, -5);437 438			// data check is permanent, cu-recovery has failed439			dev_warn (&device->cdev->dev, "A write error on the "440				"tape cannot be recovered\n");441			return tape_34xx_erp_failed(request, -EIO);442		case 0x26:443			/* Data Check (read opposite) occurred. */444			return tape_34xx_erp_read_opposite(device, request);445		case 0x28:446			/* ID-Mark at tape start couldn't be written */447			dev_warn (&device->cdev->dev, "Writing the ID-mark "448				"failed\n");449			return tape_34xx_erp_failed(request, -EIO);450		case 0x31:451			/* Tape void. Tried to read beyond end of device. */452			dev_warn (&device->cdev->dev, "Reading the tape beyond"453				" the end of the recorded area failed\n");454			return tape_34xx_erp_failed(request, -ENOSPC);455		case 0x41:456			/* Record sequence error. */457			dev_warn (&device->cdev->dev, "The tape contains an "458				"incorrect block ID sequence\n");459			return tape_34xx_erp_failed(request, -EIO);460		default:461			/* all data checks for 3480 should result in one of462			 * the above erpa-codes. For 3490, other data-check463			 * conditions do exist. */464			if (device->cdev->id.driver_info == tape_3480)465				return tape_34xx_erp_bug(device, request,466							 irb, -6);467		}468	}469 470	if (sense[0] & SENSE_OVERRUN)471		return tape_34xx_erp_overrun(device, request, irb);472 473	if (sense[1] & SENSE_RECORD_SEQUENCE_ERR)474		return tape_34xx_erp_sequence(device, request, irb);475 476	/* Sensing erpa codes */477	switch (sense[3]) {478	case 0x00:479		/* Unit check with erpa code 0. Report and ignore. */480		return TAPE_IO_SUCCESS;481	case 0x21:482		/*483		 * Data streaming not operational. CU will switch to484		 * interlock mode. Reissue the command.485		 */486		return tape_34xx_erp_retry(request);487	case 0x22:488		/*489		 * Path equipment check. Might be drive adapter error, buffer490		 * error on the lower interface, internal path not usable,491		 * or error during cartridge load.492		 */493		dev_warn (&device->cdev->dev, "A path equipment check occurred"494			" for the tape device\n");495		return tape_34xx_erp_failed(request, -EIO);496	case 0x24:497		/*498		 * Load display check. Load display was command was issued,499		 * but the drive is displaying a drive check message. Can500		 * be threated as "device end".501		 */502		return tape_34xx_erp_succeeded(request);503	case 0x27:504		/*505		 * Command reject. May indicate illegal channel program or506		 * buffer over/underrun. Since all channel programs are507		 * issued by this driver and ought be correct, we assume a508		 * over/underrun situation and retry the channel program.509		 */510		return tape_34xx_erp_retry(request);511	case 0x29:512		/*513		 * Function incompatible. Either the tape is idrc compressed514		 * but the hardware isn't capable to do idrc, or a perform515		 * subsystem func is issued and the CU is not on-line.516		 */517		return tape_34xx_erp_failed(request, -EIO);518	case 0x2a:519		/*520		 * Unsolicited environmental data. An internal counter521		 * overflows, we can ignore this and reissue the cmd.522		 */523		return tape_34xx_erp_retry(request);524	case 0x2b:525		/*526		 * Environmental data present. Indicates either unload527		 * completed ok or read buffered log command completed ok.528		 */529		if (request->op == TO_RUN) {530			/* Rewind unload completed ok. */531			tape_med_state_set(device, MS_UNLOADED);532			return tape_34xx_erp_succeeded(request);533		}534		/* tape_34xx doesn't use read buffered log commands. */535		return tape_34xx_erp_bug(device, request, irb, sense[3]);536	case 0x2c:537		/*538		 * Permanent equipment check. CU has tried recovery, but539		 * did not succeed.540		 */541		return tape_34xx_erp_failed(request, -EIO);542	case 0x2d:543		/* Data security erase failure. */544		if (request->op == TO_DSE)545			return tape_34xx_erp_failed(request, -EIO);546		/* Data security erase failure, but no such command issued. */547		return tape_34xx_erp_bug(device, request, irb, sense[3]);548	case 0x2e:549		/*550		 * Not capable. This indicates either that the drive fails551		 * reading the format id mark or that format specified552		 * is not supported by the drive.553		 */554		dev_warn (&device->cdev->dev, "The tape unit cannot process "555			"the tape format\n");556		return tape_34xx_erp_failed(request, -EMEDIUMTYPE);557	case 0x30:558		/* The medium is write protected. */559		dev_warn (&device->cdev->dev, "The tape medium is write-"560			"protected\n");561		return tape_34xx_erp_failed(request, -EACCES);562	case 0x32:563		// Tension loss. We cannot recover this, it's an I/O error.564		dev_warn (&device->cdev->dev, "The tape does not have the "565			"required tape tension\n");566		return tape_34xx_erp_failed(request, -EIO);567	case 0x33:568		/*569		 * Load Failure. The cartridge was not inserted correctly or570		 * the tape is not threaded correctly.571		 */572		dev_warn (&device->cdev->dev, "The tape unit failed to load"573			" the cartridge\n");574		tape_34xx_delete_sbid_from(device, 0);575		return tape_34xx_erp_failed(request, -EIO);576	case 0x34:577		/*578		 * Unload failure. The drive cannot maintain tape tension579		 * and control tape movement during an unload operation.580		 */581		dev_warn (&device->cdev->dev, "Automatic unloading of the tape"582			" cartridge failed\n");583		if (request->op == TO_RUN)584			return tape_34xx_erp_failed(request, -EIO);585		return tape_34xx_erp_bug(device, request, irb, sense[3]);586	case 0x35:587		/*588		 * Drive equipment check. One of the following:589		 * - cu cannot recover from a drive detected error590		 * - a check code message is shown on drive display591		 * - the cartridge loader does not respond correctly592		 * - a failure occurs during an index, load, or unload cycle593		 */594		dev_warn (&device->cdev->dev, "An equipment check has occurred"595			" on the tape unit\n");596		return tape_34xx_erp_failed(request, -EIO);597	case 0x36:598		if (device->cdev->id.driver_info == tape_3490)599			/* End of data. */600			return tape_34xx_erp_failed(request, -EIO);601		/* This erpa is reserved for 3480 */602		return tape_34xx_erp_bug(device, request, irb, sense[3]);603	case 0x37:604		/*605		 * Tape length error. The tape is shorter than reported in606		 * the beginning-of-tape data.607		 */608		dev_warn (&device->cdev->dev, "The tape information states an"609			" incorrect length\n");610		return tape_34xx_erp_failed(request, -EIO);611	case 0x38:612		/*613		 * Physical end of tape. A read/write operation reached614		 * the physical end of tape.615		 */616		if (request->op==TO_WRI ||617		    request->op==TO_DSE ||618		    request->op==TO_WTM)619			return tape_34xx_erp_failed(request, -ENOSPC);620		return tape_34xx_erp_failed(request, -EIO);621	case 0x39:622		/* Backward at Beginning of tape. */623		return tape_34xx_erp_failed(request, -EIO);624	case 0x3a:625		/* Drive switched to not ready. */626		dev_warn (&device->cdev->dev, "The tape unit is not ready\n");627		return tape_34xx_erp_failed(request, -EIO);628	case 0x3b:629		/* Manual rewind or unload. This causes an I/O error. */630		dev_warn (&device->cdev->dev, "The tape medium has been "631			"rewound or unloaded manually\n");632		tape_34xx_delete_sbid_from(device, 0);633		return tape_34xx_erp_failed(request, -EIO);634	case 0x42:635		/*636		 * Degraded mode. A condition that can cause degraded637		 * performance is detected.638		 */639		dev_warn (&device->cdev->dev, "The tape subsystem is running "640			"in degraded mode\n");641		return tape_34xx_erp_retry(request);642	case 0x43:643		/* Drive not ready. */644		tape_34xx_delete_sbid_from(device, 0);645		tape_med_state_set(device, MS_UNLOADED);646		/* Some commands commands are successful even in this case */647		if (sense[1] & SENSE_DRIVE_ONLINE) {648			switch(request->op) {649				case TO_ASSIGN:650				case TO_UNASSIGN:651				case TO_DIS:652				case TO_NOP:653					return tape_34xx_done(request);654					break;655				default:656					break;657			}658		}659		return tape_34xx_erp_failed(request, -ENOMEDIUM);660	case 0x44:661		/* Locate Block unsuccessful. */662		if (request->op != TO_BLOCK && request->op != TO_LBL)663			/* No locate block was issued. */664			return tape_34xx_erp_bug(device, request,665						 irb, sense[3]);666		return tape_34xx_erp_failed(request, -EIO);667	case 0x45:668		/* The drive is assigned to a different channel path. */669		dev_warn (&device->cdev->dev, "The tape unit is already "670			"assigned\n");671		return tape_34xx_erp_failed(request, -EIO);672	case 0x46:673		/*674		 * Drive not on-line. Drive may be switched offline,675		 * the power supply may be switched off or676		 * the drive address may not be set correctly.677		 */678		dev_warn (&device->cdev->dev, "The tape unit is not online\n");679		return tape_34xx_erp_failed(request, -EIO);680	case 0x47:681		/* Volume fenced. CU reports volume integrity is lost. */682		dev_warn (&device->cdev->dev, "The control unit has fenced "683			"access to the tape volume\n");684		tape_34xx_delete_sbid_from(device, 0);685		return tape_34xx_erp_failed(request, -EIO);686	case 0x48:687		/* Log sense data and retry request. */688		return tape_34xx_erp_retry(request);689	case 0x49:690		/* Bus out check. A parity check error on the bus was found. */691		dev_warn (&device->cdev->dev, "A parity error occurred on the "692			"tape bus\n");693		return tape_34xx_erp_failed(request, -EIO);694	case 0x4a:695		/* Control unit erp failed. */696		dev_warn (&device->cdev->dev, "I/O error recovery failed on "697			"the tape control unit\n");698		return tape_34xx_erp_failed(request, -EIO);699	case 0x4b:700		/*701		 * CU and drive incompatible. The drive requests micro-program702		 * patches, which are not available on the CU.703		 */704		dev_warn (&device->cdev->dev, "The tape unit requires a "705			"firmware update\n");706		return tape_34xx_erp_failed(request, -EIO);707	case 0x4c:708		/*709		 * Recovered Check-One failure. Cu develops a hardware error,710		 * but is able to recover.711		 */712		return tape_34xx_erp_retry(request);713	case 0x4d:714		if (device->cdev->id.driver_info == tape_3490)715			/*716			 * Resetting event received. Since the driver does717			 * not support resetting event recovery (which has to718			 * be handled by the I/O Layer), retry our command.719			 */720			return tape_34xx_erp_retry(request);721		/* This erpa is reserved for 3480. */722		return tape_34xx_erp_bug(device, request, irb, sense[3]);723	case 0x4e:724		if (device->cdev->id.driver_info == tape_3490) {725			/*726			 * Maximum block size exceeded. This indicates, that727			 * the block to be written is larger than allowed for728			 * buffered mode.729			 */730			dev_warn (&device->cdev->dev, "The maximum block size"731				" for buffered mode is exceeded\n");732			return tape_34xx_erp_failed(request, -ENOBUFS);733		}734		/* This erpa is reserved for 3480. */735		return tape_34xx_erp_bug(device, request, irb, sense[3]);736	case 0x50:737		/*738		 * Read buffered log (Overflow). CU is running in extended739		 * buffered log mode, and a counter overflows. This should740		 * never happen, since we're never running in extended741		 * buffered log mode.742		 */743		return tape_34xx_erp_retry(request);744	case 0x51:745		/*746		 * Read buffered log (EOV). EOF processing occurs while the747		 * CU is in extended buffered log mode. This should never748		 * happen, since we're never running in extended buffered749		 * log mode.750		 */751		return tape_34xx_erp_retry(request);752	case 0x52:753		/* End of Volume complete. Rewind unload completed ok. */754		if (request->op == TO_RUN) {755			tape_med_state_set(device, MS_UNLOADED);756			tape_34xx_delete_sbid_from(device, 0);757			return tape_34xx_erp_succeeded(request);758		}759		return tape_34xx_erp_bug(device, request, irb, sense[3]);760	case 0x53:761		/* Global command intercept. */762		return tape_34xx_erp_retry(request);763	case 0x54:764		/* Channel interface recovery (temporary). */765		return tape_34xx_erp_retry(request);766	case 0x55:767		/* Channel interface recovery (permanent). */768		dev_warn (&device->cdev->dev, "A channel interface error cannot be"769			" recovered\n");770		return tape_34xx_erp_failed(request, -EIO);771	case 0x56:772		/* Channel protocol error. */773		dev_warn (&device->cdev->dev, "A channel protocol error "774			"occurred\n");775		return tape_34xx_erp_failed(request, -EIO);776	case 0x57:777		/*778		 * 3480: Attention intercept.779		 * 3490: Global status intercept.780		 */781		return tape_34xx_erp_retry(request);782	case 0x5a:783		/*784		 * Tape length incompatible. The tape inserted is too long,785		 * which could cause damage to the tape or the drive.786		 */787		dev_warn (&device->cdev->dev, "The tape unit does not support "788			"the tape length\n");789		return tape_34xx_erp_failed(request, -EIO);790	case 0x5b:791		/* Format 3480 XF incompatible */792		if (sense[1] & SENSE_BEGINNING_OF_TAPE)793			/* The tape will get overwritten. */794			return tape_34xx_erp_retry(request);795		dev_warn (&device->cdev->dev, "The tape unit does not support"796			" format 3480 XF\n");797		return tape_34xx_erp_failed(request, -EIO);798	case 0x5c:799		/* Format 3480-2 XF incompatible */800		dev_warn (&device->cdev->dev, "The tape unit does not support tape "801			"format 3480-2 XF\n");802		return tape_34xx_erp_failed(request, -EIO);803	case 0x5d:804		/* Tape length violation. */805		dev_warn (&device->cdev->dev, "The tape unit does not support"806			" the current tape length\n");807		return tape_34xx_erp_failed(request, -EMEDIUMTYPE);808	case 0x5e:809		/* Compaction algorithm incompatible. */810		dev_warn (&device->cdev->dev, "The tape unit does not support"811			" the compaction algorithm\n");812		return tape_34xx_erp_failed(request, -EMEDIUMTYPE);813 814		/* The following erpas should have been covered earlier. */815	case 0x23: /* Read data check. */816	case 0x25: /* Write data check. */817	case 0x26: /* Data check (read opposite). */818	case 0x28: /* Write id mark check. */819	case 0x31: /* Tape void. */820	case 0x40: /* Overrun error. */821	case 0x41: /* Record sequence error. */822		/* All other erpas are reserved for future use. */823	default:824		return tape_34xx_erp_bug(device, request, irb, sense[3]);825	}826}827 828/*829 * 3480/3490 interrupt handler830 */831static int832tape_34xx_irq(struct tape_device *device, struct tape_request *request,833	      struct irb *irb)834{835	if (request == NULL)836		return tape_34xx_unsolicited_irq(device, irb);837 838	if ((irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) &&839	    (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) &&840	    (request->op == TO_WRI)) {841		/* Write at end of volume */842		return tape_34xx_erp_failed(request, -ENOSPC);843	}844 845	if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK)846		return tape_34xx_unit_check(device, request, irb);847 848	if (irb->scsw.cmd.dstat & DEV_STAT_DEV_END) {849		/*850		 * A unit exception occurs on skipping over a tapemark block.851		 */852		if (irb->scsw.cmd.dstat & DEV_STAT_UNIT_EXCEP) {853			if (request->op == TO_BSB || request->op == TO_FSB)854				request->rescnt++;855			else856				DBF_EVENT(5, "Unit Exception!\n");857		}858		return tape_34xx_done(request);859	}860 861	DBF_EVENT(6, "xunknownirq\n");862	tape_dump_sense_dbf(device, request, irb);863	return TAPE_IO_STOP;864}865 866/*867 * ioctl_overload868 */869static int870tape_34xx_ioctl(struct tape_device *device, unsigned int cmd, unsigned long arg)871{872	if (cmd == TAPE390_DISPLAY) {873		struct display_struct disp;874 875		if (copy_from_user(&disp, (char __user *) arg, sizeof(disp)) != 0)876			return -EFAULT;877 878		return tape_std_display(device, &disp);879	} else880		return -EINVAL;881}882 883static inline void884tape_34xx_append_new_sbid(struct tape_34xx_block_id bid, struct list_head *l)885{886	struct tape_34xx_sbid *	new_sbid;887 888	new_sbid = kmalloc(sizeof(*new_sbid), GFP_ATOMIC);889	if (!new_sbid)890		return;891 892	new_sbid->bid = bid;893	list_add(&new_sbid->list, l);894}895 896/*897 * Build up the search block ID list. The block ID consists of a logical898 * block number and a hardware specific part. The hardware specific part899 * helps the tape drive to speed up searching for a specific block.900 */901static void902tape_34xx_add_sbid(struct tape_device *device, struct tape_34xx_block_id bid)903{904	struct list_head *	sbid_list;905	struct tape_34xx_sbid *	sbid;906	struct list_head *	l;907 908	/*909	 * immediately return if there is no list at all or the block to add910	 * is located in segment 1 of wrap 0 because this position is used911	 * if no hardware position data is supplied.912	 */913	sbid_list = (struct list_head *) device->discdata;914	if (!sbid_list || (bid.segment < 2 && bid.wrap == 0))915		return;916 917	/*918	 * Search the position where to insert the new entry. Hardware919	 * acceleration uses only the segment and wrap number. So we920	 * need only one entry for a specific wrap/segment combination.921	 * If there is a block with a lower number but the same hard-922	 * ware position data we just update the block number in the923	 * existing entry.924	 */925	list_for_each(l, sbid_list) {926		sbid = list_entry(l, struct tape_34xx_sbid, list);927 928		if (929			(sbid->bid.segment == bid.segment) &&930			(sbid->bid.wrap    == bid.wrap)931		) {932			if (bid.block < sbid->bid.block)933				sbid->bid = bid;934			else return;935			break;936		}937 938		/* Sort in according to logical block number. */939		if (bid.block < sbid->bid.block) {940			tape_34xx_append_new_sbid(bid, l->prev);941			break;942		}943	}944	/* List empty or new block bigger than last entry. */945	if (l == sbid_list)946		tape_34xx_append_new_sbid(bid, l->prev);947 948	DBF_LH(4, "Current list is:\n");949	list_for_each(l, sbid_list) {950		sbid = list_entry(l, struct tape_34xx_sbid, list);951		DBF_LH(4, "%d:%03d@%05d\n",952			sbid->bid.wrap,953			sbid->bid.segment,954			sbid->bid.block955		);956	}957}958 959/*960 * Delete all entries from the search block ID list that belong to tape blocks961 * equal or higher than the given number.962 */963static void964tape_34xx_delete_sbid_from(struct tape_device *device, int from)965{966	struct list_head *	sbid_list;967	struct tape_34xx_sbid *	sbid;968	struct list_head *	l;969	struct list_head *	n;970 971	sbid_list = (struct list_head *) device->discdata;972	if (!sbid_list)973		return;974 975	list_for_each_safe(l, n, sbid_list) {976		sbid = list_entry(l, struct tape_34xx_sbid, list);977		if (sbid->bid.block >= from) {978			DBF_LH(4, "Delete sbid %d:%03d@%05d\n",979				sbid->bid.wrap,980				sbid->bid.segment,981				sbid->bid.block982			);983			list_del(l);984			kfree(sbid);985		}986	}987}988 989/*990 * Merge hardware position data into a block id.991 */992static void993tape_34xx_merge_sbid(994	struct tape_device *		device,995	struct tape_34xx_block_id *	bid996) {997	struct tape_34xx_sbid *	sbid;998	struct tape_34xx_sbid *	sbid_to_use;999	struct list_head *	sbid_list;1000	struct list_head *	l;1001 1002	sbid_list = (struct list_head *) device->discdata;1003	bid->wrap    = 0;1004	bid->segment = 1;1005 1006	if (!sbid_list || list_empty(sbid_list))1007		return;1008 1009	sbid_to_use = NULL;1010	list_for_each(l, sbid_list) {1011		sbid = list_entry(l, struct tape_34xx_sbid, list);1012 1013		if (sbid->bid.block >= bid->block)1014			break;1015		sbid_to_use = sbid;1016	}1017	if (sbid_to_use) {1018		bid->wrap    = sbid_to_use->bid.wrap;1019		bid->segment = sbid_to_use->bid.segment;1020		DBF_LH(4, "Use %d:%03d@%05d for %05d\n",1021			sbid_to_use->bid.wrap,1022			sbid_to_use->bid.segment,1023			sbid_to_use->bid.block,1024			bid->block1025		);1026	}1027}1028 1029static int1030tape_34xx_setup_device(struct tape_device * device)1031{1032	int			rc;1033	struct list_head *	discdata;1034 1035	DBF_EVENT(6, "34xx device setup\n");1036	if ((rc = tape_std_assign(device)) == 0) {1037		if ((rc = tape_34xx_medium_sense(device)) != 0) {1038			DBF_LH(3, "34xx medium sense returned %d\n", rc);1039		}1040	}1041	discdata = kmalloc(sizeof(struct list_head), GFP_KERNEL);1042	if (discdata) {1043			INIT_LIST_HEAD(discdata);1044			device->discdata = discdata;1045	}1046 1047	return rc;1048}1049 1050static void1051tape_34xx_cleanup_device(struct tape_device *device)1052{1053	tape_std_unassign(device);1054	1055	if (device->discdata) {1056		tape_34xx_delete_sbid_from(device, 0);1057		kfree(device->discdata);1058		device->discdata = NULL;1059	}1060}1061 1062 1063/*1064 * MTTELL: Tell block. Return the number of block relative to current file.1065 */1066static int1067tape_34xx_mttell(struct tape_device *device, int mt_count)1068{1069	struct {1070		struct tape_34xx_block_id	cbid;1071		struct tape_34xx_block_id	dbid;1072	} __attribute__ ((packed)) block_id;1073	int rc;1074 1075	rc = tape_std_read_block_id(device, (__u64 *) &block_id);1076	if (rc)1077		return rc;1078 1079	tape_34xx_add_sbid(device, block_id.cbid);1080	return block_id.cbid.block;1081}1082 1083/*1084 * MTSEEK: seek to the specified block.1085 */1086static int1087tape_34xx_mtseek(struct tape_device *device, int mt_count)1088{1089	struct tape_request *request;1090	struct tape_34xx_block_id *	bid;1091 1092	if (mt_count > 0x3fffff) {1093		DBF_EXCEPTION(6, "xsee parm\n");1094		return -EINVAL;1095	}1096	request = tape_alloc_request(3, 4);1097	if (IS_ERR(request))1098		return PTR_ERR(request);1099 1100	/* setup ccws */1101	request->op = TO_LBL;1102	bid         = (struct tape_34xx_block_id *) request->cpdata;1103	bid->format = (*device->modeset_byte & 0x08) ?1104			TAPE34XX_FMT_3480_XF : TAPE34XX_FMT_3480;1105	bid->block  = mt_count;1106	tape_34xx_merge_sbid(device, bid);1107 1108	tape_ccw_cc(request->cpaddr, MODE_SET_DB, 1, device->modeset_byte);1109	tape_ccw_cc(request->cpaddr + 1, LOCATE, 4, request->cpdata);1110	tape_ccw_end(request->cpaddr + 2, NOP, 0, NULL);1111 1112	/* execute it */1113	return tape_do_io_free(device, request);1114}1115 1116/*1117 * List of 3480/3490 magnetic tape commands.1118 */1119static tape_mtop_fn tape_34xx_mtop[TAPE_NR_MTOPS] = {1120	[MTRESET]	 = tape_std_mtreset,1121	[MTFSF]		 = tape_std_mtfsf,1122	[MTBSF]		 = tape_std_mtbsf,1123	[MTFSR]		 = tape_std_mtfsr,1124	[MTBSR]		 = tape_std_mtbsr,1125	[MTWEOF]	 = tape_std_mtweof,1126	[MTREW]		 = tape_std_mtrew,1127	[MTOFFL]	 = tape_std_mtoffl,1128	[MTNOP]		 = tape_std_mtnop,1129	[MTRETEN]	 = tape_std_mtreten,1130	[MTBSFM]	 = tape_std_mtbsfm,1131	[MTFSFM]	 = tape_std_mtfsfm,1132	[MTEOM]		 = tape_std_mteom,1133	[MTERASE]	 = tape_std_mterase,1134	[MTRAS1]	 = NULL,1135	[MTRAS2]	 = NULL,1136	[MTRAS3]	 = NULL,1137	[MTSETBLK]	 = tape_std_mtsetblk,1138	[MTSETDENSITY]	 = NULL,1139	[MTSEEK]	 = tape_34xx_mtseek,1140	[MTTELL]	 = tape_34xx_mttell,1141	[MTSETDRVBUFFER] = NULL,1142	[MTFSS]		 = NULL,1143	[MTBSS]		 = NULL,1144	[MTWSM]		 = NULL,1145	[MTLOCK]	 = NULL,1146	[MTUNLOCK]	 = NULL,1147	[MTLOAD]	 = tape_std_mtload,1148	[MTUNLOAD]	 = tape_std_mtunload,1149	[MTCOMPRESSION]	 = tape_std_mtcompression,1150	[MTSETPART]	 = NULL,1151	[MTMKPART]	 = NULL1152};1153 1154/*1155 * Tape discipline structure for 3480 and 3490.1156 */1157static struct tape_discipline tape_discipline_34xx = {1158	.owner = THIS_MODULE,1159	.setup_device = tape_34xx_setup_device,1160	.cleanup_device = tape_34xx_cleanup_device,1161	.process_eov = tape_std_process_eov,1162	.irq = tape_34xx_irq,1163	.read_block = tape_std_read_block,1164	.write_block = tape_std_write_block,1165	.ioctl_fn = tape_34xx_ioctl,1166	.mtop_array = tape_34xx_mtop1167};1168 1169static struct ccw_device_id tape_34xx_ids[] = {1170	{ CCW_DEVICE_DEVTYPE(0x3480, 0, 0x3480, 0), .driver_info = tape_3480},1171	{ CCW_DEVICE_DEVTYPE(0x3490, 0, 0x3490, 0), .driver_info = tape_3490},1172	{ /* end of list */ },1173};1174 1175static int1176tape_34xx_online(struct ccw_device *cdev)1177{1178	return tape_generic_online(1179		dev_get_drvdata(&cdev->dev),1180		&tape_discipline_34xx1181	);1182}1183 1184static struct ccw_driver tape_34xx_driver = {1185	.driver = {1186		.name = "tape_34xx",1187		.owner = THIS_MODULE,1188	},1189	.ids = tape_34xx_ids,1190	.probe = tape_generic_probe,1191	.remove = tape_generic_remove,1192	.set_online = tape_34xx_online,1193	.set_offline = tape_generic_offline,1194	.int_class = IRQIO_TAP,1195};1196 1197static int1198tape_34xx_init (void)1199{1200	int rc;1201 1202	TAPE_DBF_AREA = debug_register ( "tape_34xx", 2, 2, 4*sizeof(long));1203	debug_register_view(TAPE_DBF_AREA, &debug_sprintf_view);1204#ifdef DBF_LIKE_HELL1205	debug_set_level(TAPE_DBF_AREA, 6);1206#endif1207 1208	DBF_EVENT(3, "34xx init\n");1209	/* Register driver for 3480/3490 tapes. */1210	rc = ccw_driver_register(&tape_34xx_driver);1211	if (rc)1212		DBF_EVENT(3, "34xx init failed\n");1213	else1214		DBF_EVENT(3, "34xx registered\n");1215	return rc;1216}1217 1218static void1219tape_34xx_exit(void)1220{1221	ccw_driver_unregister(&tape_34xx_driver);1222 1223	debug_unregister(TAPE_DBF_AREA);1224}1225 1226MODULE_DEVICE_TABLE(ccw, tape_34xx_ids);1227MODULE_AUTHOR("(C) 2001-2002 IBM Deutschland Entwicklung GmbH");1228MODULE_DESCRIPTION("Linux on zSeries channel attached 3480 tape device driver");1229MODULE_LICENSE("GPL");1230 1231module_init(tape_34xx_init);1232module_exit(tape_34xx_exit);1233