View | Details | Raw Unified | Return to bug 96206
Collapse All | Expand All

(-)Makefile (-2 / +1 lines)
Lines 6-13 Link Here
6
#
6
#
7
7
8
PORTNAME=	smartmontools
8
PORTNAME=	smartmontools
9
PORTVERSION=	5.33
9
PORTVERSION=	5.36
10
PORTREVISION=	5
11
CATEGORIES=	sysutils
10
CATEGORIES=	sysutils
12
MASTER_SITES=	${MASTER_SITE_SOURCEFORGE}
11
MASTER_SITES=	${MASTER_SITE_SOURCEFORGE}
13
MASTER_SITE_SUBDIR=	${PORTNAME}
12
MASTER_SITE_SUBDIR=	${PORTNAME}
(-)distinfo (-3 / +3 lines)
Lines 1-3 Link Here
1
MD5 (smartmontools-5.33.tar.gz) = 53f6861a916169a88a9edb1848e27dd0
1
MD5 (smartmontools-5.36.tar.gz) = 2e424f2d35efa38a29ebca419c1dbe3c
2
SHA256 (smartmontools-5.33.tar.gz) = 2fdde1b4e610cd6e004db8f98ac1100fcbea03b8f11e236de536ce22bc6c620d
2
SHA256 (smartmontools-5.36.tar.gz) = f2032adf22f8d17aad7f3dbed0a9361c25e273d3ca6abb996c84159afd624bf4
3
SIZE (smartmontools-5.33.tar.gz) = 509826
3
SIZE (smartmontools-5.36.tar.gz) = 540786
(-)files/patch-config.h.in (-12 lines)
Lines 1-12 Link Here
1
--- config.h.in.orig	Thu Aug  4 15:16:22 2005
2
+++ config.h.in	Thu Aug  4 15:19:21 2005
3
@@ -66,6 +66,9 @@
4
 /* Define to 1 if you have the <sys/twereg.h> header file. */
5
 #undef HAVE_SYS_TWEREG_H
6
 
7
+/* Define to 1 if you have the <sys/tw_osl_ioctl.h> header file. */
8
+#undef HAVE_SYS_TW_OSL_IOCTL_H
9
+
10
 /* Define to 1 if you have the <sys/types.h> header file. */
11
 #undef HAVE_SYS_TYPES_H
12
 
(-)files/patch-configure.in (-11 lines)
Lines 1-11 Link Here
1
--- configure.in.orig	Thu Aug  4 15:16:15 2005
2
+++ configure.in	Thu Aug  4 15:18:50 2005
3
@@ -56,6 +56,8 @@
4
 dnl Check for FreeBSD twe include files...currently missing on 5.2, but should be there
5
 AC_CHECK_HEADERS([sys/tweio.h])
6
 AC_CHECK_HEADERS([sys/twereg.h])
7
+dnl Check for FreeBSD twa include files...
8
+AC_CHECK_HEADERS([sys/tw_osl_ioctl.h])
9
 
10
 dnl Checks for typedefs, structures, and compiler characteristics.
11
 
(-)files/patch-os_freebsd.c (-641 lines)
Lines 1-641 Link Here
1
--- os_freebsd.c.orig	Sun Oct  9 13:00:56 2005
2
+++ os_freebsd.c	Sun Oct  9 13:00:46 2005
3
@@ -18,6 +18,7 @@
4
 #include <stdio.h>
5
 #include <sys/types.h>
6
 #include <dirent.h>
7
+#include <fcntl.h>
8
 #include <err.h>
9
 #include <camlib.h>
10
 #include <cam/scsi/scsi_message.h>
11
@@ -109,7 +110,11 @@
12
   }
13
 
