linux/drivers/scsi/ses.c
<<
>>
Prefs
   1/*
   2 * SCSI Enclosure Services
   3 *
   4 * Copyright (C) 2008 James Bottomley <James.Bottomley@HansenPartnership.com>
   5 *
   6**-----------------------------------------------------------------------------
   7**
   8**  This program is free software; you can redistribute it and/or
   9**  modify it under the terms of the GNU General Public License
  10**  version 2 as published by the Free Software Foundation.
  11**
  12**  This program is distributed in the hope that it will be useful,
  13**  but WITHOUT ANY WARRANTY; without even the implied warranty of
  14**  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  15**  GNU General Public License for more details.
  16**
  17**  You should have received a copy of the GNU General Public License
  18**  along with this program; if not, write to the Free Software
  19**  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  20**
  21**-----------------------------------------------------------------------------
  22*/
  23
  24#include <linux/slab.h>
  25#include <linux/module.h>
  26#include <linux/kernel.h>
  27#include <linux/enclosure.h>
  28
  29#include <scsi/scsi.h>
  30#include <scsi/scsi_cmnd.h>
  31#include <scsi/scsi_dbg.h>
  32#include <scsi/scsi_device.h>
  33#include <scsi/scsi_driver.h>
  34#include <scsi/scsi_host.h>
  35
  36struct ses_device {
  37        unsigned char *page1;
  38        unsigned char *page1_types;
  39        unsigned char *page2;
  40        unsigned char *page10;
  41        short page1_len;
  42        short page1_num_types;
  43        short page2_len;
  44        short page10_len;
  45};
  46
  47struct ses_component {
  48        u64 addr;
  49        unsigned char *desc;
  50};
  51
  52static int ses_probe(struct device *dev)
  53{
  54        struct scsi_device *sdev = to_scsi_device(dev);
  55        int err = -ENODEV;
  56
  57        if (sdev->type != TYPE_ENCLOSURE)
  58                goto out;
  59
  60        err = 0;
  61        sdev_printk(KERN_NOTICE, sdev, "Attached Enclosure device\n");
  62
  63 out:
  64        return err;
  65}
  66
  67#define SES_TIMEOUT (30 * HZ)
  68#define SES_RETRIES 3
  69
  70static int ses_recv_diag(struct scsi_device *sdev, int page_code,
  71                         void *buf, int bufflen)
  72{
  73        unsigned char cmd[] = {
  74                RECEIVE_DIAGNOSTIC,
  75                1,              /* Set PCV bit */
  76                page_code,
  77                bufflen >> 8,
  78                bufflen & 0xff,
  79                0
  80        };
  81
  82        return scsi_execute_req(sdev, cmd, DMA_FROM_DEVICE, buf, bufflen,
  83                                NULL, SES_TIMEOUT, SES_RETRIES, NULL);
  84}
  85
  86static int ses_send_diag(struct scsi_device *sdev, int page_code,
  87                         void *buf, int bufflen)
  88{
  89        u32 result;
  90
  91        unsigned char cmd[] = {
  92                SEND_DIAGNOSTIC,
  93                0x10,           /* Set PF bit */
  94                0,
  95                bufflen >> 8,
  96                bufflen & 0xff,
  97                0
  98        };
  99
 100        result = scsi_execute_req(sdev, cmd, DMA_TO_DEVICE, buf, bufflen,
 101                                  NULL, SES_TIMEOUT, SES_RETRIES, NULL);
 102        if (result)
 103                sdev_printk(KERN_ERR, sdev, "SEND DIAGNOSTIC result: %8x\n",
 104                            result);
 105        return result;
 106}
 107
 108static int ses_set_page2_descriptor(struct enclosure_device *edev,
 109                                      struct enclosure_component *ecomp,
 110                                      unsigned char *desc)
 111{
 112        int i, j, count = 0, descriptor = ecomp->number;
 113        struct scsi_device *sdev = to_scsi_device(edev->edev.parent);
 114        struct ses_device *ses_dev = edev->scratch;
 115        unsigned char *type_ptr = ses_dev->page1_types;
 116        unsigned char *desc_ptr = ses_dev->page2 + 8;
 117
 118        /* Clear everything */
 119        memset(desc_ptr, 0, ses_dev->page2_len - 8);
 120        for (i = 0; i < ses_dev->page1_num_types; i++, type_ptr += 4) {
 121                for (j = 0; j < type_ptr[1]; j++) {
 122                        desc_ptr += 4;
 123                        if (type_ptr[0] != ENCLOSURE_COMPONENT_DEVICE &&
 124                            type_ptr[0] != ENCLOSURE_COMPONENT_ARRAY_DEVICE)
 125                                continue;
 126                        if (count++ == descriptor) {
 127                                memcpy(desc_ptr, desc, 4);
 128                                /* set select */
 129                                desc_ptr[0] |= 0x80;
 130                                /* clear reserved, just in case */
 131                                desc_ptr[0] &= 0xf0;
 132                        }
 133                }
 134        }
 135
 136        return ses_send_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len);
 137}
 138
 139static unsigned char *ses_get_page2_descriptor(struct enclosure_device *edev,
 140                                      struct enclosure_component *ecomp)
 141{
 142        int i, j, count = 0, descriptor = ecomp->number;
 143        struct scsi_device *sdev = to_scsi_device(edev->edev.parent);
 144        struct ses_device *ses_dev = edev->scratch;
 145        unsigned char *type_ptr = ses_dev->page1_types;
 146        unsigned char *desc_ptr = ses_dev->page2 + 8;
 147
 148        ses_recv_diag(sdev, 2, ses_dev->page2, ses_dev->page2_len);
 149
 150        for (i = 0; i < ses_dev->page1_num_types; i++, type_ptr += 4) {
 151                for (j = 0; j < type_ptr[1]; j++) {
 152                        desc_ptr += 4;
 153                        if (type_ptr[0] != ENCLOSURE_COMPONENT_DEVICE &&
 154                            type_ptr[0] != ENCLOSURE_COMPONENT_ARRAY_DEVICE)
 155                                continue;
 156                        if (count++ == descriptor)
 157                                return desc_ptr;
 158                }
 159        }
 160        return NULL;
 161}
 162
 163static void ses_get_fault(struct enclosure_device *edev,
 164                          struct enclosure_component *ecomp)
 165{
 166        unsigned char *desc;
 167
 168        desc = ses_get_page2_descriptor(edev, ecomp);
 169        if (desc)
 170                ecomp->fault = (desc[3] & 0x60) >> 4;
 171}
 172
 173static int ses_set_fault(struct enclosure_device *edev,
 174                          struct enclosure_component *ecomp,
 175                         enum enclosure_component_setting val)
 176{
 177        unsigned char desc[4] = {0 };
 178
 179        switch (val) {
 180        case ENCLOSURE_SETTING_DISABLED:
 181                /* zero is disabled */
 182                break;
 183        case ENCLOSURE_SETTING_ENABLED:
 184                desc[2] = 0x02;
 185                break;
 186        default:
 187                /* SES doesn't do the SGPIO blink settings */
 188                return -EINVAL;
 189        }
 190
 191        return ses_set_page2_descriptor(edev, ecomp, desc);
 192}
 193
 194static void ses_get_status(struct enclosure_device *edev,
 195                           struct enclosure_component *ecomp)
 196{
 197        unsigned char *desc;
 198
 199        desc = ses_get_page2_descriptor(edev, ecomp);
 200        if (desc)
 201                ecomp->status = (desc[0] & 0x0f);
 202}
 203
 204static void ses_get_locate(struct enclosure_device *edev,
 205                           struct enclosure_component *ecomp)
 206{
 207        unsigned char *desc;
 208
 209        desc = ses_get_page2_descriptor(edev, ecomp);
 210        if (desc)
 211                ecomp->locate = (desc[2] & 0x02) ? 1 : 0;
 212}
 213
 214static int ses_set_locate(struct enclosure_device *edev,
 215                          struct enclosure_component *ecomp,
 216                          enum enclosure_component_setting val)
 217{
 218        unsigned char desc[4] = {0 };
 219
 220        switch (val) {
 221        case ENCLOSURE_SETTING_DISABLED:
 222                /* zero is disabled */
 223                break;
 224        case ENCLOSURE_SETTING_ENABLED:
 225                desc[2] = 0x02;
 226                break;
 227        default:
 228                /* SES doesn't do the SGPIO blink settings */
 229                return -EINVAL;
 230        }
 231        return ses_set_page2_descriptor(edev, ecomp, desc);
 232}
 233
 234static int ses_set_active(struct enclosure_device *edev,
 235                          struct enclosure_component *ecomp,
 236                          enum enclosure_component_setting val)
 237{
 238        unsigned char desc[4] = {0 };
 239
 240        switch (val) {
 241        case ENCLOSURE_SETTING_DISABLED:
 242                /* zero is disabled */
 243                ecomp->active = 0;
 244                break;
 245        case ENCLOSURE_SETTING_ENABLED:
 246                desc[2] = 0x80;
 247                ecomp->active = 1;
 248                break;
 249        default:
 250                /* SES doesn't do the SGPIO blink settings */
 251                return -EINVAL;
 252        }
 253        return ses_set_page2_descriptor(edev, ecomp, desc);
 254}
 255
 256static struct enclosure_component_callbacks ses_enclosure_callbacks = {
 257        .get_fault              = ses_get_fault,
 258        .set_fault              = ses_set_fault,
 259        .get_status             = ses_get_status,
 260        .get_locate             = ses_get_locate,
 261        .set_locate             = ses_set_locate,
 262        .set_active             = ses_set_active,
 263};
 264
 265struct ses_host_edev {
 266        struct Scsi_Host *shost;
 267        struct enclosure_device *edev;
 268};
 269
 270#if 0
 271int ses_match_host(struct enclosure_device *edev, void *data)
 272{
 273        struct ses_host_edev *sed = data;
 274        struct scsi_device *sdev;
 275
 276        if (!scsi_is_sdev_device(edev->edev.parent))
 277                return 0;
 278
 279        sdev = to_scsi_device(edev->edev.parent);
 280
 281        if (sdev->host != sed->shost)
 282                return 0;
 283
 284        sed->edev = edev;
 285        return 1;
 286}
 287#endif  /*  0  */
 288
 289static void ses_process_descriptor(struct enclosure_component *ecomp,
 290                                   unsigned char *desc)
 291{
 292        int eip = desc[0] & 0x10;
 293        int invalid = desc[0] & 0x80;
 294        enum scsi_protocol proto = desc[0] & 0x0f;
 295        u64 addr = 0;
 296        struct ses_component *scomp = ecomp->scratch;
 297        unsigned char *d;
 298
 299        scomp->desc = desc;
 300
 301        if (invalid)
 302                return;
 303
 304        switch (proto) {
 305        case SCSI_PROTOCOL_SAS:
 306                if (eip)
 307                        d = desc + 8;
 308                else
 309                        d = desc + 4;
 310                /* only take the phy0 addr */
 311                addr = (u64)d[12] << 56 |
 312                        (u64)d[13] << 48 |
 313                        (u64)d[14] << 40 |
 314                        (u64)d[15] << 32 |
 315                        (u64)d[16] << 24 |
 316                        (u64)d[17] << 16 |
 317                        (u64)d[18] << 8 |
 318                        (u64)d[19];
 319                break;
 320        default:
 321                /* FIXME: Need to add more protocols than just SAS */
 322                break;
 323        }
 324        scomp->addr = addr;
 325}
 326
 327struct efd {
 328        u64 addr;
 329        struct device *dev;
 330};
 331
 332static int ses_enclosure_find_by_addr(struct enclosure_device *edev,
 333                                      void *data)
 334{
 335        struct efd *efd = data;
 336        int i;
 337        struct ses_component *scomp;
 338
 339        if (!edev->component[0].scratch)
 340                return 0;
 341
 342        for (i = 0; i < edev->components; i++) {
 343                scomp = edev->component[i].scratch;
 344                if (scomp->addr != efd->addr)
 345                        continue;
 346
 347                enclosure_add_device(edev, i, efd->dev);
 348                return 1;
 349        }
 350        return 0;
 351}
 352
 353#define INIT_ALLOC_SIZE 32
 354
 355static void ses_enclosure_data_process(struct enclosure_device *edev,
 356                                       struct scsi_device *sdev,
 357                                       int create)
 358{
 359        u32 result;
 360        unsigned char *buf = NULL, *type_ptr, *desc_ptr, *addl_desc_ptr = NULL;
 361        int i, j, page7_len, len, components;
 362        struct ses_device *ses_dev = edev->scratch;
 363        int types = ses_dev->page1_num_types;
 364        unsigned char *hdr_buf = kzalloc(INIT_ALLOC_SIZE, GFP_KERNEL);
 365
 366        if (!hdr_buf)
 367                goto simple_populate;
 368
 369        /* re-read page 10 */
 370        if (ses_dev->page10)
 371                ses_recv_diag(sdev, 10, ses_dev->page10, ses_dev->page10_len);
 372        /* Page 7 for the descriptors is optional */
 373        result = ses_recv_diag(sdev, 7, hdr_buf, INIT_ALLOC_SIZE);
 374        if (result)
 375                goto simple_populate;
 376
 377        page7_len = len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
 378        /* add 1 for trailing '\0' we'll use */
 379        buf = kzalloc(len + 1, GFP_KERNEL);
 380        if (!buf)
 381                goto simple_populate;
 382        result = ses_recv_diag(sdev, 7, buf, len);
 383        if (result) {
 384 simple_populate:
 385                kfree(buf);
 386                buf = NULL;
 387                desc_ptr = NULL;
 388                len = 0;
 389                page7_len = 0;
 390        } else {
 391                desc_ptr = buf + 8;
 392                len = (desc_ptr[2] << 8) + desc_ptr[3];
 393                /* skip past overall descriptor */
 394                desc_ptr += len + 4;
 395        }
 396        if (ses_dev->page10)
 397                addl_desc_ptr = ses_dev->page10 + 8;
 398        type_ptr = ses_dev->page1_types;
 399        components = 0;
 400        for (i = 0; i < types; i++, type_ptr += 4) {
 401                for (j = 0; j < type_ptr[1]; j++) {
 402                        char *name = NULL;
 403                        struct enclosure_component *ecomp;
 404
 405                        if (desc_ptr) {
 406                                if (desc_ptr >= buf + page7_len) {
 407                                        desc_ptr = NULL;
 408                                } else {
 409                                        len = (desc_ptr[2] << 8) + desc_ptr[3];
 410                                        desc_ptr += 4;
 411                                        /* Add trailing zero - pushes into
 412                                         * reserved space */
 413                                        desc_ptr[len] = '\0';
 414                                        name = desc_ptr;
 415                                }
 416                        }
 417                        if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
 418                            type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE) {
 419
 420                                if (create)
 421                                        ecomp = enclosure_component_register(edev,
 422                                                                             components++,
 423                                                                             type_ptr[0],
 424                                                                             name);
 425                                else
 426                                        ecomp = &edev->component[components++];
 427
 428                                if (!IS_ERR(ecomp) && addl_desc_ptr)
 429                                        ses_process_descriptor(ecomp,
 430                                                               addl_desc_ptr);
 431                        }
 432                        if (desc_ptr)
 433                                desc_ptr += len;
 434
 435                        if (addl_desc_ptr)
 436                                addl_desc_ptr += addl_desc_ptr[1] + 2;
 437
 438                }
 439        }
 440        kfree(buf);
 441        kfree(hdr_buf);
 442}
 443
 444static void ses_match_to_enclosure(struct enclosure_device *edev,
 445                                   struct scsi_device *sdev)
 446{
 447        unsigned char *buf;
 448        unsigned char *desc;
 449        unsigned int vpd_len;
 450        struct efd efd = {
 451                .addr = 0,
 452        };
 453
 454        buf = kmalloc(INIT_ALLOC_SIZE, GFP_KERNEL);
 455        if (!buf || scsi_get_vpd_page(sdev, 0x83, buf, INIT_ALLOC_SIZE))
 456                goto free;
 457
 458        ses_enclosure_data_process(edev, to_scsi_device(edev->edev.parent), 0);
 459
 460        vpd_len = ((buf[2] << 8) | buf[3]) + 4;
 461        kfree(buf);
 462        buf = kmalloc(vpd_len, GFP_KERNEL);
 463        if (!buf ||scsi_get_vpd_page(sdev, 0x83, buf, vpd_len))
 464                goto free;
 465
 466        desc = buf + 4;
 467        while (desc < buf + vpd_len) {
 468                enum scsi_protocol proto = desc[0] >> 4;
 469                u8 code_set = desc[0] & 0x0f;
 470                u8 piv = desc[1] & 0x80;
 471                u8 assoc = (desc[1] & 0x30) >> 4;
 472                u8 type = desc[1] & 0x0f;
 473                u8 len = desc[3];
 474
 475                if (piv && code_set == 1 && assoc == 1
 476                    && proto == SCSI_PROTOCOL_SAS && type == 3 && len == 8)
 477                        efd.addr = (u64)desc[4] << 56 |
 478                                (u64)desc[5] << 48 |
 479                                (u64)desc[6] << 40 |
 480                                (u64)desc[7] << 32 |
 481                                (u64)desc[8] << 24 |
 482                                (u64)desc[9] << 16 |
 483                                (u64)desc[10] << 8 |
 484                                (u64)desc[11];
 485
 486                desc += len + 4;
 487        }
 488        if (!efd.addr)
 489                goto free;
 490
 491        efd.dev = &sdev->sdev_gendev;
 492
 493        enclosure_for_each_device(ses_enclosure_find_by_addr, &efd);
 494 free:
 495        kfree(buf);
 496}
 497
 498static int ses_intf_add(struct device *cdev,
 499                        struct class_interface *intf)
 500{
 501        struct scsi_device *sdev = to_scsi_device(cdev->parent);
 502        struct scsi_device *tmp_sdev;
 503        unsigned char *buf = NULL, *hdr_buf, *type_ptr;
 504        struct ses_device *ses_dev;
 505        u32 result;
 506        int i, types, len, components = 0;
 507        int err = -ENOMEM;
 508        int num_enclosures;
 509        struct enclosure_device *edev;
 510        struct ses_component *scomp = NULL;
 511
 512        if (!scsi_device_enclosure(sdev)) {
 513                /* not an enclosure, but might be in one */
 514                struct enclosure_device *prev = NULL;
 515
 516                while ((edev = enclosure_find(&sdev->host->shost_gendev, prev)) != NULL) {
 517                        ses_match_to_enclosure(edev, sdev);
 518                        prev = edev;
 519                }
 520                return -ENODEV;
 521        }
 522
 523        /* TYPE_ENCLOSURE prints a message in probe */
 524        if (sdev->type != TYPE_ENCLOSURE)
 525                sdev_printk(KERN_NOTICE, sdev, "Embedded Enclosure Device\n");
 526
 527        ses_dev = kzalloc(sizeof(*ses_dev), GFP_KERNEL);
 528        hdr_buf = kzalloc(INIT_ALLOC_SIZE, GFP_KERNEL);
 529        if (!hdr_buf || !ses_dev)
 530                goto err_init_free;
 531
 532        result = ses_recv_diag(sdev, 1, hdr_buf, INIT_ALLOC_SIZE);
 533        if (result)
 534                goto recv_failed;
 535
 536        len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
 537        buf = kzalloc(len, GFP_KERNEL);
 538        if (!buf)
 539                goto err_free;
 540
 541        result = ses_recv_diag(sdev, 1, buf, len);
 542        if (result)
 543                goto recv_failed;
 544
 545        types = 0;
 546
 547        /* we always have one main enclosure and the rest are referred
 548         * to as secondary subenclosures */
 549        num_enclosures = buf[1] + 1;
 550
 551        /* begin at the enclosure descriptor */
 552        type_ptr = buf + 8;
 553        /* skip all the enclosure descriptors */
 554        for (i = 0; i < num_enclosures && type_ptr < buf + len; i++) {
 555                types += type_ptr[2];
 556                type_ptr += type_ptr[3] + 4;
 557        }
 558
 559        ses_dev->page1_types = type_ptr;
 560        ses_dev->page1_num_types = types;
 561
 562        for (i = 0; i < types && type_ptr < buf + len; i++, type_ptr += 4) {
 563                if (type_ptr[0] == ENCLOSURE_COMPONENT_DEVICE ||
 564                    type_ptr[0] == ENCLOSURE_COMPONENT_ARRAY_DEVICE)
 565                        components += type_ptr[1];
 566        }
 567        ses_dev->page1 = buf;
 568        ses_dev->page1_len = len;
 569        buf = NULL;
 570
 571        result = ses_recv_diag(sdev, 2, hdr_buf, INIT_ALLOC_SIZE);
 572        if (result)
 573                goto recv_failed;
 574
 575        len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
 576        buf = kzalloc(len, GFP_KERNEL);
 577        if (!buf)
 578                goto err_free;
 579
 580        /* make sure getting page 2 actually works */
 581        result = ses_recv_diag(sdev, 2, buf, len);
 582        if (result)
 583                goto recv_failed;
 584        ses_dev->page2 = buf;
 585        ses_dev->page2_len = len;
 586        buf = NULL;
 587
 588        /* The additional information page --- allows us
 589         * to match up the devices */
 590        result = ses_recv_diag(sdev, 10, hdr_buf, INIT_ALLOC_SIZE);
 591        if (!result) {
 592
 593                len = (hdr_buf[2] << 8) + hdr_buf[3] + 4;
 594                buf = kzalloc(len, GFP_KERNEL);
 595                if (!buf)
 596                        goto err_free;
 597
 598                result = ses_recv_diag(sdev, 10, buf, len);
 599                if (result)
 600                        goto recv_failed;
 601                ses_dev->page10 = buf;
 602                ses_dev->page10_len = len;
 603                buf = NULL;
 604        }
 605        scomp = kzalloc(sizeof(struct ses_component) * components, GFP_KERNEL);
 606        if (!scomp)
 607                goto err_free;
 608
 609        edev = enclosure_register(cdev->parent, dev_name(&sdev->sdev_gendev),
 610                                  components, &ses_enclosure_callbacks);
 611        if (IS_ERR(edev)) {
 612                err = PTR_ERR(edev);
 613                goto err_free;
 614        }
 615
 616        kfree(hdr_buf);
 617
 618        edev->scratch = ses_dev;
 619        for (i = 0; i < components; i++)
 620                edev->component[i].scratch = scomp + i;
 621
 622        ses_enclosure_data_process(edev, sdev, 1);
 623
 624        /* see if there are any devices matching before
 625         * we found the enclosure */
 626        shost_for_each_device(tmp_sdev, sdev->host) {
 627                if (tmp_sdev->lun != 0 || scsi_device_enclosure(tmp_sdev))
 628                        continue;
 629                ses_match_to_enclosure(edev, tmp_sdev);
 630        }
 631
 632        return 0;
 633
 634 recv_failed:
 635        sdev_printk(KERN_ERR, sdev, "Failed to get diagnostic page 0x%x\n",
 636                    result);
 637        err = -ENODEV;
 638 err_free:
 639        kfree(buf);
 640        kfree(scomp);
 641        kfree(ses_dev->page10);
 642        kfree(ses_dev->page2);
 643        kfree(ses_dev->page1);
 644 err_init_free:
 645        kfree(ses_dev);
 646        kfree(hdr_buf);
 647        sdev_printk(KERN_ERR, sdev, "Failed to bind enclosure %d\n", err);
 648        return err;
 649}
 650
 651static int ses_remove(struct device *dev)
 652{
 653        return 0;
 654}
 655
 656static void ses_intf_remove_component(struct scsi_device *sdev)
 657{
 658        struct enclosure_device *edev, *prev = NULL;
 659
 660        while ((edev = enclosure_find(&sdev->host->shost_gendev, prev)) != NULL) {
 661                prev = edev;
 662                if (!enclosure_remove_device(edev, &sdev->sdev_gendev))
 663                        break;
 664        }
 665        if (edev)
 666                put_device(&edev->edev);
 667}
 668
 669static void ses_intf_remove_enclosure(struct scsi_device *sdev)
 670{
 671        struct enclosure_device *edev;
 672        struct ses_device *ses_dev;
 673
 674        /*  exact match to this enclosure */
 675        edev = enclosure_find(&sdev->sdev_gendev, NULL);
 676        if (!edev)
 677                return;
 678
 679        ses_dev = edev->scratch;
 680        edev->scratch = NULL;
 681
 682        kfree(ses_dev->page10);
 683        kfree(ses_dev->page1);
 684        kfree(ses_dev->page2);
 685        kfree(ses_dev);
 686
 687        kfree(edev->component[0].scratch);
 688
 689        put_device(&edev->edev);
 690        enclosure_unregister(edev);
 691}
 692
 693static void ses_intf_remove(struct device *cdev,
 694                            struct class_interface *intf)
 695{
 696        struct scsi_device *sdev = to_scsi_device(cdev->parent);
 697
 698        if (!scsi_device_enclosure(sdev))
 699                ses_intf_remove_component(sdev);
 700        else
 701                ses_intf_remove_enclosure(sdev);
 702}
 703
 704static struct class_interface ses_interface = {
 705        .add_dev        = ses_intf_add,
 706        .remove_dev     = ses_intf_remove,
 707};
 708
 709static struct scsi_driver ses_template = {
 710        .owner                  = THIS_MODULE,
 711        .gendrv = {
 712                .name           = "ses",
 713                .probe          = ses_probe,
 714                .remove         = ses_remove,
 715        },
 716};
 717
 718static int __init ses_init(void)
 719{
 720        int err;
 721
 722        err = scsi_register_interface(&ses_interface);
 723        if (err)
 724                return err;
 725
 726        err = scsi_register_driver(&ses_template.gendrv);
 727        if (err)
 728                goto out_unreg;
 729
 730        return 0;
 731
 732 out_unreg:
 733        scsi_unregister_interface(&ses_interface);
 734        return err;
 735}
 736
 737static void __exit ses_exit(void)
 738{
 739        scsi_unregister_driver(&ses_template.gendrv);
 740        scsi_unregister_interface(&ses_interface);
 741}
 742
 743module_init(ses_init);
 744module_exit(ses_exit);
 745
 746MODULE_ALIAS_SCSI_DEVICE(TYPE_ENCLOSURE);
 747
 748MODULE_AUTHOR("James Bottomley");
 749MODULE_DESCRIPTION("SCSI Enclosure Services (ses) driver");
 750MODULE_LICENSE("GPL v2");
 751