lcs.c (c203e45f069af47ca7623e4dcd8c00bfba2722e4) lcs.c (23d805b647db6c2063a13089497615efa9deacdd)
1/*
2 * linux/drivers/s390/net/lcs.c
3 *
4 * Linux for S/390 Lan Channel Station Network Driver
5 *
6 * Copyright (C) 1999-2001 IBM Deutschland Entwicklung GmbH,
7 * IBM Corporation
8 * Author(s): Original Code written by

--- 1313 unchanged lines hidden (view full) ---

1322
1323static int
1324lcs_get_problem(struct ccw_device *cdev, struct irb *irb)
1325{
1326 int dstat, cstat;
1327 char *sense;
1328
1329 sense = (char *) irb->ecw;
1/*
2 * linux/drivers/s390/net/lcs.c
3 *
4 * Linux for S/390 Lan Channel Station Network Driver
5 *
6 * Copyright (C) 1999-2001 IBM Deutschland Entwicklung GmbH,
7 * IBM Corporation
8 * Author(s): Original Code written by

--- 1313 unchanged lines hidden (view full) ---

1322
1323static int
1324lcs_get_problem(struct ccw_device *cdev, struct irb *irb)
1325{
1326 int dstat, cstat;
1327 char *sense;
1328
1329 sense = (char *) irb->ecw;
1330 cstat = irb->scsw.cstat;
1331 dstat = irb->scsw.dstat;
1330 cstat = irb->scsw.cmd.cstat;
1331 dstat = irb->scsw.cmd.dstat;
1332
1333 if (cstat & (SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK |
1334 SCHN_STAT_CHN_DATA_CHK | SCHN_STAT_CHAIN_CHECK |
1335 SCHN_STAT_PROT_CHECK | SCHN_STAT_PROG_CHECK)) {
1336 LCS_DBF_TEXT(2, trace, "CGENCHK");
1337 return 1;
1338 }
1339 if (dstat & DEV_STAT_UNIT_CHECK) {

--- 43 unchanged lines hidden (view full) ---

1383 return;
1384
1385 card = CARD_FROM_DEV(cdev);
1386 if (card->read.ccwdev == cdev)
1387 channel = &card->read;
1388 else
1389 channel = &card->write;
1390
1332
1333 if (cstat & (SCHN_STAT_CHN_CTRL_CHK | SCHN_STAT_INTF_CTRL_CHK |
1334 SCHN_STAT_CHN_DATA_CHK | SCHN_STAT_CHAIN_CHECK |
1335 SCHN_STAT_PROT_CHECK | SCHN_STAT_PROG_CHECK)) {
1336 LCS_DBF_TEXT(2, trace, "CGENCHK");
1337 return 1;
1338 }
1339 if (dstat & DEV_STAT_UNIT_CHECK) {

--- 43 unchanged lines hidden (view full) ---

1383 return;
1384
1385 card = CARD_FROM_DEV(cdev);
1386 if (card->read.ccwdev == cdev)
1387 channel = &card->read;
1388 else
1389 channel = &card->write;
1390
1391 cstat = irb->scsw.cstat;
1392 dstat = irb->scsw.dstat;
1391 cstat = irb->scsw.cmd.cstat;
1392 dstat = irb->scsw.cmd.dstat;
1393 LCS_DBF_TEXT_(5, trace, "Rint%s",cdev->dev.bus_id);
1393 LCS_DBF_TEXT_(5, trace, "Rint%s",cdev->dev.bus_id);
1394 LCS_DBF_TEXT_(5, trace, "%4x%4x",irb->scsw.cstat, irb->scsw.dstat);
1395 LCS_DBF_TEXT_(5, trace, "%4x%4x",irb->scsw.fctl, irb->scsw.actl);
1394 LCS_DBF_TEXT_(5, trace, "%4x%4x", irb->scsw.cmd.cstat,
1395 irb->scsw.cmd.dstat);
1396 LCS_DBF_TEXT_(5, trace, "%4x%4x", irb->scsw.cmd.fctl,
1397 irb->scsw.cmd.actl);
1396
1397 /* Check for channel and device errors presented */
1398 rc = lcs_get_problem(cdev, irb);
1399 if (rc || (dstat & DEV_STAT_UNIT_EXCEP)) {
1400 PRINT_WARN("check on device %s, dstat=0x%X, cstat=0x%X \n",
1401 cdev->dev.bus_id, dstat, cstat);
1402 if (rc) {
1403 channel->state = LCS_CH_STATE_ERROR;
1404 }
1405 }
1406 if (channel->state == LCS_CH_STATE_ERROR) {
1407 lcs_schedule_recovery(card);
1408 wake_up(&card->wait_q);
1409 return;
1410 }
1411 /* How far in the ccw chain have we processed? */
1412 if ((channel->state != LCS_CH_STATE_INIT) &&
1398
1399 /* Check for channel and device errors presented */
1400 rc = lcs_get_problem(cdev, irb);
1401 if (rc || (dstat & DEV_STAT_UNIT_EXCEP)) {
1402 PRINT_WARN("check on device %s, dstat=0x%X, cstat=0x%X \n",
1403 cdev->dev.bus_id, dstat, cstat);
1404 if (rc) {
1405 channel->state = LCS_CH_STATE_ERROR;
1406 }
1407 }
1408 if (channel->state == LCS_CH_STATE_ERROR) {
1409 lcs_schedule_recovery(card);
1410 wake_up(&card->wait_q);
1411 return;
1412 }
1413 /* How far in the ccw chain have we processed? */
1414 if ((channel->state != LCS_CH_STATE_INIT) &&
1413 (irb->scsw.fctl & SCSW_FCTL_START_FUNC)) {
1414 index = (struct ccw1 *) __va((addr_t) irb->scsw.cpa)
1415 (irb->scsw.cmd.fctl & SCSW_FCTL_START_FUNC)) {
1416 index = (struct ccw1 *) __va((addr_t) irb->scsw.cmd.cpa)
1415 - channel->ccws;
1417 - channel->ccws;
1416 if ((irb->scsw.actl & SCSW_ACTL_SUSPENDED) ||
1417 (irb->scsw.cstat & SCHN_STAT_PCI))
1418 if ((irb->scsw.cmd.actl & SCSW_ACTL_SUSPENDED) ||
1419 (irb->scsw.cmd.cstat & SCHN_STAT_PCI))
1418 /* Bloody io subsystem tells us lies about cpa... */
1419 index = (index - 1) & (LCS_NUM_BUFFS - 1);
1420 while (channel->io_idx != index) {
1421 __lcs_processed_buffer(channel,
1422 channel->iob + channel->io_idx);
1423 channel->io_idx =
1424 (channel->io_idx + 1) & (LCS_NUM_BUFFS - 1);
1425 }
1426 }
1427
1420 /* Bloody io subsystem tells us lies about cpa... */
1421 index = (index - 1) & (LCS_NUM_BUFFS - 1);
1422 while (channel->io_idx != index) {
1423 __lcs_processed_buffer(channel,
1424 channel->iob + channel->io_idx);
1425 channel->io_idx =
1426 (channel->io_idx + 1) & (LCS_NUM_BUFFS - 1);
1427 }
1428 }
1429
1428 if ((irb->scsw.dstat & DEV_STAT_DEV_END) ||
1429 (irb->scsw.dstat & DEV_STAT_CHN_END) ||
1430 (irb->scsw.dstat & DEV_STAT_UNIT_CHECK))
1430 if ((irb->scsw.cmd.dstat & DEV_STAT_DEV_END) ||
1431 (irb->scsw.cmd.dstat & DEV_STAT_CHN_END) ||
1432 (irb->scsw.cmd.dstat & DEV_STAT_UNIT_CHECK))
1431 /* Mark channel as stopped. */
1432 channel->state = LCS_CH_STATE_STOPPED;
1433 /* Mark channel as stopped. */
1434 channel->state = LCS_CH_STATE_STOPPED;
1433 else if (irb->scsw.actl & SCSW_ACTL_SUSPENDED)
1435 else if (irb->scsw.cmd.actl & SCSW_ACTL_SUSPENDED)
1434 /* CCW execution stopped on a suspend bit. */
1435 channel->state = LCS_CH_STATE_SUSPENDED;
1436 /* CCW execution stopped on a suspend bit. */
1437 channel->state = LCS_CH_STATE_SUSPENDED;
1436 if (irb->scsw.fctl & SCSW_FCTL_HALT_FUNC) {
1437 if (irb->scsw.cc != 0) {
1438 if (irb->scsw.cmd.fctl & SCSW_FCTL_HALT_FUNC) {
1439 if (irb->scsw.cmd.cc != 0) {
1438 ccw_device_halt(channel->ccwdev, (addr_t) channel);
1439 return;
1440 }
1441 /* The channel has been stopped by halt_IO. */
1442 channel->state = LCS_CH_STATE_HALTED;
1443 }
1440 ccw_device_halt(channel->ccwdev, (addr_t) channel);
1441 return;
1442 }
1443 /* The channel has been stopped by halt_IO. */
1444 channel->state = LCS_CH_STATE_HALTED;
1445 }
1444 if (irb->scsw.fctl & SCSW_FCTL_CLEAR_FUNC) {
1446 if (irb->scsw.cmd.fctl & SCSW_FCTL_CLEAR_FUNC)
1445 channel->state = LCS_CH_STATE_CLEARED;
1447 channel->state = LCS_CH_STATE_CLEARED;
1446 }
1447 /* Do the rest in the tasklet. */
1448 tasklet_schedule(&channel->irq_tasklet);
1449}
1450
1451/**
1452 * Tasklet for IRQ handler
1453 */
1454static void

--- 888 unchanged lines hidden ---
1448 /* Do the rest in the tasklet. */
1449 tasklet_schedule(&channel->irq_tasklet);
1450}
1451
1452/**
1453 * Tasklet for IRQ handler
1454 */
1455static void

--- 888 unchanged lines hidden ---