Skip to content

Commit 41c8617

Browse files
committed
Fix 3880/3990 control unit chaining requirement check:
Closes GitHub Issue #660
1 parent 38c9c16 commit 41c8617

File tree

4 files changed

+80
-141
lines changed

4 files changed

+80
-141
lines changed

ckddasd.c

+73-139
Original file line numberDiff line numberDiff line change
@@ -660,7 +660,9 @@ BYTE serial[12+1] = {0}; /* Dasd serial number */
660660
/* Set number of sense bytes according to controller specification */
661661
dev->numsense = dev->ckdcu->senselength;
662662

663-
/* Set flag bit if 3990 controller */
663+
/* Set flag bit if 3880/3990 controller */
664+
if (dev->ckdcu->devt == 0x3880)
665+
dev->ckd3880 = 1;
664666
if (dev->ckdcu->devt == 0x3990)
665667
dev->ckd3990 = 1;
666668

@@ -2276,6 +2278,37 @@ int rc; /* Return code */
22762278
return 0;
22772279
} /* end function ckd_write_data */
22782280

2281+
2282+
/*-------------------------------------------------------------------*/
2283+
/* ckd chaining requirement check: returns 0 = okay, -1 = error */
2284+
/*-------------------------------------------------------------------*/
2285+
int ckd_chaining_check( DEVBLK* dev, BYTE* unitstat)
2286+
{
2287+
/* For 3990, command reject if not preceded by Seek, Seek Cyl,
2288+
Locate Record, Read IPL, or Recalibrate command. The same
2289+
requirement is in place for 3880 with FC 3005. The 2105 and
2290+
later machines however, are not (yet?) considered.
2291+
*/
2292+
if (1
2293+
&& (0
2294+
|| dev->ckd3880
2295+
|| dev->ckd3990
2296+
)
2297+
&& !dev->ckdseek
2298+
&& !dev->ckdskcyl
2299+
&& !dev->ckdlocat
2300+
&& !dev->ckdrdipl
2301+
&& !dev->ckdrecal
2302+
)
2303+
{
2304+
ckd_build_sense( dev, SENSE_CR, 0, 0, FORMAT_2, MESSAGE_2 );
2305+
*unitstat = CSW_CE | CSW_DE | CSW_UC;
2306+
return -1;
2307+
}
2308+
return 0;
2309+
}
2310+
2311+
22792312
/*-------------------------------------------------------------------*/
22802313
/* Forward references to static helper functions */
22812314
/*-------------------------------------------------------------------*/
@@ -2322,6 +2355,7 @@ static bool DefineExtent
23222355
U32* residual
23232356
);
23242357

2358+
23252359
/*-------------------------------------------------------------------*/
23262360
/* Execute a Channel Command Word */
23272361
/*-------------------------------------------------------------------*/
@@ -2453,7 +2487,7 @@ BYTE trk_ovfl; /* == 1 if track ovfl write */
24532487
&& code != 0xDE // READ TRACK
24542488
)
24552489
{
2456-
ckd_build_sense( dev, SENSE_CR, 0, 0,FORMAT_0, MESSAGE_2 );
2490+
ckd_build_sense( dev, SENSE_CR, 0, 0, FORMAT_0, MESSAGE_2 );
24572491
*unitstat = CSW_CE | CSW_DE | CSW_UC;
24582492
return;
24592493
}
@@ -2562,21 +2596,10 @@ BYTE trk_ovfl; /* == 1 if track ovfl write */
25622596
/*---------------------------------------------------------------*/
25632597
/* READ DATA */
25642598
/*---------------------------------------------------------------*/
2565-
/* For 3990, command reject if not preceded by Seek, Seek Cyl,
2566-
Locate Record, Read IPL, or Recalibrate command */
2567-
if (1
2568-
&& dev->ckd3990
2569-
&& !dev->ckdseek
2570-
&& !dev->ckdskcyl
2571-
&& !dev->ckdlocat
2572-
&& !dev->ckdrdipl
2573-
&& !dev->ckdrecal
2574-
)
2575-
{
2576-
ckd_build_sense( dev, SENSE_CR, 0, 0, FORMAT_0, MESSAGE_2 );
2577-
*unitstat = CSW_CE | CSW_DE | CSW_UC;
2599+
2600+
/* Check for invalid command sequence */
2601+
if (ckd_chaining_check( dev, unitstat ))
25782602
break;
2579-
}
25802603

