drivers/s390/cio/device_fsm.c

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

File Facts

System
Linux kernel
Corpus path
drivers/s390/cio/device_fsm.c
Extension
.c
Size
31450 bytes
Lines
1130
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 (!cdev->online) {
			ccw_device_update_sense_data(cdev);
			break;
		}
		cdev->private->state = DEV_STATE_OFFLINE;
		cdev->private->flags.recog_done = 1;
		if (ccw_device_test_sense_data(cdev)) {
			cdev->private->flags.donotify = 1;
			ccw_device_online(cdev);
			wake_up(&cdev->private->wait_q);
		} else {
			ccw_device_update_sense_data(cdev);
			ccw_device_sched_todo(cdev, CDEV_TODO_REBIND);
		}
		return;
	case DEV_STATE_BOXED:
		if (cdev->id.cu_type != 0) { /* device was recognized before */
			cdev->private->flags.recog_done = 1;
			cdev->private->state = DEV_STATE_BOXED;
			wake_up(&cdev->private->wait_q);
			return;
		}
		break;
	}
	cdev->private->state = state;
	io_subchannel_recog_done(cdev);
	wake_up(&cdev->private->wait_q);
}

/*
 * Function called from device_id.c after sense id has completed.
 */
void
ccw_device_sense_id_done(struct ccw_device *cdev, int err)
{
	switch (err) {
	case 0:
		ccw_device_recog_done(cdev, DEV_STATE_OFFLINE);
		break;
	case -ETIME:		/* Sense id stopped by timeout. */
		ccw_device_recog_done(cdev, DEV_STATE_BOXED);
		break;
	default:
		ccw_device_recog_done(cdev, DEV_STATE_NOT_OPER);
		break;
	}
}

/**
  * ccw_device_notify() - inform the device's driver about an event
  * @cdev: device for which an event occurred
  * @event: event that occurred
  *
  * Returns:
  *   -%EINVAL if the device is offline or has no driver.
  *   -%EOPNOTSUPP if the device's driver has no notifier registered.
  *   %NOTIFY_OK if the driver wants to keep the device.
  *   %NOTIFY_BAD if the driver doesn't want to keep the device.
  */
int ccw_device_notify(struct ccw_device *cdev, int event)
{
	int ret = -EINVAL;

	if (!cdev->drv)
		goto out;
	if (!cdev->online)
		goto out;
	CIO_MSG_EVENT(2, "notify called for 0.%x.%04x, event=%d\n",
		      cdev->private->dev_id.ssid, cdev->private->dev_id.devno,
		      event);
	if (!cdev->drv->notify) {
		ret = -EOPNOTSUPP;
		goto out;
	}
	if (cdev->drv->notify(cdev, event))
		ret = NOTIFY_OK;
	else
		ret = NOTIFY_BAD;
out:
	return ret;
}

static void ccw_device_oper_notify(struct ccw_device *cdev)
{
	struct subchannel *sch = to_subchannel(cdev->dev.parent);

	if (ccw_device_notify(cdev, CIO_OPER) == NOTIFY_OK) {
		/* Re-enable channel measurements, if needed. */
		ccw_device_sched_todo(cdev, CDEV_TODO_ENABLE_CMF);
		/* Save indication for new paths. */

Annotation

Implementation Notes