drivers/s390/cio/fcx.c

Source file repositories/reference/linux-study-clean/drivers/s390/cio/fcx.c

File Facts

System
Linux kernel
Corpus path
drivers/s390/cio/fcx.c
Extension
.c
Size
9516 bytes
Lines
354
Domain
Driver Families
Bucket
drivers/s390
Inferred role
Driver Families: exported/initcall integration point
Status
integration implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

if (tidaw[i].flags & TIDAW_FLAGS_INSERT_CBC) {
			cbc_data = 4 + ALIGN(data_count, 4) - data_count;
			cbc_count += cbc_data;
			data_count += cbc_data;
		}
	}
	return cbc_count;
}

/**
 * tcw_finalize - finalize tcw length fields and tidaw list
 * @tcw: pointer to the tcw
 * @num_tidaws: the number of tidaws used to address input/output data or zero
 * if no tida is used
 *
 * Calculate the input-/output-count and tccbl field in the tcw, add a
 * tcat the tccb and terminate the data tidaw list if used.
 *
 * Note: in case input- or output-tida is used, the tidaw-list must be stored
 * in contiguous storage (no ttic). The tcal field in the tccb must be
 * up-to-date.
 */
void tcw_finalize(struct tcw *tcw, int num_tidaws)
{
	struct tidaw *tidaw;
	struct tccb *tccb;
	struct tccb_tcat *tcat;
	u32 count;

	/* Terminate tidaw list. */
	tidaw = tcw_get_data(tcw);
	if (num_tidaws > 0)
		tidaw[num_tidaws - 1].flags |= TIDAW_FLAGS_LAST;
	/* Add tcat to tccb. */
	tccb = tcw_get_tccb(tcw);
	tcat = (struct tccb_tcat *) &tccb->tca[tca_size(tccb)];
	memset(tcat, 0, sizeof(*tcat));
	/* Calculate tcw input/output count and tcat transport count. */
	count = calc_dcw_count(tccb);
	if (tcw->w && (tcw->flags & TCW_FLAGS_OUTPUT_TIDA))
		count += calc_cbc_size(tidaw, num_tidaws);
	if (tcw->r)
		tcw->input_count = count;
	else if (tcw->w)
		tcw->output_count = count;
	tcat->count = ALIGN(count, 4) + 4;
	/* Calculate tccbl. */
	tcw->tccbl = (sizeof(struct tccb) + tca_size(tccb) +
		      sizeof(struct tccb_tcat) - 20) >> 2;
}
EXPORT_SYMBOL(tcw_finalize);

/**
 * tcw_set_intrg - set the interrogate tcw address of a tcw
 * @tcw: the tcw address
 * @intrg_tcw: the address of the interrogate tcw
 *
 * Set the address of the interrogate tcw in the specified tcw.
 */
void tcw_set_intrg(struct tcw *tcw, struct tcw *intrg_tcw)
{
	tcw->intrg = virt_to_dma32(intrg_tcw);
}
EXPORT_SYMBOL(tcw_set_intrg);

/**
 * tcw_set_data - set data address and tida flag of a tcw
 * @tcw: the tcw address
 * @data: the data address
 * @use_tidal: zero of the data address specifies a contiguous block of data,
 * non-zero if it specifies a list if tidaws.
 *
 * Set the input/output data address of a tcw (depending on the value of the
 * r-flag and w-flag). If @use_tidal is non-zero, the corresponding tida flag
 * is set as well.
 */
void tcw_set_data(struct tcw *tcw, void *data, int use_tidal)
{
	if (tcw->r) {
		tcw->input = virt_to_dma64(data);
		if (use_tidal)
			tcw->flags |= TCW_FLAGS_INPUT_TIDA;
	} else if (tcw->w) {
		tcw->output = virt_to_dma64(data);
		if (use_tidal)
			tcw->flags |= TCW_FLAGS_OUTPUT_TIDA;
	}
}
EXPORT_SYMBOL(tcw_set_data);

Annotation

Implementation Notes