25812604
/* Check operation code if within domain of a Locate Record */
25822605
if (dev->ckdlcount > 0)
@@ -2677,17 +2700,10 @@ BYTE trk_ovfl; /* == 1 if track ovfl write */
26772700
/*---------------------------------------------------------------*/
26782701
/* READ KEY AND DATA */
26792702
/*---------------------------------------------------------------*/
2680-
/* For 3990, command reject if not preceded by Seek, Seek Cyl,
2681-
Locate Record, Read IPL, or Recalibrate command */
2682-
if (dev->ckd3990
2683-
&& dev->ckdseek == 0 && dev->ckdskcyl == 0
2684-
&& dev->ckdlocat == 0 && dev->ckdrdipl == 0
2685-
&& dev->ckdrecal == 0)
2686-
{
2687-
ckd_build_sense( dev, SENSE_CR, 0, 0, FORMAT_0, MESSAGE_2 );
2688-
*unitstat = CSW_CE | CSW_DE | CSW_UC;
2703+
2704+
/* Check for invalid command sequence */
2705+
if (ckd_chaining_check( dev, unitstat ))
26892706
break;
2690-
}
26912707

26922708
/* Check operation code if within domain of a Locate Record */
26932709
if (dev->ckdlcount > 0)
@@ -2783,17 +2799,10 @@ BYTE trk_ovfl; /* == 1 if track ovfl write */
27832799
/*---------------------------------------------------------------*/
27842800
/* READ COUNT */
27852801
/*---------------------------------------------------------------*/
2786-
/* For 3990, command reject if not preceded by Seek, Seek Cyl,
2787-
Locate Record, Read IPL, or Recalibrate command */
2788-
if (dev->ckd3990
2789-
&& dev->ckdseek == 0 && dev->ckdskcyl == 0
2790-
&& dev->ckdlocat == 0 && dev->ckdrdipl == 0
2791-
&& dev->ckdrecal == 0)
2792-
{
2793-
ckd_build_sense( dev, SENSE_CR, 0, 0, FORMAT_0, MESSAGE_2 );
2794-
*unitstat = CSW_CE | CSW_DE | CSW_UC;
2802+
2803+
/* Check for invalid command sequence */
2804+
if (ckd_chaining_check( dev, unitstat ))
27952805
break;
2796-
}
27972806

27982807
/* Check operation code if within domain of a Locate Record */
27992808
if (dev->ckdlcount > 0)
@@ -2853,17 +2862,10 @@ BYTE trk_ovfl; /* == 1 if track ovfl write */
28532862
/*---------------------------------------------------------------*/
28542863
/* READ RECORD ZERO */
28552864
/*---------------------------------------------------------------*/
2856-
/* For 3990, command reject if not preceded by Seek, Seek Cyl,
2857-
Locate Record, Read IPL, or Recalibrate command */
2858-
if (dev->ckd3990
2859-
&& dev->ckdseek == 0 && dev->ckdskcyl == 0
2860-
&& dev->ckdlocat == 0 && dev->ckdrdipl == 0
2861-
&& dev->ckdrecal == 0)
2862-
{
2863-
ckd_build_sense( dev, SENSE_CR, 0, 0, FORMAT_0, MESSAGE_2 );
2864-
*unitstat = CSW_CE | CSW_DE | CSW_UC;
2865+
2866+
/* Check for invalid command sequence */
2867+
if (ckd_chaining_check( dev, unitstat ))
28652868
break;
2866-
}
28672869

28682870
/* Check operation code if within domain of a Locate Record */
28692871
if (dev->ckdlcount > 0)
@@ -2984,20 +2986,9 @@ BYTE trk_ovfl; /* == 1 if track ovfl write */
29842986
break;
29852987
}
29862988