14
   if (parse_ok == CONTROLLER_ATA) {
15
+#ifdef IOCATAREQUEST
16
+    if ((fdchan->device = open(dev,O_RDONLY))<0) {
17
+#else
18
     if ((fdchan->atacommand = open("/dev/ata",O_RDWR))<0) {
19
+#endif
20
       int myerror = errno;      //preserve across free call
21
       free (fdchan);
22
       errno = myerror;
23
@@ -120,7 +125,26 @@
24
   if (parse_ok == CONTROLLER_3WARE_678K_CHAR) {
25
     char buf[512];
26
     sprintf(buf,"/dev/twe%d",fdchan->device);
27
+#ifdef IOCATAREQUEST
28
+    if ((fdchan->device = open(buf,O_RDWR))<0) {
29
+#else
30
     if ((fdchan->atacommand = open(buf,O_RDWR))<0) {
31
+#endif
32
+      int myerror = errno; // preserver across free call
33
+      free(fdchan);
34
+      errno=myerror;
35
+      return -1;
36
+    }
37
+  }
38
+
39
+  if (parse_ok == CONTROLLER_3WARE_9000_CHAR) {
40
+    char buf[512];
41
+    sprintf(buf,"/dev/twa%d",fdchan->device);
42
+#ifdef IOCATAREQUEST
43
+    if ((fdchan->device = open(buf,O_RDWR))<0) {
44
+#else
45
+    if ((fdchan->atacommand = open(buf,O_RDWR))<0) {
46
+#endif
47
       int myerror = errno; // preserver across free call
48
       free(fdchan);
49
       errno=myerror;
50
@@ -167,8 +191,13 @@
51
     free(fdchan->devname);
52
   
53
   // close device, if open
54
+#ifdef IOCATAREQUEST
55
+  if (fdchan->device)
56
+    failed=close(fdchan->device);
57
+#else
58
   if (fdchan->atacommand)
59
     failed=close(fdchan->atacommand);
60
+#endif
61
 
62
   if (fdchan->scsicontrol)
63
     failed=close(fdchan->scsicontrol);
64
@@ -221,7 +250,7 @@
65
 }
66
 
67
 int ata_command_interface(int fd, smart_command_set command, int select, char *data) {
68
-#ifndef ATAREQUEST
69
+#if !defined(ATAREQUEST) && !defined(IOCATAREQUEST)
70
   // sorry, but without ATAng, we can't do anything here
71
   printwarning(BAD_KERNEL,NULL);
72
   errno = ENOSYS;
73
@@ -229,7 +258,11 @@
74
 #else
75
   struct freebsd_dev_channel* con;
76
   int retval, copydata=0;
77
+#ifdef IOCATAREQUEST
78
+  struct ata_ioc_request request;
79
+#else
80
   struct ata_cmd iocmd;
81
+#endif
82
   unsigned char buff[512];
83
 
84
   // check that "file descriptor" is valid
85
@@ -238,89 +271,97 @@
86
 
87
   bzero(buff,512);
88
 
89
+#ifdef IOCATAREQUEST
90
+  bzero(&request,sizeof(struct ata_ioc_request));
91
+#else
92
   bzero(&iocmd,sizeof(struct ata_cmd));
93
+#endif
94
   bzero(buff,512);
95
+
96
+#ifndef IOCATAREQUEST
97
   iocmd.cmd=ATAREQUEST;
98
   iocmd.channel=con->channel;
99
   iocmd.device=con->device;
100
+#define request iocmd.u.request
101
+#endif
102
 
103
-  iocmd.u.request.u.ata.command=ATA_SMART_CMD;
104
-  iocmd.u.request.timeout=600;
105
+  request.u.ata.command=ATA_SMART_CMD;
106
+  request.timeout=600;
107
   switch (command){
108
   case READ_VALUES:
109
-    iocmd.u.request.u.ata.feature=ATA_SMART_READ_VALUES;
110
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
111
-    iocmd.u.request.flags=ATA_CMD_READ;
112
-    iocmd.u.request.data=buff;
113
-    iocmd.u.request.count=512;
114
+    request.u.ata.feature=ATA_SMART_READ_VALUES;
115
+    request.u.ata.lba=0xc24f<<8;
116
+    request.flags=ATA_CMD_READ;
117
+    request.data=buff;
118
+    request.count=512;
119
     copydata=1;
120
     break;
121
   case READ_THRESHOLDS:
122
-    iocmd.u.request.u.ata.feature=ATA_SMART_READ_THRESHOLDS;
123
-    iocmd.u.request.u.ata.count=1;
124
-    iocmd.u.request.u.ata.lba=1|(0xc24f<<8);
125
-    iocmd.u.request.flags=ATA_CMD_READ;
126
-    iocmd.u.request.data=buff;
127
-    iocmd.u.request.count=512;
128
+    request.u.ata.feature=ATA_SMART_READ_THRESHOLDS;
129
+    request.u.ata.count=1;
130
+    request.u.ata.lba=1|(0xc24f<<8);
131
+    request.flags=ATA_CMD_READ;
132
+    request.data=buff;
133
+    request.count=512;
134
     copydata=1;
135
     break;
136
   case READ_LOG:
137
-    iocmd.u.request.u.ata.feature=ATA_SMART_READ_LOG_SECTOR;
138
-    iocmd.u.request.u.ata.lba=select|(0xc24f<<8);
139
-    iocmd.u.request.u.ata.count=1;
140
-    iocmd.u.request.flags=ATA_CMD_READ;
141
-    iocmd.u.request.data=buff;
142
-    iocmd.u.request.count=512;
143
+    request.u.ata.feature=ATA_SMART_READ_LOG_SECTOR;
144
+    request.u.ata.lba=select|(0xc24f<<8);
145
+    request.u.ata.count=1;
146
+    request.flags=ATA_CMD_READ;
147
+    request.data=buff;
148
+    request.count=512;
149
     copydata=1;
150
     break;
151
   case IDENTIFY:
152
-    iocmd.u.request.u.ata.command=ATA_IDENTIFY_DEVICE;
153
-    iocmd.u.request.flags=ATA_CMD_READ;
154
-    iocmd.u.request.data=buff;
155
-    iocmd.u.request.count=512;
156
+    request.u.ata.command=ATA_IDENTIFY_DEVICE;
157
+    request.flags=ATA_CMD_READ;
158
+    request.data=buff;
159
+    request.count=512;
160
     copydata=1;
161
     break;
162
   case PIDENTIFY:
163
-    iocmd.u.request.u.ata.command=ATA_IDENTIFY_PACKET_DEVICE;
164
-    iocmd.u.request.flags=ATA_CMD_READ;
165
-    iocmd.u.request.data=buff;
166
-    iocmd.u.request.count=512;
167
+    request.u.ata.command=ATA_IDENTIFY_PACKET_DEVICE;
168
+    request.flags=ATA_CMD_READ;
169
+    request.data=buff;
170
+    request.count=512;
171
     copydata=1;
172
     break;
173
   case ENABLE:
174
-    iocmd.u.request.u.ata.feature=ATA_SMART_ENABLE;
175
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
176
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
177
+    request.u.ata.feature=ATA_SMART_ENABLE;
178
+    request.u.ata.lba=0xc24f<<8;
179
+    request.flags=ATA_CMD_CONTROL;
180
     break;
181
   case DISABLE:
182
-    iocmd.u.request.u.ata.feature=ATA_SMART_DISABLE;
183
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
184
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
185
+    request.u.ata.feature=ATA_SMART_DISABLE;
186
+    request.u.ata.lba=0xc24f<<8;
187
+    request.flags=ATA_CMD_CONTROL;
188
     break;
189
   case AUTO_OFFLINE:
190
     // NOTE: According to ATAPI 4 and UP, this command is obsolete
191
-    iocmd.u.request.u.ata.feature=ATA_SMART_AUTO_OFFLINE;
192
-    iocmd.u.request.u.ata.lba=select|(0xc24f<<8);
193
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
194
+    request.u.ata.feature=ATA_SMART_AUTO_OFFLINE;
195
+    request.u.ata.lba=select|(0xc24f<<8);
196
+    request.flags=ATA_CMD_CONTROL;
197
     break;
198
   case AUTOSAVE:
199
-    iocmd.u.request.u.ata.feature=ATA_SMART_AUTOSAVE;
200
-    iocmd.u.request.u.ata.count=0xf1;  // to enable autosave
201
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
202
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
203
+    request.u.ata.feature=ATA_SMART_AUTOSAVE;
204
+    request.u.ata.count=0xf1;  // to enable autosave
205
+    request.u.ata.lba=0xc24f<<8;
206
+    request.flags=ATA_CMD_CONTROL;
207
     break;
208
   case IMMEDIATE_OFFLINE:
209
-    iocmd.u.request.u.ata.feature=ATA_SMART_IMMEDIATE_OFFLINE;
210
-    iocmd.u.request.u.ata.lba = select|(0xc24f<<8); // put test in sector
211
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
212
+    request.u.ata.feature=ATA_SMART_IMMEDIATE_OFFLINE;
213
+    request.u.ata.lba = select|(0xc24f<<8); // put test in sector
214
+    request.flags=ATA_CMD_CONTROL;
215
     break;
216
   case STATUS_CHECK: // same command, no HDIO in FreeBSD
217
   case STATUS:
218
     // this command only says if SMART is working.  It could be
219
     // replaced with STATUS_CHECK below.
220
-    iocmd.u.request.u.ata.feature=ATA_SMART_STATUS;
221
-    iocmd.u.request.u.ata.lba=0xc24f<<8;
222
-    iocmd.u.request.flags=ATA_CMD_CONTROL;
223
+    request.u.ata.feature=ATA_SMART_STATUS;
224
+    request.u.ata.lba=0xc24f<<8;
225
+    request.flags=ATA_CMD_CONTROL;
226
     break;
227
   default:
228
     pout("Unrecognized command %d in ata_command_interface()\n"
229
@@ -334,15 +375,19 @@
230
     unsigned const char failed_lo=0xf4, failed_hi=0x2c;
231
     unsigned char low,high;
232
     
233
-    if ((retval=ioctl(con->atacommand, IOCATA, &iocmd)))
234
+#ifdef IOCATAREQUEST
235
+    if ((retval=ioctl(con->device, IOCATAREQUEST, &request)) || request.error)
236
+#else
237
+    if ((retval=ioctl(con->atacommand, IOCATA, &iocmd)) || request.error)
238
+#endif
239
       return -1;
240
 
241
 #if __FreeBSD_version < 502000
242
     printwarning(NO_RETURN,NULL);
243
 #endif
244
 
245
-    high = (iocmd.u.request.u.ata.lba >> 16) & 0xff;
246
-    low = (iocmd.u.request.u.ata.lba >> 8) & 0xff;
247
+    high = (request.u.ata.lba >> 16) & 0xff;
248
+    low = (request.u.ata.lba >> 8) & 0xff;
249
     
250
     // Cyl low and Cyl high unchanged means "Good SMART status"
251
     if (low==normal_lo && high==normal_hi)
252
@@ -355,21 +400,23 @@
253
     // We haven't gotten output that makes sense; print out some debugging info
254
     char buf[512];
255
     sprintf(buf,"CMD=0x%02x\nFR =0x%02x\nNS =0x%02x\nSC =0x%02x\nCL =0x%02x\nCH =0x%02x\nRETURN =0x%04x\n",
256
-            (int)iocmd.u.request.u.ata.command,
257
-            (int)iocmd.u.request.u.ata.feature,
258
-            (int)iocmd.u.request.u.ata.count,
259
-            (int)((iocmd.u.request.u.ata.lba) & 0xff),
260
-            (int)((iocmd.u.request.u.ata.lba>>8) & 0xff),
261
-            (int)((iocmd.u.request.u.ata.lba>>16) & 0xff),
262
-            (int)iocmd.u.request.error);
263
+            (int)request.u.ata.command,
264
+            (int)request.u.ata.feature,
265
+            (int)request.u.ata.count,
266
+            (int)((request.u.ata.lba) & 0xff),
267
+            (int)((request.u.ata.lba>>8) & 0xff),
268
+            (int)((request.u.ata.lba>>16) & 0xff),
269
+            (int)request.error);
270
     printwarning(BAD_SMART,buf);
271
     return 0;   
272
   }
273
 
274
-  if ((retval=ioctl(con->atacommand, IOCATA, &iocmd))) {
275
-    perror("Failed command: ");
276
+#ifdef IOCATAREQUEST
277
+  if ((retval=ioctl(con->device, IOCATAREQUEST, &request)) || request.error)
278
+#else
279
+  if ((retval=ioctl(con->atacommand, IOCATA, &iocmd)) || request.error)
280
+#endif
281
     return -1;
282
-  }
283
   // 
284
   if (copydata)
285
     memcpy(data, buff, 512);
286
@@ -483,16 +530,22 @@
287
 
288
 // Interface to ATA devices behind 3ware escalade RAID controller cards.  See os_linux.c
289
 
290
+#define BUFFER_LEN_678K_CHAR ( sizeof(struct twe_usercommand) ) // 520
291
+#define BUFFER_LEN_9000_CHAR ( sizeof(TW_OSLI_IOCTL_NO_DATA_BUF) + sizeof(TWE_Command) ) // 2048
292
+#define TW_IOCTL_BUFFER_SIZE ( MAX(BUFFER_LEN_678K_CHAR, BUFFER_LEN_9000_CHAR) )
293
+
294
 int escalade_command_interface(int fd, int disknum, int escalade_type, smart_command_set command, int select, char *data) {
295
   // to hold true file descriptor
296
   struct freebsd_dev_channel* con;
297
 
298
   // return value and buffer for ioctl()
299
   int  ioctlreturn, readdata=0;
300
-  struct twe_usercommand* cmd = NULL;
301
+  struct twe_usercommand* cmd_twe = NULL;
302
+  TW_OSLI_IOCTL_NO_DATA_BUF* cmd_twa = NULL;
303
+  TWE_Command_ATA* ata = NULL;
304
 
305
   // Used by both the SCSI and char interfaces
306
-  char ioctl_buffer[sizeof(struct twe_usercommand)];
307
+  char ioctl_buffer[TW_IOCTL_BUFFER_SIZE];
308
 
309
   if (disknum < 0) {
310
     printwarning(NO_DISK_3WARE,NULL);
311
@@ -503,27 +556,40 @@
312
   if (isnotopen(&fd,&con))
313
       return -1;
314
 
315
-  memset(ioctl_buffer, 0, sizeof(struct twe_usercommand));
316
+  memset(ioctl_buffer, 0, TW_IOCTL_BUFFER_SIZE);
317
 
318
-  cmd = (struct twe_usercommand*)ioctl_buffer;
319
-  cmd->tu_command.ata.opcode = TWE_OP_ATA_PASSTHROUGH;
320
+  if (escalade_type==CONTROLLER_3WARE_9000_CHAR) {
321
+    cmd_twa = (TW_OSLI_IOCTL_NO_DATA_BUF*)ioctl_buffer;
322
+    cmd_twa->pdata = ((TW_OSLI_IOCTL_WITH_PAYLOAD*)cmd_twa)->payload.data_buf;
323
+    cmd_twa->driver_pkt.buffer_length = 512;
324
+    ata = (TWE_Command_ATA*)&cmd_twa->cmd_pkt.command.cmd_pkt_7k;
325
+  } else if (escalade_type==CONTROLLER_3WARE_678K_CHAR) {
326
+    cmd_twe = (struct twe_usercommand*)ioctl_buffer;
327
+    ata = &cmd_twe->tu_command.ata;
328
+  } else {
329
+    pout("Unrecognized escalade_type %d in freebsd_3ware_command_interface(disk %d)\n"
330
+         "Please contact " PACKAGE_BUGREPORT "\n", escalade_type, disknum);
331
+    errno=ENOSYS;
332
+    return -1;
333
+  }
334
 
335
   // Same for (almost) all commands - but some reset below
336
-  cmd->tu_command.ata.request_id    = 0xFF;
337
-  cmd->tu_command.ata.unit   = disknum;
338
-  cmd->tu_command.ata.host_id = 0;
339
-  cmd->tu_command.ata.status        = 0;           
340
-  cmd->tu_command.ata.flags         = 0x1;
341
-  cmd->tu_command.ata.drive_head    = 0x0;
342
-  cmd->tu_command.ata.sector_num    = 0;
343
+  ata->opcode        = TWE_OP_ATA_PASSTHROUGH;
344
+  ata->request_id    = 0xFF;
345
+  ata->unit          = disknum;
346
+  ata->host_id       = 0;
347
+  ata->status        = 0;           
348
+  ata->flags         = 0x1;
349
+  ata->drive_head    = 0x0;
350
+  ata->sector_num    = 0;
351
 
352
   // All SMART commands use this CL/CH signature.  These are magic
353
   // values from the ATA specifications.
354
-  cmd->tu_command.ata.cylinder_lo   = 0x4F;
355
-  cmd->tu_command.ata.cylinder_hi   = 0xC2;
356
+  ata->cylinder_lo   = 0x4F;
357
+  ata->cylinder_hi   = 0xC2;
358
   
359
   // SMART ATA COMMAND REGISTER value
360
-  cmd->tu_command.ata.command       = ATA_SMART_CMD;
361
+  ata->command       = ATA_SMART_CMD;
362
   
363
   // Is this a command that reads or returns 512 bytes?
364
   // passthru->param values are:
365
@@ -538,61 +604,63 @@
366
       command == IDENTIFY        ||
367
       command == WRITE_LOG ) {
368
     readdata=1;
369
-    cmd->tu_size = 512;
370
-    cmd->tu_data = data;
371
-    cmd->tu_command.ata.sgl_offset = 0x5;
372
-    cmd->tu_command.ata.size         = 0x5;
373
-    cmd->tu_command.ata.param        = 0xD;
374
-    cmd->tu_command.ata.sector_count = 0x1;
375
+    if (escalade_type==CONTROLLER_3WARE_678K_CHAR) {
376
+      cmd_twe->tu_data = data;
377
+      cmd_twe->tu_size = 512;
378
+    }
379
+    ata->sgl_offset   = 0x5;
380
+    ata->size         = 0x5;
381
+    ata->param        = 0xD;
382
+    ata->sector_count = 0x1;
383
     // For 64-bit to work correctly, up the size of the command packet
384
     // in dwords by 1 to account for the 64-bit single sgl 'address'
385
     // field. Note that this doesn't agree with the typedefs but it's
386
     // right (agree with kernel driver behavior/typedefs).
387
-    //if (sizeof(long)==8)
388
-    //  cmd->tu_command.ata.size++;
389
+    //if (escalade_type==CONTROLLER_3WARE_9000_CHAR && sizeof(long)==8)
390
+    //  ata->size++;
391
   }
392
   else {
393
     // Non data command -- but doesn't use large sector 
394
     // count register values.  
395
-    cmd->tu_command.ata.sgl_offset = 0x0;
396
-    cmd->tu_command.ata.size         = 0x5;
397
-    cmd->tu_command.ata.param        = 0x8;
398
-    cmd->tu_command.ata.sector_count = 0x0;
399
+    ata->sgl_offset   = 0x0;
400
+    ata->size         = 0x5;
401
+    ata->param        = 0x8;
402
+    ata->sector_count = 0x0;
403
   }
404
   
405
   // Now set ATA registers depending upon command
406
   switch (command){
407
   case CHECK_POWER_MODE:
408
-    cmd->tu_command.ata.command     = ATA_CHECK_POWER_MODE;
409
-    cmd->tu_command.ata.features    = 0;
410
-    cmd->tu_command.ata.cylinder_lo = 0;
411
-    cmd->tu_command.ata.cylinder_hi = 0;
412
+    ata->command     = ATA_CHECK_POWER_MODE;
413
+    ata->features    = 0;
414
+    ata->cylinder_lo = 0;
415
+    ata->cylinder_hi = 0;
416
     break;
417
   case READ_VALUES:
418
-    cmd->tu_command.ata.features = ATA_SMART_READ_VALUES;
419
+    ata->features = ATA_SMART_READ_VALUES;
420
     break;
421
   case READ_THRESHOLDS:
422
-    cmd->tu_command.ata.features = ATA_SMART_READ_THRESHOLDS;
423
+    ata->features = ATA_SMART_READ_THRESHOLDS;
424
     break;
425
   case READ_LOG:
426
-    cmd->tu_command.ata.features = ATA_SMART_READ_LOG_SECTOR;
427
+    ata->features = ATA_SMART_READ_LOG_SECTOR;
428
     // log number to return
429
-    cmd->tu_command.ata.sector_num  = select;
430
+    ata->sector_num  = select;
431
     break;
432
   case WRITE_LOG:
433
-    cmd->tu_data = data;
434
+    if (escalade_type==CONTROLLER_3WARE_9000_CHAR)
435
+      memcpy(cmd_twa->pdata, data, 512);
436
     readdata=0;
437
-    cmd->tu_command.ata.features     = ATA_SMART_WRITE_LOG_SECTOR;
438
-    cmd->tu_command.ata.sector_count = 1;
439
-    cmd->tu_command.ata.sector_num   = select;
440
-    cmd->tu_command.ata.param        = 0xF;  // PIO data write
441
+    ata->features     = ATA_SMART_WRITE_LOG_SECTOR;
442
+    ata->sector_num   = select;
443
+    ata->param        = 0xF;  // PIO data write
444
     break;
445
   case IDENTIFY:
446
     // ATA IDENTIFY DEVICE
447
-    cmd->tu_command.ata.command     = ATA_IDENTIFY_DEVICE;
448
-    cmd->tu_command.ata.features    = 0;
449
-    cmd->tu_command.ata.cylinder_lo = 0;
450
-    cmd->tu_command.ata.cylinder_hi = 0;
451
+    ata->command     = ATA_IDENTIFY_DEVICE;
452
+    ata->features    = 0;
453
+    ata->cylinder_lo = 0;
454
+    ata->cylinder_hi = 0;
455
     break;
456
   case PIDENTIFY:
457
     // 3WARE controller can NOT have packet device internally
458
@@ -600,34 +668,34 @@
459
     errno=ENODEV;
460
     return -1;
461
   case ENABLE:
462
-    cmd->tu_command.ata.features = ATA_SMART_ENABLE;
463
+    ata->features = ATA_SMART_ENABLE;
464
     break;
465
   case DISABLE:
466
-    cmd->tu_command.ata.features = ATA_SMART_DISABLE;
467
+    ata->features = ATA_SMART_DISABLE;
468
     break;
469
   case AUTO_OFFLINE:
470
-    cmd->tu_command.ata.features     = ATA_SMART_AUTO_OFFLINE;
471
+    ata->features     = ATA_SMART_AUTO_OFFLINE;
472
     // Enable or disable?
473
-    cmd->tu_command.ata.sector_count = select;
474
+    ata->sector_count = select;
475
     break;
476
   case AUTOSAVE:
477
-    cmd->tu_command.ata.features     = ATA_SMART_AUTOSAVE;
478
+    ata->features     = ATA_SMART_AUTOSAVE;
479
     // Enable or disable?
480
-    cmd->tu_command.ata.sector_count = select;
481
+    ata->sector_count = select;
482
     break;
483
   case IMMEDIATE_OFFLINE:
484
-    cmd->tu_command.ata.features    = ATA_SMART_IMMEDIATE_OFFLINE;
485
+    ata->features    = ATA_SMART_IMMEDIATE_OFFLINE;
486
     // What test type to run?
487
-    cmd->tu_command.ata.sector_num  = select;
488
+    ata->sector_num  = select;
489
     break;
490
   case STATUS_CHECK:
491
-    cmd->tu_command.ata.features = ATA_SMART_STATUS;
492
+    ata->features = ATA_SMART_STATUS;
493
     break;
494
   case STATUS:
495
     // This is JUST to see if SMART is enabled, by giving SMART status
496
     // command. But it doesn't say if status was good, or failing.
497
     // See below for the difference.
498
-    cmd->tu_command.ata.features = ATA_SMART_STATUS;
499
+    ata->features = ATA_SMART_STATUS;
500
     break;
501
   default:
502
     pout("Unrecognized command %d in freebsd_3ware_command_interface(disk %d)\n"
503
@@ -637,7 +705,19 @@
504
   }
505
 
506
   // Now send the command down through an ioctl()
507
-  ioctlreturn=ioctl(con->atacommand,TWEIO_COMMAND,cmd);
508
+  if (escalade_type==CONTROLLER_3WARE_9000_CHAR) {
509
+#ifdef IOCATAREQUEST
510
+    ioctlreturn=ioctl(con->device,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH,cmd_twa);
511
+#else
512
+    ioctlreturn=ioctl(con->atacommand,TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH,cmd_twa);
513
+#endif
514
+  } else {
515
+#ifdef IOCATAREQUEST
516
+    ioctlreturn=ioctl(con->device,TWEIO_COMMAND,cmd_twe);
517
+#else
518
+    ioctlreturn=ioctl(con->atacommand,TWEIO_COMMAND,cmd_twe);
519
+#endif
520
+  }
521
   
522
   // Deal with the different error cases
523
   if (ioctlreturn) {
524
@@ -648,9 +728,9 @@
525
   
526
   // See if the ATA command failed.  Now that we have returned from
527
   // the ioctl() call, if passthru is valid, then:
528
-  // - cmd->tu_command.ata.status contains the 3ware controller STATUS
529
-  // - cmd->tu_command.ata.command contains the ATA STATUS register
530
-  // - cmd->tu_command.ata.features contains the ATA ERROR register
531
+  // - ata->status contains the 3ware controller STATUS
532
+  // - ata->command contains the ATA STATUS register
533
+  // - ata->features contains the ATA ERROR register
534
   //
535
   // Check bits 0 (error bit) and 5 (device fault) of the ATA STATUS
536
   // If bit 0 (error bit) is set, then ATA ERROR register is valid.
537
@@ -658,21 +738,27 @@
538
   // doesn't make much sense: we don't care in detail why the error
539
   // happened.
540
   
541
-  if (cmd->tu_command.ata.status || (cmd->tu_command.ata.command & 0x21)) {
542
-    pout("Command failed, ata.status=(0x%2.2x), ata.command=(0x%2.2x), ata.flags=(0x%2.2x)\n",cmd->tu_command.ata.status,cmd->tu_command.ata.command,cmd->tu_command.ata.flags);
543
+  if (ata->status || (ata->command & 0x21)) {
544
+    pout("Command failed, ata.status=(0x%2.2x), ata.command=(0x%2.2x), ata.flags=(0x%2.2x)\n",ata->status,ata->command,ata->flags);
545
     errno=EIO;
546
     return -1;
547
   }
548
   
549
+  // If this is a read data command, copy data to output buffer
550
+  if (readdata) {
551
+    if (escalade_type==CONTROLLER_3WARE_9000_CHAR)
552
+      memcpy(data, cmd_twa->pdata, 512);
553
+  }
554
+
555
   // For STATUS_CHECK, we need to check register values
556
   if (command==STATUS_CHECK) {
557
     
558
     // To find out if the SMART RETURN STATUS is good or failing, we
559
     // need to examine the values of the Cylinder Low and Cylinder
560
     // High Registers.
561
-    
562
-    unsigned short cyl_lo=cmd->tu_command.ata.cylinder_lo;
563
-    unsigned short cyl_hi=cmd->tu_command.ata.cylinder_hi;
564
+
565
+    unsigned short cyl_lo=ata->cylinder_lo;
566
+    unsigned short cyl_hi=ata->cylinder_hi;
567
     
568
     // If values in Cyl-LO and Cyl-HI are unchanged, SMART status is good.
569
     if (cyl_lo==0x4F && cyl_hi==0xC2)
570
@@ -688,7 +774,7 @@
571
   
572
   // copy sector count register (one byte!) to return data
573
   if (command==CHECK_POWER_MODE)
574
-    *data=*(char *)&(cmd->tu_command.ata.sector_count);
575
+    *data=*(char *)&(ata->sector_count);
576
   
577
   // look for nonexistent devices/ports
578
   if (command==IDENTIFY && !nonempty((unsigned char *)data, 512)) {
579
@@ -709,6 +795,14 @@
580
   return 0;
581
 }
582
 
583
+static int get_twa_channel_unit (const char* name, int* unit, int* dev) {
584
+  if (sscanf(name, "twa%d", dev) != 1)
585
+    return -1;
586
+  *unit=0; // not really needed for TWA drives, as we handle that seperately
587
+  return 0;
588
+}
589
+
590
+#ifndef IOCATAREQUEST
591
 static int get_ata_channel_unit ( const char* name, int* unit, int* dev) {
592
 #ifndef ATAREQUEST
593
   *dev=0;
594
@@ -756,7 +850,7 @@
595
     return 0;
596
 #endif
597
 }
598
-
599
+#endif
600
 
601
 // Guess device type (ata or scsi) based on device name (FreeBSD
602
 // specific) SCSI device name in FreeBSD can be sd, sr, scd, st, nst,
603
@@ -768,6 +862,7 @@
604
 static const char * fbsd_dev_scsi_tape2 = "nsa";
605
 static const char * fbsd_dev_scsi_tape3 = "esa";
606
 static const char * fbsd_dev_twe_disk = "twed";
607
+static const char * fbsd_dev_twa_disk = "twa";
608
 
609
 static int parse_ata_chan_dev(const char * dev_name, struct freebsd_dev_channel *chan) {
610
   int len;
611
@@ -788,11 +883,13 @@
612
   // form /dev/ad* or ad*
613
   if (!strncmp(fbsd_dev_ata_disk_prefix, dev_name,
614
                strlen(fbsd_dev_ata_disk_prefix))) {
615
+#ifndef IOCATAREQUEST
616
     if (chan != NULL) {
617
       if (get_ata_channel_unit(dev_name,&(chan->channel),&(chan->device))<0) {
618
         return CONTROLLER_UNKNOWN;
619
       }
620
     }
621
+#endif
622
     return CONTROLLER_ATA;
623
   }
624
   
625
@@ -824,6 +921,16 @@
626
       }
627
     }
628
     return CONTROLLER_3WARE_678K_CHAR;
629
+  }
630
+
631
+  if (!strncmp(fbsd_dev_twa_disk,dev_name,
632
+	       strlen(fbsd_dev_twa_disk))) {
633
+    if (chan != NULL) {
634
+      if (get_twa_channel_unit(dev_name,&(chan->channel),&(chan->device))<0) {
635
+	return CONTROLLER_UNKNOWN;
636
+      }
637
+    }
638
+    return CONTROLLER_3WARE_9000_CHAR;
639
   }
640
 
641
   // we failed to recognize any of the forms
(-)files/patch-os_freebsd.h (-265 lines)
Lines 1-265 Link Here
1
--- os_freebsd.h.orig	Sun Sep  5 09:16:07 2004
2
+++ os_freebsd.h	Sat Aug  6 21:08:54 2005
3
@@ -261,6 +261,262 @@
4
 
5
 #endif
6
 
7
+#ifdef  HAVE_SYS_TW_OSL_IOCTL_H
8
+#include <sys/tw_osl_ioctl.h>
9
+#else
10
+/*
11
+ * Following cut out of tw_osl_types.h
12
+ *
13
+ */
14
+
15
+typedef void			TW_VOID;
16
+typedef char			TW_INT8;
17
+typedef unsigned char		TW_UINT8;
18
+typedef short			TW_INT16;
19
+typedef unsigned short		TW_UINT16;
20
+typedef int			TW_INT32;
21
+typedef unsigned int		TW_UINT32;
22
+typedef long long		TW_INT64;
23
+typedef unsigned long long	TW_UINT64;
24
+
25
+/*
26
+ * Following cut out of tw_cl_share.h
27
+ *
28
+ */
29
+
30
+#pragma pack(1)
31
+
32
+struct tw_cl_event_packet {
33
+	TW_UINT32	sequence_id;
34
+	TW_UINT32	time_stamp_sec;
35
+	TW_UINT16	aen_code;
36
+	TW_UINT8	severity;
37
+	TW_UINT8	retrieved;
38
+	TW_UINT8	repeat_count;
39
+	TW_UINT8	parameter_len;
40
+	TW_UINT8	parameter_data[98];
41
+	TW_UINT32	event_src;
42
+	TW_UINT8	severity_str[20];
43
+};
44
+
45
+#pragma pack()
46
+
47
+/*
48
+ * Following cut out of tw_cl_fwif.h
49
+ *
50
+ */
51
+
52
+#define TWA_FW_CMD_ATA_PASSTHROUGH		0x11
53
+
54
+#define TWA_SENSE_DATA_LENGTH		18
55
+
56
+#pragma pack(1)
57
+/* 7000 structures. */
58
+struct tw_cl_command_init_connect {
59
+	TW_UINT8	res1__opcode;	/* 3:5 */
60
+	TW_UINT8	size;
61
+	TW_UINT8	request_id;
62
+	TW_UINT8	res2;
63
+	TW_UINT8	status;
64
+	TW_UINT8	flags;
65
+	TW_UINT16	message_credits;
66
+	TW_UINT32	features;
67
+	TW_UINT16	fw_srl;
68
+	TW_UINT16	fw_arch_id;
69
+	TW_UINT16	fw_branch;
70
+	TW_UINT16	fw_build;
71
+	TW_UINT32	result;
72
+};
73
+
74
+
75
+/* Structure for downloading firmware onto the controller. */
76
+struct tw_cl_command_download_firmware {
77
+	TW_UINT8	sgl_off__opcode;/* 3:5 */
78
+	TW_UINT8	size;
79
+	TW_UINT8	request_id;
80
+	TW_UINT8	unit;
81
+	TW_UINT8	status;
82
+	TW_UINT8	flags;
83
+	TW_UINT16	param;
84
+	TW_UINT8	sgl[1];
85
+};
86
+
87
+
88
+/* Structure for hard resetting the controller. */
89
+struct tw_cl_command_reset_firmware {
90
+	TW_UINT8	res1__opcode;	/* 3:5 */
91
+	TW_UINT8	size;
92
+	TW_UINT8	request_id;
93
+	TW_UINT8	unit;
94
+	TW_UINT8	status;
95
+	TW_UINT8	flags;
96
+	TW_UINT8	res2;
97
+	TW_UINT8	param;
98
+};
99
+
100
+
101
+/* Structure for sending get/set param commands. */
102
+struct tw_cl_command_param {
103
+	TW_UINT8	sgl_off__opcode;/* 3:5 */
104
+	TW_UINT8	size;
105
+	TW_UINT8	request_id;
106
+	TW_UINT8	host_id__unit;	/* 4:4 */
107
+	TW_UINT8	status;
108
+	TW_UINT8	flags;
109
+	TW_UINT16	param_count;
110
+	TW_UINT8	sgl[1];
111
+};
112
+
113
+
114
+/* Generic command packet. */
115
+struct tw_cl_command_generic {
116
+	TW_UINT8	sgl_off__opcode;/* 3:5 */
117
+	TW_UINT8	size;
118
+	TW_UINT8	request_id;
119
+	TW_UINT8	host_id__unit;	/* 4:4 */
120
+	TW_UINT8	status;
121
+	TW_UINT8	flags;
122
+	TW_UINT16	count;	/* block cnt, parameter cnt, message credits */
123
+};
124
+
125
+
126
+/* Command packet header. */
127
+struct tw_cl_command_header {
128
+	TW_UINT8	sense_data[TWA_SENSE_DATA_LENGTH];
129
+	struct {
130
+		TW_INT8		reserved[4];
131
+		TW_UINT16	error;
132
+		TW_UINT8	padding;
133
+		TW_UINT8	res__severity;	/* 5:3 */
134
+	} status_block;
135
+	TW_UINT8	err_specific_desc[98];
136
+	struct {
137
+		TW_UINT8	size_header;
138
+		TW_UINT16	reserved;
139
+		TW_UINT8	size_sense;
140
+	} header_desc;
141
+};
142
+
143
+
144
+/* 7000 Command packet. */
145
+union tw_cl_command_7k {
146
+	struct tw_cl_command_init_connect	init_connect;
147
+	struct tw_cl_command_download_firmware	download_fw;
148
+	struct tw_cl_command_reset_firmware	reset_fw;
149
+	struct tw_cl_command_param		param;
150
+	struct tw_cl_command_generic		generic;
151
+	TW_UINT8	padding[1024 - sizeof(struct tw_cl_command_header)];
152
+};
153
+
154
+
155
+/* 9000 Command Packet. */
156
+struct tw_cl_command_9k {
157
+	TW_UINT8	res__opcode;	/* 3:5 */
158
+	TW_UINT8	unit;
159
+	TW_UINT16	lun_l4__req_id;	/* 4:12 */
160
+	TW_UINT8	status;
161
+	TW_UINT8	sgl_offset; /* offset (in bytes) to sg_list, from the
162
+					end of sgl_entries */
163
+	TW_UINT16	lun_h4__sgl_entries;
164
+	TW_UINT8	cdb[16];
165
+	TW_UINT8	sg_list[872];/* total struct size =
166
+					1024-sizeof(cmd_hdr) */
167
+};
168
+
169
+
170
+/* Full command packet. */
171
+struct tw_cl_command_packet {
172
+	struct tw_cl_command_header	cmd_hdr;
173
+	union {
174
+		union tw_cl_command_7k	cmd_pkt_7k;
175
+		struct tw_cl_command_9k cmd_pkt_9k;
176
+	} command;
177
+};
178
+
179
+#pragma pack()
180
+
181
+/*
182
+ * Following cut out of tw_cl_ioctl.h
183
+ *
184
+ */
185
+
186
+#pragma pack(1)
187
+
188
+/* Structure used to handle GET/RELEASE LOCK ioctls. */
189
+struct tw_cl_lock_packet {
190
+	TW_UINT32	timeout_msec;
191
+	TW_UINT32	time_remaining_msec;
192
+	TW_UINT32	force_flag;
193
+};
194
+
195
+
196
+/* Structure used to handle GET COMPATIBILITY INFO ioctl. */
197
+struct tw_cl_compatibility_packet {
198
+	TW_UINT8	driver_version[32];/* driver version */
199
+	TW_UINT16	working_srl;	/* driver & firmware negotiated srl */
200
+	TW_UINT16	working_branch;	/* branch # of the firmware that the
201
+					driver is compatible with */
202
+	TW_UINT16	working_build;	/* build # of the firmware that the
203
+					driver is compatible with */
204
+};
205
+
206
+
207
+/* Driver understandable part of the ioctl packet built by the API. */
208
+struct tw_cl_driver_packet {
209
+	TW_UINT32	control_code;
210
+	TW_UINT32	status;
211
+	TW_UINT32	unique_id;
212
+	TW_UINT32	sequence_id;
213
+	TW_UINT32	os_status;
214
+	TW_UINT32	buffer_length;
215
+};
216
+
217
+#pragma pack()
218
+
219
+/*
220
+ * Following cut out of tw_osl_ioctl.h
221
+ *
222
+ */
223
+
224
+#pragma pack(1)
225
+/*
226
+ * We need the structure below to ensure that the first byte of
227
+ * data_buf is not overwritten by the kernel, after we return
228
+ * from the ioctl call.  Note that cmd_pkt has been reduced
229
+ * to an array of 1024 bytes even though it's actually 2048 bytes
230
+ * in size.  This is because, we don't expect requests from user
231
+ * land requiring 2048 (273 sg elements) byte cmd pkts.
232
+ */
233
+typedef struct tw_osli_ioctl_no_data_buf {
234
+	struct tw_cl_driver_packet	driver_pkt;
235
+	TW_VOID				*pdata; /* points to data_buf */
236
+	TW_INT8				padding[488 - sizeof(TW_VOID *)];
237
+	struct tw_cl_command_packet	cmd_pkt;
238
+} TW_OSLI_IOCTL_NO_DATA_BUF;
239
+
240
+#pragma pack()
241
+
242
+#define TW_OSL_IOCTL_FIRMWARE_PASS_THROUGH		\
243
+	_IOWR('T', 202, TW_OSLI_IOCTL_NO_DATA_BUF)
244
+
245
+#pragma pack(1)
246
+
247
+typedef struct tw_osli_ioctl_with_payload {
248
+	struct tw_cl_driver_packet	driver_pkt;
249
+	TW_INT8				padding[488];
250
+	struct tw_cl_command_packet	cmd_pkt;
251
+	union {
252
+		struct tw_cl_event_packet		event_pkt;
253
+		struct tw_cl_lock_packet		lock_pkt;
254
+		struct tw_cl_compatibility_packet	compat_pkt;
255
+		TW_INT8					data_buf[1];
256
+	} payload;
257
+} TW_OSLI_IOCTL_WITH_PAYLOAD;
258
+
259
+#pragma pack()
260
+
261
+#endif
262
+
263
 /* 
264
    The following definitions/macros/prototypes are used for three
265
    different interfaces, referred to as "the three cases" below.

Return to bug 96206