2987-
/* For 3990, command reject if not preceded by Seek, Seek Cyl,
2988-
Locate Record, Read IPL, or Recalibrate command. The same
2989-
requirement is in place for 3880 with FC 3005. The 2105 and
2990-
later machines however, are not (yet?) considered.
2991-
*/
2992-
if ((dev->ckd3990 || dev->ckdcu->devt == 0x3880)
2993-
&& dev->ckdseek == 0 && dev->ckdskcyl == 0
2994-
&& dev->ckdlocat == 0 && dev->ckdrdipl == 0
2995-
&& dev->ckdrecal == 0)
2996-
{
2997-
ckd_build_sense( dev, SENSE_CR, 0, 0, FORMAT_0, MESSAGE_2 );
2998-
*unitstat = CSW_CE | CSW_DE | CSW_UC;
2989+
/* Check for invalid command sequence */
2990+
if (ckd_chaining_check( dev, unitstat ))
29992991
break;
3000-
}
30012992

30022993
/* Check operation code if within domain of a Locate Record */
30032994
if (dev->ckdlcount > 0)
@@ -3091,17 +3082,10 @@ BYTE trk_ovfl; /* == 1 if track ovfl write */
30913082
/*---------------------------------------------------------------*/
30923083
/* READ HOME ADDRESS */
30933084
/*---------------------------------------------------------------*/
3094-
/* For 3990, command reject if not preceded by Seek, Seek Cyl,
3095-
Locate Record, Read IPL, or Recalibrate command */
3096-
if (dev->ckd3990
3097-
&& dev->ckdseek == 0 && dev->ckdskcyl == 0
3098-
&& dev->ckdlocat == 0 && dev->ckdrdipl == 0
3099-
&& dev->ckdrecal == 0)
3100-
{
3101-
ckd_build_sense( dev, SENSE_CR, 0, 0, FORMAT_0, MESSAGE_2 );
3102-
*unitstat = CSW_CE | CSW_DE | CSW_UC;
3085+
3086+
/* Check for invalid command sequence */
3087+
if (ckd_chaining_check( dev, unitstat ))
31033088
break;
3104-
}
31053089

31063090
/* Check operation code if within domain of a Locate Record */
31073091
if (dev->ckdlcount > 0)
@@ -3164,17 +3148,10 @@ BYTE trk_ovfl; /* == 1 if track ovfl write */
31643148
so the IBM HA and Hercules 'track header' have identical
31653149
contents.
31663150
*/
3167-
/* For 3990, command reject if not preceded by Seek, Seek Cyl,
3168-
Locate Record, Read IPL, or Recalibrate command */
3169-
if (dev->ckd3990
3170-
&& dev->ckdseek == 0 && dev->ckdskcyl == 0
3171-
&& dev->ckdlocat == 0 && dev->ckdrdipl == 0
3172-
&& dev->ckdrecal == 0)
3173-
{
3174-
ckd_build_sense( dev, SENSE_CR, 0, 0, FORMAT_0, MESSAGE_2 );
3175-
*unitstat = CSW_CE | CSW_DE | CSW_UC;
3151+
3152+
/* Check for invalid command sequence */
3153+
if (ckd_chaining_check( dev, unitstat ))
31763154
break;
3177-
}
31783155

31793156
/* Check operation code if within domain of a Locate Record */
31803157
if (dev->ckdlcount > 0)
@@ -3227,17 +3204,10 @@ BYTE trk_ovfl; /* == 1 if track ovfl write */
32273204
/*---------------------------------------------------------------*/
32283205
/* READ COUNT KEY AND DATA */
32293206
/*---------------------------------------------------------------*/
3230-
/* For 3990, command reject if not preceded by Seek, Seek Cyl,
3231-
Locate Record, Read IPL, or Recalibrate command */
3232-
if (dev->ckd3990
3233-
&& dev->ckdseek == 0 && dev->ckdskcyl == 0
3234-
&& dev->ckdlocat == 0 && dev->ckdrdipl == 0
3235-
&& dev->ckdrecal == 0)
3236-
{
3237-
ckd_build_sense( dev, SENSE_CR, 0, 0, FORMAT_0, MESSAGE_2 );
3238-
*unitstat = CSW_CE | CSW_DE | CSW_UC;
3207+
3208+
/* Check for invalid command sequence */
3209+
if (ckd_chaining_check( dev, unitstat ))
32393210
break;
3240-
}
32413211

32423212
/* Check operation code if within domain of a Locate Record */
32433213
if (dev->ckdlcount > 0)
@@ -3333,17 +3303,10 @@ BYTE trk_ovfl; /* == 1 if track ovfl write */
33333303
/*---------------------------------------------------------------*/
33343304
/* READ MULTIPLE COUNT KEY AND DATA */
33353305
/*---------------------------------------------------------------*/
3336-
/* For 3990, command reject if not preceded by Seek, Seek Cyl,
3337-
Locate Record, Read IPL, or Recalibrate */
3338-
if (dev->ckd3990
3339-
&& dev->ckdseek == 0 && dev->ckdskcyl == 0
3340-
&& dev->ckdlocat == 0 && dev->ckdrdipl == 0
3341-
&& dev->ckdrecal == 0)
3342-
{
3343-
ckd_build_sense( dev, SENSE_CR, 0, 0, FORMAT_0, MESSAGE_2 );
3344-
*unitstat = CSW_CE | CSW_DE | CSW_UC;
3306+
3307+
/* Check for invalid command sequence */
3308+
if (ckd_chaining_check( dev, unitstat ))
33453309
break;
3346-
}
33473310

33483311
/* Command reject if within the domain of a Locate Record */
33493312
if (dev->ckdlcount > 0)
@@ -3851,17 +3814,9 @@ BYTE trk_ovfl; /* == 1 if track ovfl write */
38513814
break;
38523815
}
38533816

3854-
/* For 3990, command reject if not preceded by Seek, Seek Cyl,
3855-
Locate Record, Read IPL, or Recalibrate command */
3856-
if (dev->ckd3990
3857-
&& dev->ckdseek == 0 && dev->ckdskcyl == 0
3858-
&& dev->ckdlocat == 0 && dev->ckdrdipl == 0
3859-
&& dev->ckdrecal == 0)
3860-
{
3861-
ckd_build_sense( dev, SENSE_CR, 0, 0, FORMAT_0, MESSAGE_2 );
3862-
*unitstat = CSW_CE | CSW_DE | CSW_UC;
3817+
/* Check for invalid command sequence */
3818+
if (ckd_chaining_check( dev, unitstat ))
38633819
break;
3864-
}
38653820

38663821
/* Set residual count */
38673822
num = (count < 1) ? count : 1;
@@ -3885,17 +3840,10 @@ BYTE trk_ovfl; /* == 1 if track ovfl write */
38853840
/*---------------------------------------------------------------*/
38863841
/* SEARCH KEY */
38873842
/*---------------------------------------------------------------*/
3888-
/* For 3990, command reject if not preceded by Seek, Seek Cyl,
3889-
Locate Record, Read IPL, or Recalibrate command */
3890-
if (dev->ckd3990
3891-
&& dev->ckdseek == 0 && dev->ckdskcyl == 0
3892-
&& dev->ckdlocat == 0 && dev->ckdrdipl == 0
3893-
&& dev->ckdrecal == 0)
3894-
{
3895-
ckd_build_sense( dev, SENSE_CR, 0, 0, FORMAT_0, MESSAGE_2 );
3896-
*unitstat = CSW_CE | CSW_DE | CSW_UC;
3843+
3844+
/* Check for invalid command sequence */
3845+
if (ckd_chaining_check( dev, unitstat ))
38973846
break;
3898-
}
38993847

39003848
/* Command reject if within the domain of a Locate Record */
39013849
if (dev->ckdlcount > 0)
@@ -3968,17 +3916,10 @@ BYTE trk_ovfl; /* == 1 if track ovfl write */
39683916
/*---------------------------------------------------------------*/
39693917
/* SEARCH ID */
39703918
/*---------------------------------------------------------------*/
3971-
/* For 3990, command reject if not preceded by Seek, Seek Cyl,
3972-
Locate Record, Read IPL, or Recalibrate command */
3973-
if (dev->ckd3990
3974-
&& dev->ckdseek == 0 && dev->ckdskcyl == 0
3975-
&& dev->ckdlocat == 0 && dev->ckdrdipl == 0
3976-
&& dev->ckdrecal == 0)
3977-
{
3978-
ckd_build_sense( dev, SENSE_CR, 0, 0, FORMAT_0, MESSAGE_2 );
3979-
*unitstat = CSW_CE | CSW_DE | CSW_UC;
3919+
3920+
/* Check for invalid command sequence */
3921+
if (ckd_chaining_check( dev, unitstat ))
39803922
break;
3981-
}
39823923

39833924
/* Command reject if within the domain of a Locate Record */
39843925
if (dev->ckdlcount > 0)
@@ -4027,17 +3968,10 @@ BYTE trk_ovfl; /* == 1 if track ovfl write */
40273968
/*---------------------------------------------------------------*/
40283969
/* SEARCH HOME ADDRESS EQUAL */
40293970
/*---------------------------------------------------------------*/
4030-
/* For 3990, command reject if not preceded by Seek, Seek Cyl,
4031-
Locate Record, Read IPL, or Recalibrate command */
4032-
if (dev->ckd3990
4033-
&& dev->ckdseek == 0 && dev->ckdskcyl == 0
4034-
&& dev->ckdlocat == 0 && dev->ckdrdipl == 0
4035-
&& dev->ckdrecal == 0)
4036-
{
4037-
ckd_build_sense( dev, SENSE_CR, 0, 0, FORMAT_0, MESSAGE_2 );
4038-
*unitstat = CSW_CE | CSW_DE | CSW_UC;
3971+
3972+
/* Check for invalid command sequence */
3973+
if (ckd_chaining_check( dev, unitstat ))
40393974
break;
4040-
}
40413975

40423976
/* Command reject if within the domain of a Locate Record */
40433977
if (dev->ckdlcount > 0)

ckddasd64.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -484,7 +484,9 @@ BYTE serial[12+1] = {0}; /* Dasd serial number */
484484
/* Set number of sense bytes according to controller specification */
485485
dev->numsense = dev->ckdcu->senselength;
486486

487-
/* Set flag bit if 3990 controller */
487+
/* Set flag bit if 3880/3990 controller */
488+
if (dev->ckdcu->devt == 0x3880)
489+
dev->ckd3880 = 1;
488490
if (dev->ckdcu->devt == 0x3990)
489491
dev->ckd3990 = 1;
490492

hstructs.h

+1
Original file line numberDiff line numberDiff line change
@@ -1905,6 +1905,7 @@ struct DEVBLK { /* Device configuration block*/
19051905
BYTE devcache:1; /* 0 = device cache off
19061906
1 = device cache on */
19071907
u_int ckd3990:1; /* 1=Control unit is 3990 */
1908+
u_int ckd3880:1; /* 1=Control unit is 3880 */
19081909
u_int ckdxtdef:1; /* 1=Define Extent processed */
19091910
u_int ckdsetfm:1; /* 1=Set File Mask processed */
19101911
u_int ckdlocat:1; /* 1=Locate Record processed */

shared.c

+3-1
Original file line numberDiff line numberDiff line change
@@ -334,7 +334,9 @@ char *strtok_str = NULL; /* last position */
334334
return -1;
335335
}
336336

337-
/* Set flag bit if 3990 controller */
337+
/* Set flag bit if 3880/3990 controller */
338+
if (dev->ckdcu->devt == 0x3880)
339+
dev->ckd3880 = 1;
338340
if (dev->ckdcu->devt == 0x3990)
339341
dev->ckd3990 = 1;
340342

0 commit comments

Comments
 (0)